diff --git a/src/utils/vector-layer-utils.js b/src/utils/vector-layer-utils.js index c4f97de..65efad8 100644 --- a/src/utils/vector-layer-utils.js +++ b/src/utils/vector-layer-utils.js @@ -146,15 +146,11 @@ export function setHighlight(layerId, sourceId, mapId = "homeMap") { let hoveredLineId = null; let clickedLineId = null; Vue.config.maps[mapId].on('click', layerId, async (e) => { - if (!e.features || e.features.length <= 0) + sourceLayer = e.features[0].sourceLayer; + // 排除没有 sourceLayer 的情况(如点击事件中 features 可能来自多个图层,某些图层缺乏 sourceLayer 属性会导致后续 setFeatureState 报错) + if (!sourceLayer) return; - if (mapId == "workUnitMap_uuv") { - // 相关逻辑位于单位统计页面 - // showUnitReport(mapId, e.features[0].properties.unit_name, e.features[0].geometry.coordinates); - return; - } - // // 查询点击点周围的所有要素(使用边界框) // const bbox = [ // [e.point.x - 10, e.point.y - 10], // 左上 @@ -194,21 +190,18 @@ export function setHighlight(layerId, sourceId, mapId = "homeMap") { // 单击时加入选择列表(用于单击 ESC 键时取消选择状态) clickedLineIds.push(clickedLineId); // document.removeEventListener("keydown", removeHighlight, true); - document.addEventListener("keydown", (e) => { - removeHighlight(e, sourceId); - }, { once: true }); // once:一个布尔值,表示 listener 在添加之后最多只调用一次。如果为 true,listener 会在其被调用之后自动移除。 - // }, true); + // document.addEventListener("keydown", (e) => { + // removeHighlight(e, sourceId); + // }, { once: true }); // once:一个布尔值,表示 listener 在添加之后最多只调用一次。如果为 true,listener 会在其被调用之后自动移除。 } }); // When the user moves their mouse over the state-fill layer, we'll update the feature state for the feature under the mouse. Vue.config.maps[mapId].on('mousemove', layerId, (e) => { - if (mapId == "workUnitMap_uuv") - return; - - if (e.features.length <= 0) - return; sourceLayer = e.features[0].sourceLayer; + // 排除没有 sourceLayer 的情况(如点击事件中 features 可能来自多个图层,某些图层缺乏 sourceLayer 属性会导致后续 setFeatureState 报错) + if (!sourceLayer) + return; if (hoveredLineId) { Vue.config.maps[mapId].setFeatureState( { source: sourceId, sourceLayer: sourceLayer, id: hoveredLineId }, @@ -234,7 +227,7 @@ export function setHighlight(layerId, sourceId, mapId = "homeMap") { }); } -export async function showUnitReport(mapId, unit, coordinates) { +export async function showUnitReport(mapId, unit, coordinate, callbackOnClose = null) { const result = await (await fetch(`${Vue.config.baseUrl}/ds/report/unit/total.htm?unit=${unit}`)).json(); const unitReports = result.array || []; if (!unitReports.length) { @@ -266,7 +259,7 @@ export async function showUnitReport(mapId, unit, coordinates) { `; - showPopupDetails(mapId, coordinates, description, "350px"); + showPopupDetails({ mapId, coordinate, description, maxWidth: "350px", callbackOnClose: callbackOnClose }); } export function changeCursor(layerId, mapId = "homeMap", cursor = "pointer") { @@ -324,7 +317,7 @@ export function showSampleLineInfo(layerId, mapId = "homeMap") { `; - showPopupDetails(mapId, e.lngLat, description, "450px"); + showPopupDetails({ mapId, coordinate: e.lngLat, description, maxWidth: "450px" }); }); } @@ -369,7 +362,7 @@ export function showSampleStationInfo(layerId, mapId = "homeMap") { `; - showPopupDetails(mapId, feature.geometry.coordinates, description, "450px"); + showPopupDetails({ mapId, coordinate: feature.geometry.coordinates, description, maxWidth: "450px" }); }); } @@ -413,12 +406,12 @@ export function showTrackInfo(layerId, mapId = "homeMap") { `; - showPopupDetails(mapId, coordinate, description, "420px"); + showPopupDetails({ coordinate, mapId, description, maxWidth: "420px" }); }) }); } -export function showPopupDetails(mapId, coordinate, description, maxWidth = "300px", closeButton = true, closeOnClick = true, options = {}) { +export function showPopupDetails({ mapId, coordinate, description, maxWidth = "300px", closeButton = true, closeOnClick = true, options = {}, callbackOnClose }) { const map = Vue.config.maps[mapId]; if (!map) return; @@ -446,7 +439,13 @@ export function showPopupDetails(mapId, coordinate, description, maxWidth = "300 .setOffset(10) .setMaxWidth(maxWidth) .addTo(map); - sharedPopup.on('close', () => { sharedPopup = null; }); + sharedPopup.on('close', () => { + sharedPopup = null; + // 关闭弹窗时执行回调(如有) + if (callbackOnClose && typeof callbackOnClose === "function") { + callbackOnClose(); + } + }); } } else { sharedPopup = new window.mapboxgl.Popup(popupOptions) @@ -455,13 +454,17 @@ export function showPopupDetails(mapId, coordinate, description, maxWidth = "300 .setOffset(10) .setMaxWidth(maxWidth) .addTo(map); - sharedPopup.on('close', () => { sharedPopup = null; }); + sharedPopup.on('close', () => { + sharedPopup = null; + // 关闭弹窗时执行回调(如有) + if (callbackOnClose && typeof callbackOnClose === "function") { + callbackOnClose(); + } + }); } } export async function loadJsonLineFeature(layerId, color, geojson, mapId) { - // console.log("layerId: ",layerId); - let source = Vue.config.maps[mapId].getSource(layerId); if (!source) { Vue.config.maps[mapId].addSource(layerId, { @@ -551,13 +554,11 @@ export async function loadJsonPointFeature(layerId, color, geojson, text_field, export async function highlightFeaturesByProperty(mapId, sourceId, layerId, propertyName = "sample_name", targetValue = "TARGET_VALUE") { // 清空所有高亮状态(可选) Vue.config.maps[mapId].querySourceFeatures(sourceId).forEach(f => { - console.log("AAAAA: ", f); Vue.config.maps[mapId].setFeatureState({ source: sourceId, id: f.id }, { highlight: false }); }); // 标记匹配要素 Vue.config.maps[mapId].querySourceFeatures(sourceId).forEach(f => { - console.log("BBBBB: ", f); if (f.properties && f.properties[propertyName] === targetValue) { Vue.config.maps[mapId].setFeatureState({ source: sourceId, id: f.id }, { highlight: true }); } diff --git a/src/views/statistics/AuvStatistics.vue b/src/views/statistics/AuvStatistics.vue index 6b31a28..9889f2a 100644 --- a/src/views/statistics/AuvStatistics.vue +++ b/src/views/statistics/AuvStatistics.vue @@ -64,6 +64,7 @@