Эх сурвалжийг харах

feat: 修改地图中心点判断

zhouyuhao 10 сар өмнө
parent
commit
f9bfdc0e08

+ 91 - 27
src/views/Tracking/src/components/TrackingDetail/src/components/MapView.vue

@@ -275,6 +275,56 @@ let isFirstRender = true // 标记是否为首次渲染
 let allMarkers = []
 let visibleMarkers = new Set()
 
+// 设置中心点之后的东北角和西南角的经纬度对象
+let latLngBoundsObj = ref({ northEast: { lat: 0, lng: 0 }, southWest: { lat: 0, lng: 0 } })
+// 设置中心和缩放级别
+const setCenterAndZoom = () => {
+  if (viewData.value.length > 0) {
+    // 根据标记的位置设置中心点以及缩放级别
+    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
+      }
+      addResetZoomButton(initialCenter!, initialZoomLevel!)
+    }, 500)
+  }
+}
+
+// 用来记录初始化时默认打开的弹出窗口,以便在地图移动时判断是否需要重新打开弹出窗口
+const popupObj = ref({})
+// 判断是否需要打开弹出窗口
+const shouldDisplayPopup = (isInit?: boolean) => {
+  Object.values(allMarkers).forEach((marker) => {
+    // 创建 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
+
+        marker.openPopup()
+      } else {
+        const popupItem = popupObj.value[`${marksLatLng.lat},${marksLatLng.lng}`]
+        // 如果用户没有关闭弹出窗口,则重新打开弹出窗口
+        if (popupItem) {
+          marker.openPopup()
+        }
+      }
+    }
+  })
+}
+
 // 添加标记后更新中心和缩放级别
 const addMarkersToMap = () => {
   if (!map) return // 确保地图已经初始化
@@ -291,31 +341,24 @@ const addMarkersToMap = () => {
         </p>
       </div>
     `
-    marker
-      .bindPopup(customPopupContent, {
-        closeButton: false,
-        autoClose: false,
-        closeOnClick: false
-      })
-      .openPopup()
+    marker.bindPopup(customPopupContent, {
+      closeButton: false,
+      autoClose: false,
+      autoPan: false, // 防止弹出框打开时移动地图
+      closeOnClick: false
+    })
+    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
   })
 
-  updateVisibleMarkers()
-
-  if (viewData.value.length > 0) {
-    // 根据标记的位置设置中心点以及缩放级别
-    const bounds = L.latLngBounds(viewData.value)
-    map!.fitBounds(bounds, { paddingTopLeft: [20, 70], paddingBottomRight: [0, 0] })
-    setTimeout(() => {
-      if (isFirstRender) {
-        initialCenter = map!.getCenter()
-        initialZoomLevel = map!.getZoom()
-        isFirstRender = false
-      }
-      addResetZoomButton(initialCenter!, initialZoomLevel!)
-    }, 1000)
-  }
+  updateVisibleMarkers(true)
 }
 
 // 新增轮船当前位置标记
@@ -380,7 +423,7 @@ const addShipMarker = (x: number) => {
 }
 
 // 更新可见标记
-const updateVisibleMarkers = () => {
+const updateVisibleMarkers = (isInit?: boolean) => {
   const newVisibleMarkers = new Set()
 
   let bnd = map.getBounds()
@@ -404,18 +447,30 @@ const updateVisibleMarkers = () => {
 
   // 计算当前视图中的标记,包括多地球的情况
   while (x >= cc1 && x <= cc2 && cc > 0) {
+    if (x === 0) {
+      x++
+      continue
+    }
     Object.values(allMarkers).forEach((marker) => {
       const latLng = marker.getLatLng()
       const key = `${latLng.lat},${latLng.lng},${x}`
       if (!allMarkers[key]) {
         const newMarker: any = L.marker([latLng.lat, latLng.lng + x * 360], {
           icon: marker.options.icon
-        })
-          .bindPopup(marker.getPopup().getContent(), marker.getPopup().options)
-          .openPopup()
+        }).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}` // 使用经纬度组合成一个唯一键
+
+          if (key in popupObj.value) {
+            popupObj.value[key] = newMarker.isPopupOpen() // 直接切换 isPopup 状态
+          }
+        })
         allMarkers[key] = newMarker
         map.addLayer(newMarker)
       }
@@ -430,6 +485,7 @@ const updateVisibleMarkers = () => {
 
   // 更新可见标记集合
   visibleMarkers = newVisibleMarkers
+  shouldDisplayPopup(isInit)
 }
 
 // 处理得到的数据
@@ -492,11 +548,19 @@ const getMarker = () => {
               iconColor: iconColorList[item.label].color
             })
           })
+        if (data?.rangePoint.length > 0) {
+          if (Number(data.rangePoint[2].lon) < Number(data.rangePoint[1].lon)) {
+            data.rangePoint[2].lon = Number(data.rangePoint[2].lon) + 360
+          }
+          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)]
           }
         )
+        setCenterAndZoom()
         // 请求成功后添加标记,并动态添加重置按钮
         addMarkersToMap()
         if (data?.dottedLine) {
@@ -740,4 +804,4 @@ onUnmounted(() => {
     }
   }
 }
-</style>
+</style>