Compare commits

...

3 Commits

Author SHA1 Message Date
hym b4c8296d75 Merge branch 'master' of http://124.222.8.13:3000/revisit/DSDSWeb 2026-06-25 21:35:08 +08:00
hym d4fd572394 更新地图初始化逻辑 2026-06-25 21:35:04 +08:00
hym f7c3baa76f 更新图层操作逻辑 2026-06-25 21:33:25 +08:00
9 changed files with 124 additions and 40 deletions

View File

@ -16,6 +16,7 @@ import qs from 'qs'
import store from './store/index'
import { extractWMTSBoundsInfo } from '@/utils/mapbox-utils'
import { getGeoserverCapabilities } from '@/utils/vector-layer-utils'
window.sessionStorage.setItem('webInfo', 'ASOS')
Vue.use(ElementUI, { locale: Zhlocale })
@ -35,6 +36,9 @@ new Vue({
// 定义部分全局变量
Vue.config.maps = {};
Vue.config.layers = {};
Vue.config.username = "***";
Vue.config.password = "***";
Vue.config.firstRender = true;
Vue.config.boundsInfoList = [];
Vue.config.baseUrl = process.env.NODE_ENV === 'development' ? 'http://124.222.8.13:9801' : `${window.location.protocol}//${window.location.hostname}:${window.location.port}`
@ -43,7 +47,14 @@ Vue.config.sprites = ["go.png", "ship.png", "ship1.png", "ship2.png", "ship3.png
if (Vue.config.firstRender) {
Vue.config.firstRender = !Vue.config.firstRender;
fetch(`${Vue.config.baseUrl}/geoserver/gwc/service/wmts?service=WMTS&acceptVersions=1.0.0&request=GetCapabilities`)
// fetch(`${Vue.config.baseUrl}/geoserver/gwc/service/wmts?service=WMTS&acceptVersions=1.0.0&request=GetCapabilities`)
// fetch(`http://10.1.51.150:8080/geoserver/gwc/service/wmts?service=WMTS&acceptVersions=1.0.0&request=GetCapabilities`, {
fetch(`${Vue.config.baseUrl}/geoserver/gwc/service/wmts?service=WMTS&acceptVersions=1.0.0&request=GetCapabilities`, {
headers: {
// 'Authorization': `Basic ${btoa(`${Vue.config.username}:${Vue.config.password}`)}`,
'Accept': 'application/vnd.ogc.sld+xml'
}
})
.then(response => response.text())
.then(async (xmlContent) => {
Vue.config.boundsInfoList = await extractWMTSBoundsInfo(xmlContent);
@ -53,8 +64,9 @@ if (Vue.config.firstRender) {
window.mapboxgl.accessToken = 'pk.eyJ1IjoicWRod2kiLCJhIjoiY2xiaXppcjEyMGNhMjNwbzVrcHl4d20zOSJ9.0ETMJM3-zllFh2GRrRVUZg'
Vue.config.tiles = {
// "world_horizon_1": `${Vue.config.baseUrl}/geoserver/gwc/service/wmts/rest/ougp:world_horizon_1/EPSG:900913/EPSG:900913:{z}/{y}/{x}?format=image/jpeg`,
"world_horizon_1": `${Vue.config.baseUrl}/geoserver/gwc/service/wmts/rest/ougp:world_horizon_1/EPSG:900913/EPSG:900913:{z}/{y}/{x}?format=image/jpeg`,
"World_Imagery": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
"GEBCO_basemap_NCEI": "https://tiles.arcgis.com/tiles/C8EMgrsFcRFL6LrL/arcgis/rest/services/GEBCO_basemap_NCEI/MapServer/tile/{z}/{y}/{x}",
"gaode":"https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&scl=2&style=8&x={x}&y={y}&z={z}"
"gaode": "https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&scl=2&style=8&x={x}&y={y}&z={z}"
};

View File

@ -62,6 +62,23 @@ export function initMapbox(mapId, options = {}) {
boxZoom: true,//如果为true则启用了“缩放框”交互按住shift并在地图上拖框放大
preserveDrawingBuffer: false,//如果为true地图的canvas可以使用导出到png通过map.getCanvas().toDataURL()。默认为false会提高地图性能。
// projection: 'equirectangular', // 设置投影方式经纬度直投解决缩放级别大于26时瓦片消失的问题
transformRequest(url, resourceType) {
// 注释掉以免缩放级别大于12时出现空白底图
// if (url.includes("ougp:world"))
// return filterRequest(url, resourceType, 12);
// 判断请求是否来自你的 GeoServer
if (url.includes(`${Vue.config.baseUrl}/geoserver`)) {
return {
url: url,
// headers: { 'Authorization': `Basic ${btoa(`${Vue.config.username}:${Vue.config.password}`)}` },
credentials: 'same-origin' // 用于控制Cookie发送
};
}
// 对其他请求不做修改
return { url: url };
}
});
Vue.config.maps[mapId] = map;
@ -89,8 +106,8 @@ export function initMapbox(mapId, options = {}) {
loadVectorLayer({ layerId: "GSHHS_f_L1", features: ["line"], colors: ["#5c71c3"], visibility: "visible", mapId, workspace: 'ougp' });
// 加载等深线
if (options.contourOn || false) {
loadVectorLayer({ layerId: "contour-4500m", features: ["line"], colors: ["#FEFEFE"], visibility: "visible", mapId, workspace: 'ougp' });
loadVectorLayer({ layerId: "contour-6000m", features: ["line"], colors: ["#FEFEFE"], visibility: "visible", mapId, workspace: 'ougp' });
loadVectorLayer({ layerId: (Vue.config.layers["4500米等深线"] || Vue.config.layers["contour-4500m"]), features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId, workspace: 'ougp' });
loadVectorLayer({ layerId: (Vue.config.layers["6000米等深线"] || Vue.config.layers["contour-6000m"]), features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId, workspace: 'ougp' });
}
});
}

View File

@ -48,6 +48,7 @@ export function loadVectorLayer({ layerId, features = ["line", "symbol"], colors
if (!source) {
// request vector tiles with extra buffer to avoid geometry clipping at tile edges
const tilesUrl = `${Vue.config.baseUrl}/geoserver/gwc/service/tms/1.0.0/${workspace}:${layerId}@EPSG:900913@pbf/{z}/{x}/{y}.pbf?buffer=64`;
// const tilesUrl = `http://10.1.51.150:8080/geoserver/gwc/service/tms/1.0.0/${workspace}:${layerId}@EPSG:900913@pbf/{z}/{x}/{y}.pbf?buffer=64`;
let bb = Vue.config.boundsInfoList.find(x => x.layerName.toLowerCase() == `${workspace}:${layerId}`.toLocaleLowerCase());
let bounds = bb ? bb.bounds : null;
if (bounds) {
@ -420,9 +421,20 @@ export function showSampleStationInfo(layerId, mapId = "homeMap", callbackOnClic
});
}
/**
* 显示高亮样品信息弹窗
* @param {Object} params - 参数对象
* @param {string} params.mapId - 地图实例ID
* @param {string} params.job_type - 作业类型"测线作业""站位作业"
* @param {Object} params.sample - 样品数据对象
* @param {string} params.layerId - 图层ID
* @param {string} params.sourceLayerId - 源图层ID
* @param {Function} params.callbackOnClick - 关闭弹窗时的回调函数
*/
export function showHighlightSampleInfo({ mapId, job_type, sample, layerId, sourceLayerId, callbackOnClick }) {
let description = "";
let coordinate;
// 根据作业类型生成对应的信息弹窗内容
if (job_type == "测线作业") {
// // 恢复其它测线的线宽
// // setMapPaintProperty({ mapId, property: "line-width", value: lineWidthExpression });
@ -441,11 +453,7 @@ export function showHighlightSampleInfo({ mapId, job_type, sample, layerId, sour
// { hover: true }
// );
// if (lastLineId)
// Vue.config.maps[mapId].setPaintProperty(lastLineId, 'line-color', '#FFFFFF')
// Vue.config.maps[mapId].setPaintProperty(layerId, 'line-color', '#FFFF00')
// lastLineId = layerId;
// 测线坐标取起止点中点
coordinate = [(Number(sample.start_lon) + Number(sample.end_lon)) / 2, (Number(sample.start_lat) + Number(sample.end_lat)) / 2];
description = `
<table class="popup-table" style="min-width:380px;">
@ -483,6 +491,7 @@ export function showHighlightSampleInfo({ mapId, job_type, sample, layerId, sour
</tr>
</table>`;
}
// 站位作业:使用采样点坐标,生成站位信息表格
else if (job_type == "站位作业") {
coordinate = [sample.sampling_lon, sample.sampling_lat];
description = `
@ -510,9 +519,10 @@ export function showHighlightSampleInfo({ mapId, job_type, sample, layerId, sour
</tr>
<tr>
<td colspan="2">备注信息: <b>${sample.sample_remark}</b></td>
</tr>
</tr>
</table>`;
}
// 调用弹窗工具显示详情
showPopupDetails({ mapId, coordinate, description, maxWidth: "450px", callbackOnClose: callbackOnClick });
}
@ -529,7 +539,7 @@ export function showTrackInfo(layerId, mapId = "homeMap") {
let match = layerId.match(/vector-(.*)-[(symbol)|(line)]/);
if (!match)
return;
const voyageId = match[1];
const voyageId = getKeyByValue(Vue.config.layers,match[1]);
regInfo({ voyage_name: voyageId }).then(res => {
const info = res.map.voyage;
const description = `
@ -751,4 +761,45 @@ export async function highlightFeaturesByProperty(mapId, sourceId, layerId, prop
'#FFFFFF', // 高亮颜色
"#FF0000"// 默认颜色
]);
}
export async function getGeoserverCapabilities() {
const url = `${Vue.config.baseUrl}/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities`;
// const url = `http://10.1.51.150:8080/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities`;
const xmlContent = await fetch(url
, {
headers: {
// 'Authorization': `Basic ${btoa(`${Vue.config.username}:${Vue.config.password}`)}`,
'Accept': 'application/vnd.ogc.sld+xml'
}
})
.then(response => response.text())
.then(xml => xml);
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlContent, "text/xml");
const layerInfoList = [];
const layers = xmlDoc.getElementsByTagName("Layer");
// 遍历所有 Layer 元素,提取图层信息
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
// 提取 Name
const nameElement = layer.getElementsByTagName("Name")[0];
const name = nameElement ? nameElement.textContent || "" : "";
if (!name) continue;
// 提取 Title
const titleElement = layer.getElementsByTagName("Title")[0];
const title = titleElement ? titleElement.textContent || "" : "";
if (!title || title === "sea_ice" || title === "north magnetic pole") continue;
Vue.config.layers[title] = name.split(':')[1];
}
console.log(Vue.config.layers);
}
function getKeyByValue(obj, value) {
return Object.keys(obj).find(key => obj[key] === value);
}

View File

@ -456,7 +456,7 @@ export default {
item.highlight = false
item.show = true
//
loadVectorLayer({ layerId: item.voyage_name, features: ["line", "symbol"], colors: [colors[i], colors[i]], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds" });
loadVectorLayer({ layerId: Vue.config.layers[item.voyage_name], features: ["line", "symbol"], colors: [colors[i], colors[i]], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds" });
i++;
})
}
@ -486,12 +486,12 @@ export default {
},
//
addHighlightLayer(voyageName, i) {
Vue.config.maps["dataSearchMap"].setPaintProperty(`vector-${voyageName}-line`, "line-width", 4);
Vue.config.maps["dataSearchMap"].setPaintProperty(`vector-${Vue.config.layers[voyageName]}-line`, "line-width", 4);
this.dataList[i].highlight = true;
},
//
clearHighlight(voyageName, i) {
Vue.config.maps["dataSearchMap"].setPaintProperty(`vector-${voyageName}-line`, "line-width", lineWidthExpression);
Vue.config.maps["dataSearchMap"].setPaintProperty(`vector-${Vue.config.layers[voyageName]}-line`, "line-width", lineWidthExpression);
this.dataList[i].highlight = false;
},
//
@ -500,8 +500,8 @@ export default {
this.dataList[i].show = true;
}
//
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${voyageName}-symbol`, "visibility", "visible");
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${voyageName}-line`, "visibility", "visible");
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${Vue.config.layers[voyageName]}-symbol`, "visibility", "visible");
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${Vue.config.layers[voyageName]}-line`, "visibility", "visible");
},
//
@ -512,8 +512,8 @@ export default {
//
// let visibility = Vue.config.maps["dataSearchMap"].getLayoutProperty(`vector-${voyageName}-symbol`, "visibility");
// visibility = visibility == "visible" ? "none" : "visible";
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${voyageName}-symbol`, "visibility", "none");
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${voyageName}-line`, "visibility", "none");
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${Vue.config.layers[voyageName]}-symbol`, "visibility", "none");
Vue.config.maps["dataSearchMap"].setLayoutProperty(`vector-${Vue.config.layers[voyageName]}-line`, "visibility", "none");
},
//
clearAll() {
@ -544,9 +544,9 @@ export default {
// loadVectorLayer({layerId:item.voyage_name, features:["line", "symbol"], colors:[colors[i], colors[i]], visibility:"visible", mapId:"dataSearchMap", workspace:"dsds"});
// 线/
if (item.job_type == "测线作业") {
loadVectorLayer({ layerId: `sample_line_${item.dataset_name}`, features: ["line"], colors: ["#FFFFFF", "#FFFFFF"], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds", textField: "sample_name", callbackOnClick: this.setHightItem });
loadVectorLayer({ layerId: `${Vue.config.layers["sample_line_" + item.dataset_name]}`, features: ["line"], colors: ["#FFFFFF", "#FFFFFF"], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds", textField: "sample_name", callbackOnClick: this.setHightItem });
} else {
loadVectorLayer({ layerId: `sample_station_${item.dataset_name}`, features: ["symbol"], colors: ["#FFFFFF", "#FFFFFF"], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds", textField: "sample_name", callbackOnClick: this.setHightItem });
loadVectorLayer({ layerId: `${Vue.config.layers["sample_station_" + item.dataset_name]}`, features: ["symbol"], colors: ["#FFFFFF", "#FFFFFF"], visibility: "visible", mapId: "dataSearchMap", workspace: "dsds", textField: "sample_name", callbackOnClick: this.setHightItem });
}
i++;
})

View File

@ -234,7 +234,7 @@ import { getVoyage, statisticsNums } from '../api/home'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/swiper-bundle.css'
import { sampleDatasetList, voyageRegList } from '@/api/dataTransfer'
import { loadVectorLayer } from '@/utils/vector-layer-utils'
import { loadVectorLayer, getGeoserverCapabilities } from '@/utils/vector-layer-utils'
import { ColorGenerator } from '@/utils/color-generator';
import { initMapbox, handleWheel, initSprites, triggerLayerClick } from "@/utils/mapbox-utils";
@ -310,10 +310,10 @@ export default {
this.dataUpdate()
this.sampleDataUpdate()
},
mounted() {
async mounted() {
initMapbox("homeMap", {
tileKey: "World_Imagery",
zoom: 1.5,
zoom: 3,
center: [122, 15],
minZoom: 1,
maxZoom: 29,
@ -328,13 +328,16 @@ export default {
// 线
// loadVectorLayer("GSHHS_f_L1", ["line"], ["#FEFEFE"], "homeMap", 'ougp');
// 线
loadVectorLayer({ layerId: "contour-4500m", features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId: "homeMap", workspace: 'ougp' });
loadVectorLayer({ layerId: "contour-6000m", features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId: "homeMap", workspace: 'ougp' });
loadVectorLayer({ layerId: (Vue.config.layers["4500米等深线"] || Vue.config.layers["contour-4500m"]), features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId: "homeMap", workspace: 'ougp' });
loadVectorLayer({ layerId: (Vue.config.layers["6000米等深线"] || Vue.config.layers["contour-6000m"]), features: ["line"], colors: ["#FEFEFE"], visibility: "none", mapId: "homeMap", workspace: 'ougp' });
});
},
methods: {
//
getVoyageList() {
async getVoyageList() {
// await getGeoserverCapabilities getVoyage
await getGeoserverCapabilities();
getVoyage({
start: 0,
limit: 10
@ -345,7 +348,7 @@ export default {
const colors = ColorGenerator.generateDivergingColors(this.voyageList.length);
this.voyageList.forEach(element => {
//
loadVectorLayer({ layerId: element.voyage_name, features: ["line", "symbol"], colors: [colors[i], colors[i]], visibility: "visible", mapId: "homeMap", workspace: "dsds" });
loadVectorLayer({ layerId: Vue.config.layers[element.voyage_name], features: ["line", "symbol"], colors: [colors[i], colors[i]], visibility: "visible", mapId: "homeMap", workspace: "dsds", textField: "name" });
i++;
});
@ -359,10 +362,10 @@ export default {
//
handleRowClick(row, column, event) {
// /
let visibility = Vue.config.maps["homeMap"].getLayoutProperty(`vector-${row.voyage_name}-symbol`, "visibility");
let visibility = Vue.config.maps["homeMap"].getLayoutProperty(`vector-${Vue.config.layers[row.voyage_name]}-symbol`, "visibility");
visibility = visibility == "visible" ? "none" : "visible";
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${row.voyage_name}-symbol`, "visibility", visibility);
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${row.voyage_name}-line`, "visibility", visibility);
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${Vue.config.layers[row.voyage_name]}-symbol`, "visibility", visibility);
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${Vue.config.layers[row.voyage_name]}-line`, "visibility", visibility);
this.$refs.multipleTable.toggleRowSelection(row);
},
@ -379,8 +382,8 @@ export default {
//
voyagesToRemove.forEach(voyage => {
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${voyage}-symbol`, "visibility", "none");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${voyage}-line`, "visibility", "none");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${Vue.config.layers[voyage]}-symbol`, "visibility", "none");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${Vue.config.layers[voyage]}-line`, "visibility", "none");
});
//
@ -388,8 +391,8 @@ export default {
// val
const correspondingItem = val.find(item => item.voyage_name === voyage);
if (correspondingItem) {
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${voyage}-symbol`, "visibility", "visible");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${voyage}-line`, "visibility", "visible");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${Vue.config.layers[voyage]}-symbol`, "visibility", "visible");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${Vue.config.layers[voyage]}-line`, "visibility", "visible");
}
});
@ -403,12 +406,13 @@ export default {
// **2: **
const index = this.selectedDepths.indexOf(depth);
console.log("depth>>>",depth);
if (index > -1) {
this.selectedDepths.splice(index, 1); //
Vue.config.maps["homeMap"].setLayoutProperty(`vector-contour-${depth}m-line`, "visibility", "none");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${(Vue.config.layers[depth + "米等深线"] || Vue.config.layers["contour-" + depth + "m"])}-line`, "visibility", "none");
} else {
this.selectedDepths.push(depth); //
Vue.config.maps["homeMap"].setLayoutProperty(`vector-contour-${depth}m-line`, "visibility", "visible");
Vue.config.maps["homeMap"].setLayoutProperty(`vector-${(Vue.config.layers[depth + "米等深线"] || Vue.config.layers["contour-" + depth + "m"])}-line`, "visibility", "visible");
}
},

View File

@ -249,7 +249,7 @@ export default {
//
res.array.forEach(item => {
//
loadVectorLayer({ layerId: item.diving_sn, features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_auv", worksapce: "dsds" });
loadVectorLayer({ layerId: Vue.config.layers[item.diving_sn], features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_auv", worksapce: "dsds" });
i++;
})
})

View File

@ -234,7 +234,7 @@ export default {
const colors = ColorGenerator.generateDivergingColors(res.array.length);
res.array.forEach(item => {
//
loadVectorLayer({ layerId: item.diving_sn, features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_hov", workspace: "dsds" });
loadVectorLayer({ layerId: Vue.config.layers[item.diving_sn], features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_hov", workspace: "dsds" });
i++;
})
})

View File

@ -234,7 +234,7 @@ export default {
//
res.array.forEach(item => {
//
loadVectorLayer({ layerId: item.diving_sn, features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_rov", workspace: "dsds" });
loadVectorLayer({ layerId: Vue.config.layers[item.diving_sn], features: ["line", "symbol"], colors: [colors[i], "#FFFFFF"], visibility: "visible", mapId: "voyageMap_rov", workspace: "dsds" });
i++;
})
})

View File

@ -249,7 +249,7 @@ export default {
//
res.array.forEach(item => {
//
loadVectorLayer({ layerId: item.voyage_name, features: ['line', 'symbol'], colors: [colors[i], '#FFFFFF'], visibility: 'visible', mapId: 'voyageMap_ship', workspace: 'dsds' })
loadVectorLayer({ layerId: Vue.config.layers[item.voyage_name], features: ['line', 'symbol'], colors: [colors[i], '#FFFFFF'], visibility: 'visible', mapId: 'voyageMap_ship', workspace: 'dsds' })
i++
})
})