This commit is contained in:
2026-07-30 15:50:31 +08:00
parent d464721a1c
commit 1b8fd95fb2
7 changed files with 105 additions and 77 deletions
+55 -18
View File
@@ -11,6 +11,8 @@ const mapContainer = ref(null)
let map = null
let markerLayer = null
let currentMarkers = []
let markerByPoiId = {}
let activeMarker = null
let radiusCircle = null
const emit = defineEmits(['marker-click', 'map-click'])
@@ -19,6 +21,30 @@ const emit = defineEmits(['marker-click', 'map-click'])
const amapTileUrl = 'https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
const amapSubdomains = ['1', '2', '3', '4']
// 蓝色默认图标
const blueIcon = L.divIcon({
className: '',
html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 42" width="32" height="42">
<path d="M16 2C8.268 2 2 8.268 2 16c0 9.678 14 24 14 24s14-14.322 14-24C30 8.268 23.732 2 16 2z" fill="#1a73e8" stroke="#fff" stroke-width="2"/>
<circle cx="16" cy="15" r="6" fill="#fff"/>
</svg>`,
iconSize: [32, 42],
iconAnchor: [16, 42],
popupAnchor: [0, -42],
})
// 红色选中图标
const redIcon = L.divIcon({
className: '',
html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 42" width="32" height="42">
<path d="M16 2C8.268 2 2 8.268 2 16c0 9.678 14 24 14 24s14-14.322 14-24C30 8.268 23.732 2 16 2z" fill="#e53935" stroke="#fff" stroke-width="2"/>
<circle cx="16" cy="15" r="6" fill="#fff"/>
</svg>`,
iconSize: [32, 42],
iconAnchor: [16, 42],
popupAnchor: [0, -42],
})
onMounted(() => {
map = L.map(mapContainer.value, {
center: [39.9042, 116.4074], // 北京
@@ -51,29 +77,20 @@ onUnmounted(() => {
function clearMarkers() {
markerLayer.clearLayers()
currentMarkers = []
markerByPoiId = {}
activeMarker = null
}
function addMarkers(pois) {
clearMarkers()
if (!map || !pois.length) return
const pinIcon = L.divIcon({
className: '',
html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 42" width="32" height="42">
<path d="M16 2C8.268 2 2 8.268 2 16c0 9.678 14 24 14 24s14-14.322 14-24C30 8.268 23.732 2 16 2z" fill="#1a73e8" stroke="#fff" stroke-width="2"/>
<circle cx="16" cy="15" r="6" fill="#fff"/>
</svg>`,
iconSize: [32, 42],
iconAnchor: [16, 42],
popupAnchor: [0, -42],
})
pois.forEach((poi) => {
const lat = parseFloat(poi.latitude)
const lng = parseFloat(poi.longitude)
if (isNaN(lat) || isNaN(lng)) return
const marker = L.marker([lat, lng], { icon: pinIcon }).addTo(markerLayer)
const marker = L.marker([lat, lng], { icon: blueIcon }).addTo(markerLayer)
marker.bindPopup(`
<div class="map-popup">
<h4>${poi.name}</h4>
@@ -84,12 +101,24 @@ function addMarkers(pois) {
`)
marker.on('click', () => {
setActiveMarker(marker)
emit('marker-click', poi)
})
currentMarkers.push(marker)
if (poi.poiId) {
markerByPoiId[poi.poiId] = marker
}
})
}
function setActiveMarker(marker) {
// 恢复上一个选中标记为蓝色
if (activeMarker && activeMarker !== marker) {
activeMarker.setIcon(blueIcon)
}
marker.setIcon(redIcon)
activeMarker = marker
}
function focusMarker(poi) {
@@ -100,14 +129,22 @@ function focusMarker(poi) {
// 先飞到该位置
flyTo(lat, lng, 15)
// 找到对应标记并弹窗
for (const marker of currentMarkers) {
const pos = marker.getLatLng()
if (Math.abs(pos.lat - lat) < 0.001 && Math.abs(pos.lng - lng) < 0.001) {
marker.openPopup()
break
// 按 poiId 查找
let marker = poi.poiId ? markerByPoiId[poi.poiId] : null
if (!marker) {
// 按坐标查找
for (const m of currentMarkers) {
const pos = m.getLatLng()
if (Math.abs(pos.lat - lat) < 0.001 && Math.abs(pos.lng - lng) < 0.001) {
marker = m
break
}
}
}
if (!marker) return
setActiveMarker(marker)
marker.openPopup()
}
// 地图跳转到指定坐标