diff --git a/src/main.js b/src/main.js index 02bc37d..c24e40d 100644 --- a/src/main.js +++ b/src/main.js @@ -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}" }; \ No newline at end of file diff --git a/src/utils/mapbox-utils.js b/src/utils/mapbox-utils.js index 8e2a987..b0a3713 100644 --- a/src/utils/mapbox-utils.js +++ b/src/utils/mapbox-utils.js @@ -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' }); } }); } diff --git a/src/utils/vector-layer-utils.js b/src/utils/vector-layer-utils.js index 03c4fb3..30bd69e 100644 --- a/src/utils/vector-layer-utils.js +++ b/src/utils/vector-layer-utils.js @@ -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 = ` @@ -483,6 +491,7 @@ export function showHighlightSampleInfo({ mapId, job_type, sample, layerId, sour `; } + // 站位作业:使用采样点坐标,生成站位信息表格 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 备注信息: ${sample.sample_remark} - + `; } + // 调用弹窗工具显示详情 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); } \ No newline at end of file