|
@@ -275,6 +275,56 @@ let isFirstRender = true // 标记是否为首次渲染
|
|
|
let allMarkers = []
|
|
let allMarkers = []
|
|
|
let visibleMarkers = new Set()
|
|
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 = () => {
|
|
const addMarkersToMap = () => {
|
|
|
if (!map) return // 确保地图已经初始化
|
|
if (!map) return // 确保地图已经初始化
|
|
@@ -291,31 +341,24 @@ const addMarkersToMap = () => {
|
|
|
</p>
|
|
</p>
|
|
|
</div>
|
|
</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
|
|
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()
|
|
const newVisibleMarkers = new Set()
|
|
|
|
|
|
|
|
let bnd = map.getBounds()
|
|
let bnd = map.getBounds()
|
|
@@ -404,18 +447,30 @@ const updateVisibleMarkers = () => {
|
|
|
|
|
|
|
|
// 计算当前视图中的标记,包括多地球的情况
|
|
// 计算当前视图中的标记,包括多地球的情况
|
|
|
while (x >= cc1 && x <= cc2 && cc > 0) {
|
|
while (x >= cc1 && x <= cc2 && cc > 0) {
|
|
|
|
|
+ if (x === 0) {
|
|
|
|
|
+ x++
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
Object.values(allMarkers).forEach((marker) => {
|
|
Object.values(allMarkers).forEach((marker) => {
|
|
|
const latLng = marker.getLatLng()
|
|
const latLng = marker.getLatLng()
|
|
|
const key = `${latLng.lat},${latLng.lng},${x}`
|
|
const key = `${latLng.lat},${latLng.lng},${x}`
|
|
|
if (!allMarkers[key]) {
|
|
if (!allMarkers[key]) {
|
|
|
const newMarker: any = L.marker([latLng.lat, latLng.lng + x * 360], {
|
|
const newMarker: any = L.marker([latLng.lat, latLng.lng + x * 360], {
|
|
|
icon: marker.options.icon
|
|
icon: marker.options.icon
|
|
|
- })
|
|
|
|
|
- .bindPopup(marker.getPopup().getContent(), marker.getPopup().options)
|
|
|
|
|
- .openPopup()
|
|
|
|
|
|
|
+ }).bindPopup(marker.getPopup().getContent(), marker.getPopup().options)
|
|
|
|
|
+
|
|
|
newMarker._x = x
|
|
newMarker._x = x
|
|
|
// 使用原始的经度作为标记的唯一标识
|
|
// 使用原始的经度作为标记的唯一标识
|
|
|
newMarker._lng = latLng.lng
|
|
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
|
|
allMarkers[key] = newMarker
|
|
|
map.addLayer(newMarker)
|
|
map.addLayer(newMarker)
|
|
|
}
|
|
}
|
|
@@ -430,6 +485,7 @@ const updateVisibleMarkers = () => {
|
|
|
|
|
|
|
|
// 更新可见标记集合
|
|
// 更新可见标记集合
|
|
|
visibleMarkers = newVisibleMarkers
|
|
visibleMarkers = newVisibleMarkers
|
|
|
|
|
+ shouldDisplayPopup(isInit)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 处理得到的数据
|
|
// 处理得到的数据
|
|
@@ -492,11 +548,19 @@ const getMarker = () => {
|
|
|
iconColor: iconColorList[item.label].color
|
|
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(
|
|
viewData.value = (data?.rangePoint.length > 0 ? data?.rangePoint : data?.point)?.map(
|
|
|
(item) => {
|
|
(item) => {
|
|
|
return [Number(item.lat), Number(item.lon || item.lng)]
|
|
return [Number(item.lat), Number(item.lon || item.lng)]
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
+ setCenterAndZoom()
|
|
|
// 请求成功后添加标记,并动态添加重置按钮
|
|
// 请求成功后添加标记,并动态添加重置按钮
|
|
|
addMarkersToMap()
|
|
addMarkersToMap()
|
|
|
if (data?.dottedLine) {
|
|
if (data?.dottedLine) {
|
|
@@ -740,4 +804,4 @@ onUnmounted(() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
|
|
+</style>
|