优化地图 Popup 对象复用机制
This commit is contained in:
parent
21949e6057
commit
8ee0db5f3a
|
|
@ -3,9 +3,19 @@ import { regInfo } from '@/api/dataSearch'
|
|||
|
||||
let sourceLayer = undefined;
|
||||
let clickedLineIds = [];
|
||||
// 单例 Popup,用于确保地图上只有一个弹框实例
|
||||
let sharedPopup = null;
|
||||
// 存储可复用的每个地图对象的唯一 Popup 实例(key 为 mapId),以避免频繁创建/销毁 Popup 导致的性能问题和潜在内存泄漏
|
||||
let sharedPopup = {};
|
||||
|
||||
export function setMapLayoutProperty(mapId, visibility = "none") {
|
||||
// 设置所有图层的显示/隐藏状态(根据图层类型或名称过滤底图图层,避免误操作)
|
||||
const layers = Vue.config.maps[mapId].getStyle().layers;
|
||||
layers.forEach(layer => {
|
||||
// 跳过底图
|
||||
if (layer.id !== '影像地图' && layer.type !== 'raster') {
|
||||
Vue.config.maps[mapId].setLayoutProperty(layer.id, 'visibility', visibility);
|
||||
}
|
||||
});
|
||||
}
|
||||
export function loadVectorLayer(layerId, features = ["line", "symbol"], colors = ["#FEFEFE", "#FF0000"], visibility = "visible", mapId = "homeMap", workspace = 'dsds', textField = "name") {
|
||||
// 添加数据源
|
||||
const sourceId = `vector-${layerId}`;
|
||||
|
|
@ -140,6 +150,10 @@ export async function loadVectorFeature(layerId, feature, color, visibility, map
|
|||
await showSampleLineInfo(`${sourceId}-${feature}`, mapId);
|
||||
if (layerId.includes("sample_station"))
|
||||
await showSampleStationInfo(`${sourceId}-${feature}`, mapId);
|
||||
else if (sourceId.includes("-SY") || sourceId.includes("-FDZ")) {
|
||||
await showDiveInfo(`${sourceId}-${feature}`, mapId);
|
||||
console.log(mapId, `${sourceId}-${feature}`);
|
||||
}
|
||||
else
|
||||
await showTrackInfo(`${sourceId}-${feature}`, mapId);
|
||||
|
||||
|
|
@ -415,6 +429,36 @@ export function showTrackInfo(layerId, mapId = "homeMap") {
|
|||
});
|
||||
}
|
||||
|
||||
export function showDiveInfo(layerId, mapId = "homeMap") {
|
||||
Vue.config.maps[mapId].on("click", layerId, async (e) => {
|
||||
// 禁止点击事件穿透 - 判断同一个 event 是否已经触发,用于避免图层内标记点注册的点击事件重复触发(点位分布密集时容易出现)
|
||||
if (e.defaultPrevented)
|
||||
return;
|
||||
// 标记该 event 已触发,禁止点击事件穿透
|
||||
if (typeof e.preventDefault === "function")
|
||||
e.preventDefault();
|
||||
|
||||
const feature = e.features[0];
|
||||
let coordinate = e.lngLat;
|
||||
const description = `
|
||||
<table class="popup-table" style="min-width:280px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td colspan="2">潜次信息</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td colspan="2">潜次编号: <b>${feature.properties.name}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">created_at: <b>${feature.properties.created_at}</b></td>
|
||||
</tr>
|
||||
</table>`;
|
||||
|
||||
showPopupDetails({ mapId, coordinate, description, maxWidth: "300px" });
|
||||
})
|
||||
}
|
||||
|
||||
export function showPopupDetails({ mapId, coordinate, description, maxWidth = "300px", closeButton = true, closeOnClick = true, options = {}, callbackOnClose }) {
|
||||
const map = Vue.config.maps[mapId];
|
||||
if (!map)
|
||||
|
|
@ -423,28 +467,29 @@ export function showPopupDetails({ mapId, coordinate, description, maxWidth = "3
|
|||
const popupOptions = Object.assign({ offset: {}, className: "my-class", closeButton: closeButton, closeOnClick: closeOnClick }, options);
|
||||
|
||||
// 如果已有共享 popup,复用并更新位置/内容;否则创建新的并绑定 close 事件以便释放引用
|
||||
if (sharedPopup) {
|
||||
if (sharedPopup[mapId]) {
|
||||
try {
|
||||
sharedPopup.setLngLat(coordinate)
|
||||
sharedPopup[mapId].setLngLat(coordinate)
|
||||
.setHTML(description)
|
||||
.setOffset(10)
|
||||
.setMaxWidth(maxWidth);
|
||||
.setMaxWidth(maxWidth)
|
||||
.addTo(map);
|
||||
} catch (err) {
|
||||
console.error("设置 popup 失败:", err);
|
||||
try {
|
||||
// 万一现有 popup 状态异常,移除并重新创建
|
||||
sharedPopup.remove();
|
||||
sharedPopup = null;
|
||||
sharedPopup[mapId].remove();
|
||||
sharedPopup[mapId] = null;
|
||||
} catch (e) {
|
||||
console.error("移除异常 popup 失败:", e);
|
||||
}
|
||||
sharedPopup = new window.mapboxgl.Popup(popupOptions)
|
||||
sharedPopup[mapId] = new window.mapboxgl.Popup(popupOptions)
|
||||
.setLngLat(coordinate)
|
||||
.setHTML(description)
|
||||
.setOffset(10)
|
||||
.setMaxWidth(maxWidth)
|
||||
.addTo(map);
|
||||
sharedPopup.on('close', () => {
|
||||
sharedPopup = null;
|
||||
sharedPopup[mapId].on('close', () => {
|
||||
// 关闭弹窗时执行回调(如有)
|
||||
if (callbackOnClose && typeof callbackOnClose === "function") {
|
||||
callbackOnClose();
|
||||
|
|
@ -452,14 +497,13 @@ export function showPopupDetails({ mapId, coordinate, description, maxWidth = "3
|
|||
});
|
||||
}
|
||||
} else {
|
||||
sharedPopup = new window.mapboxgl.Popup(popupOptions)
|
||||
sharedPopup[mapId] = new window.mapboxgl.Popup(popupOptions)
|
||||
.setLngLat(coordinate)
|
||||
.setHTML(description)
|
||||
.setOffset(10)
|
||||
.setMaxWidth(maxWidth)
|
||||
.addTo(map);
|
||||
sharedPopup.on('close', () => {
|
||||
sharedPopup = null;
|
||||
sharedPopup[mapId].on('close', () => {
|
||||
// 关闭弹窗时执行回调(如有)
|
||||
if (callbackOnClose && typeof callbackOnClose === "function") {
|
||||
callbackOnClose();
|
||||
|
|
|
|||
Loading…
Reference in New Issue