Browse Source

fix: 修改不地图默认不打开标记弹窗bug

zhouyuhao 10 months ago
parent
commit
5899a84904

+ 50 - 46
src/views/Tracking/src/components/TrackingDetail/src/components/MapView.vue

@@ -12,7 +12,6 @@ import L from 'leaflet'
 import DestinationIcon from '../images/destinationIcon.png'
 import OriginIcon from '../images/originIcon.png'
 import TransferIcon from '../images/transferIcon.png'
-import { onMounted, ref, watch } from 'vue'
 import * as turf from '@turf/turf'
 import { useThemeStore } from '@/stores/modules/theme'
 
@@ -272,8 +271,7 @@ let initialCenter: L.LatLng | null = null
 let initialZoomLevel: number | null = null
 let isFirstRender = true // 标记是否为首次渲染
 
-let allMarkers = []
-let visibleMarkers = new Set()
+let mirrorMarkers = ref({})
 
 // 设置中心点之后的东北角和西南角的经纬度对象
 let latLngBoundsObj = ref({ northEast: { lat: 0, lng: 0 }, southWest: { lat: 0, lng: 0 } })
@@ -283,17 +281,19 @@ const setCenterAndZoom = () => {
     // 根据标记的位置设置中心点以及缩放级别
     const bounds = L.latLngBounds(viewData.value)
     map!.fitBounds(bounds, { paddingTopLeft: [20, 70], paddingBottomRight: [0, 0] })
-    const curLatLon = map.getBounds()
-    latLngBoundsObj.value = {
-      northEast: { lat: curLatLon.getNorth(), lng: curLatLon.getEast() },
-      southWest: { lat: curLatLon.getSouth(), lng: curLatLon.getWest() }
-    }
+
     setTimeout(() => {
       if (isFirstRender) {
         initialCenter = map!.getCenter()
         initialZoomLevel = map!.getZoom()
         isFirstRender = false
       }
+      // 获取东北角和西南角的经纬度
+      const curLatLon = map.getBounds()
+      latLngBoundsObj.value = {
+        northEast: { lat: curLatLon.getNorth(), lng: curLatLon.getEast() },
+        southWest: { lat: curLatLon.getSouth(), lng: curLatLon.getWest() }
+      }
       addResetZoomButton(initialCenter!, initialZoomLevel!)
     }, 500)
   }
@@ -301,31 +301,42 @@ const setCenterAndZoom = () => {
 
 // 用来记录初始化时默认打开的弹出窗口,以便在地图移动时判断是否需要重新打开弹出窗口
 const popupObj = ref({})
+// 将经纬度格式化为四位小数,防止精度问题
+const formatLocationNum = (num: string | number) => {
+  return Number(num).toFixed(4)
+}
 // 判断是否需要打开弹出窗口
 const shouldDisplayPopup = (isInit?: boolean) => {
-  Object.values(allMarkers).forEach((marker) => {
+  const allMarkers = {
+    ...initMarksObj.value,
+    ...mirrorMarkers.value
+  }
+  Object.values(allMarkers).forEach((marker: any) => {
     // 创建 LatLngBounds 对象
     const bounds = L.latLngBounds(latLngBoundsObj.value.southWest, latLngBoundsObj.value.northEast)
     const marksLatLng = marker.getLatLng()
     // 检查标记是否在边界内
     const isInsideBounds = bounds.contains(marksLatLng)
-    if (isInsideBounds) {
-      if (isInit) {
-        popupObj.value[`${marksLatLng.lat},${marksLatLng.lng}`] = true
-
+    const locationKey = `${formatLocationNum(marksLatLng.lat)},${formatLocationNum(marksLatLng.lng)}`
+    if (!isInsideBounds) return
+    if (isInit) {
+      if (!popupObj.value[locationKey]) {
+        popupObj.value[locationKey] = true
+        marker.openPopup()
+      }
+    } else {
+      const popupItem = popupObj.value[locationKey]
+      // 如果用户没有关闭弹出窗口,则重新打开弹出窗口
+      if (popupItem) {
         marker.openPopup()
-      } else {
-        const popupItem = popupObj.value[`${marksLatLng.lat},${marksLatLng.lng}`]
-        // 如果用户没有关闭弹出窗口,则重新打开弹出窗口
-        if (popupItem) {
-          marker.openPopup()
-        }
       }
     }
   })
 }
 
-// 添加标记后更新中心和缩放级别
+// 初始标记的位置
+const initMarksObj = ref({})
+// 添加标记
 const addMarkersToMap = () => {
   if (!map) return // 确保地图已经初始化
 
@@ -350,15 +361,15 @@ const addMarkersToMap = () => {
     marker.on('click', () => {
       const latLng = marker.getLatLng() // 获取标记的经纬度
       const key = `${latLng.lat},${latLng.lng}` // 使用经纬度组合成一个唯一键
-
       if (key in popupObj.value) {
         popupObj.value[key] = marker.isPopupOpen() // 直接切换 isPopup 状态
       }
     })
-    allMarkers[`${position.lat},${position.lng}`] = marker
+    initMarksObj.value[`${position.lat},${position.lng}`] = marker
   })
-
-  updateVisibleMarkers(true)
+  setTimeout(() => {
+    updateVisibleMarkers(true)
+  }, 1000)
 }
 
 // 新增轮船当前位置标记
@@ -437,32 +448,28 @@ const updateVisibleMarkers = (isInit?: boolean) => {
 
   let x = cc1
 
-  // 移除不再可见的标记
-  visibleMarkers.forEach((marker: any) => {
-    if (!newVisibleMarkers.has(marker)) {
-      map.removeLayer(marker)
-      delete allMarkers[`${marker.getLatLng().lat},${marker._lng},${marker._x}`]
-    }
+  // 移除所有标记
+  Object.values(mirrorMarkers.value).forEach((marker: any) => {
+    map.removeLayer(marker)
+    delete mirrorMarkers.value[`${marker.getLatLng().lat},${marker.getLatLng().lng}`]
   })
 
   // 计算当前视图中的标记,包括多地球的情况
   while (x >= cc1 && x <= cc2 && cc > 0) {
     if (x === 0) {
+      addShipMarker(x)
       x++
+      cc--
       continue
     }
-    Object.values(allMarkers).forEach((marker) => {
+    Object.values(initMarksObj.value).forEach((marker: any) => {
       const latLng = marker.getLatLng()
-      const key = `${latLng.lat},${latLng.lng},${x}`
-      if (!allMarkers[key]) {
+      const key = `${latLng.lat},${latLng.lng + x * 360}`
+      if (!mirrorMarkers.value[key]) {
         const newMarker: any = L.marker([latLng.lat, latLng.lng + x * 360], {
           icon: marker.options.icon
         }).bindPopup(marker.getPopup().getContent(), marker.getPopup().options)
 
-        newMarker._x = x
-        // 使用原始的经度作为标记的唯一标识
-        newMarker._lng = latLng.lng
-
         newMarker.on('click', () => {
           const latLng = newMarker.getLatLng() // 获取标记的经纬度
           const key = `${latLng.lat},${latLng.lng}` // 使用经纬度组合成一个唯一键
@@ -471,10 +478,10 @@ const updateVisibleMarkers = (isInit?: boolean) => {
             popupObj.value[key] = newMarker.isPopupOpen() // 直接切换 isPopup 状态
           }
         })
-        allMarkers[key] = newMarker
+        mirrorMarkers.value[key] = newMarker
         map.addLayer(newMarker)
       }
-      newVisibleMarkers.add(allMarkers[key])
+      newVisibleMarkers.add(mirrorMarkers.value[key])
     })
 
     addShipMarker(x)
@@ -482,9 +489,6 @@ const updateVisibleMarkers = (isInit?: boolean) => {
     x++
     cc--
   }
-
-  // 更新可见标记集合
-  visibleMarkers = newVisibleMarkers
   shouldDisplayPopup(isInit)
 }
 
@@ -554,15 +558,15 @@ const getMarker = () => {
           }
           data.rangePoint.splice(0, 1)
         }
-
         viewData.value = (data?.rangePoint.length > 0 ? data?.rangePoint : data?.point)?.map(
           (item) => {
-            return [Number(item.lat), Number(item.lon || item.lng)]
+            return { lat: Number(item.lat), lng: Number(item.lon || item.lng) }
           }
         )
-        setCenterAndZoom()
-        // 请求成功后添加标记,并动态添加重置按钮
+        // 请求成功后添加标记
         addMarkersToMap()
+        // 设置中心和缩放级别
+        setCenterAndZoom()
         if (data?.dottedLine) {
           draw_marker(handleData(data.dottedLine), handleData(data.solidLine))
           map.on('moveend', function () {