|
@@ -1,44 +1,160 @@
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { onMounted, ref } from 'vue'
|
|
import { onMounted, ref } from 'vue'
|
|
|
|
|
+import OriginIcon from '../image/hhh_2.png'
|
|
|
import L from 'leaflet'
|
|
import L from 'leaflet'
|
|
|
-const MapDataList = ref()
|
|
|
|
|
|
|
+const MapDataList = ref([])
|
|
|
|
|
+
|
|
|
|
|
+const originIcon = L.icon({
|
|
|
|
|
+ iconUrl: OriginIcon,
|
|
|
|
|
+ iconSize: [0, 0],
|
|
|
|
|
+ iconAnchor: [10, 20],
|
|
|
|
|
+ popupAnchor: [0, -8]
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+let map: L.Map | null = null
|
|
|
const init = () => {
|
|
const init = () => {
|
|
|
- const map = L.map('map').setView([51.505, -0.09], 3)
|
|
|
|
|
|
|
+ if (map) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ map = L.map('map', { attributionControl: false }).setView([51.505, -0.09], 3)
|
|
|
|
|
|
|
|
L.tileLayer('https://map.kerryapex.com/osm_tiles/{z}/{x}/{y}.png', {
|
|
L.tileLayer('https://map.kerryapex.com/osm_tiles/{z}/{x}/{y}.png', {
|
|
|
- attribution: '© OpenStreetMap contributors'
|
|
|
|
|
|
|
+ attribution:
|
|
|
|
|
+ '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
|
}).addTo(map)
|
|
}).addTo(map)
|
|
|
|
|
|
|
|
- const popupOptions = {
|
|
|
|
|
- closeButton: false, // 移除关闭按钮
|
|
|
|
|
- autoClose: false, // 禁止点击其他地方自动关闭
|
|
|
|
|
- closeOnClick: false // 禁止点击地图时自动关闭
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const addResetZoomButton = (center: L.LatLng, zoom: number) => {
|
|
|
|
|
+ const ResetZoomControl = L.Control.extend({
|
|
|
|
|
+ options: {
|
|
|
|
|
+ position: 'topleft'
|
|
|
|
|
+ },
|
|
|
|
|
+ onAdd: function () {
|
|
|
|
|
+ const container = L.DomUtil.create('div', 'reset-zoom-control leaflet-bar')
|
|
|
|
|
|
|
|
- $api.GetTop10ODEcharts({}).then((res: any) => {
|
|
|
|
|
- if (res.code === 200) {
|
|
|
|
|
- MapDataList.value = res.data.toporiginMap
|
|
|
|
|
|
|
+ // 创建重置缩放按钮
|
|
|
|
|
+ const resetZoomButton = L.DomUtil.create(
|
|
|
|
|
+ 'a',
|
|
|
|
|
+ 'reset-zoom-button leaflet-bar-part',
|
|
|
|
|
+ container
|
|
|
|
|
+ )
|
|
|
|
|
+ resetZoomButton.href = '#'
|
|
|
|
|
+ resetZoomButton.title = 'Reset Zoom'
|
|
|
|
|
+ resetZoomButton.innerHTML = `<div class="outer-ring" style="height: 100%; padding: 4px;border: 1px solid #2b2f36;border-radius: 50%;">
|
|
|
|
|
+ <div class="inner-ring" style=" height: 100%; width: 100%; background-color: #2b2f36; border-radius: 50%;"></div>
|
|
|
|
|
+ </div>`
|
|
|
|
|
+ resetZoomButton.setAttribute('role', 'button')
|
|
|
|
|
+
|
|
|
|
|
+ // 点击按钮时重置地图到首次标记后的缩放和中心
|
|
|
|
|
+ resetZoomButton.addEventListener('click', () => {
|
|
|
|
|
+ map!.setView(center, zoom)
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- MapDataList.value.forEach((item: any) => {
|
|
|
|
|
- const marker = L.marker(item.qandl, { icon: L.divIcon(item.divIcon) }).addTo(map)
|
|
|
|
|
- // 绑定弹出框并立即展示
|
|
|
|
|
- marker
|
|
|
|
|
- .bindPopup(
|
|
|
|
|
- `
|
|
|
|
|
|
|
+ return container
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 添加重置按钮到地图
|
|
|
|
|
+ new ResetZoomControl().addTo(map!)
|
|
|
|
|
+ }
|
|
|
|
|
+ // 定义首次渲染地图的中心和缩放级别
|
|
|
|
|
+ let initialCenter: L.LatLng | null = null
|
|
|
|
|
+ let initialZoomLevel: number | null = null
|
|
|
|
|
+ let isFirstRender = true // 标记是否为首次渲染
|
|
|
|
|
+
|
|
|
|
|
+ const addMarkersToMap = () => {
|
|
|
|
|
+ if (!map) return // 确保地图已经初始化
|
|
|
|
|
+ const latLngBounds: any = [] // 用来存储所有标记的坐标
|
|
|
|
|
+ MapDataList.value.forEach((item: any) => {
|
|
|
|
|
+ const marker = L.marker(item.qandl, { icon: originIcon }).addTo(map)
|
|
|
|
|
+ const customPopupContent = `
|
|
|
<div class="popup-content" style="background-color:${item.color}">
|
|
<div class="popup-content" style="background-color:${item.color}">
|
|
|
<div class="popup-content-text">
|
|
<div class="popup-content-text">
|
|
|
<p class="popup-label" style="color:${item.textcolor}">${item.name}</p>
|
|
<p class="popup-label" style="color:${item.textcolor}">${item.name}</p>
|
|
|
<p class="popup-value" style="color:${item.textcolor}">${item.value}</p>
|
|
<p class="popup-value" style="color:${item.textcolor}">${item.value}</p>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- `,
|
|
|
|
|
- popupOptions
|
|
|
|
|
- )
|
|
|
|
|
- .openPopup()
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ `
|
|
|
|
|
+ marker
|
|
|
|
|
+ .bindPopup(customPopupContent, {
|
|
|
|
|
+ closeButton: false,
|
|
|
|
|
+ autoClose: false,
|
|
|
|
|
+ closeOnClick: false
|
|
|
|
|
+ })
|
|
|
|
|
+ .openPopup()
|
|
|
|
|
+ latLngBounds.push([item.qandl[0], item.qandl[1]])
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (latLngBounds.length > 0) {
|
|
|
|
|
+ const bounds = L.latLngBounds(latLngBounds)
|
|
|
|
|
+ map!.fitBounds(bounds, { paddingTopLeft: [20, 70], paddingBottomRight: [400, 0] })
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ if (isFirstRender) {
|
|
|
|
|
+ initialCenter = map!.getCenter()
|
|
|
|
|
+ initialZoomLevel = map!.getZoom()
|
|
|
|
|
+ isFirstRender = false
|
|
|
|
|
+ }
|
|
|
|
|
+ addResetZoomButton(initialCenter!, initialZoomLevel!)
|
|
|
|
|
+ }, 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $api.GetTop10ODEcharts({}).then((res: any) => {
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ res.data.toporiginMap &&
|
|
|
|
|
+ res.data.toporiginMap.forEach((item: any) => {
|
|
|
|
|
+ MapDataList.value.push({
|
|
|
|
|
+ color: item.color,
|
|
|
|
|
+ name: item.name,
|
|
|
|
|
+ qandl: item.qandl,
|
|
|
|
|
+ textcolor: item.textcolor,
|
|
|
|
|
+ value: item.value
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ // testList.value.forEach((item: any) => {
|
|
|
|
|
+ // MapDataList.value.push({
|
|
|
|
|
+ // color: item.color,
|
|
|
|
|
+ // name: item.name,
|
|
|
|
|
+ // qandl: item.qandl,
|
|
|
|
|
+ // textcolor: item.textcolor,
|
|
|
|
|
+ // value: item.value
|
|
|
|
|
+ // })
|
|
|
|
|
+ // })
|
|
|
|
|
+
|
|
|
|
|
+ // 请求成功后添加标记,并动态添加重置按钮
|
|
|
|
|
+ addMarkersToMap()
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
+const testList = ref([
|
|
|
|
|
+ {
|
|
|
|
|
+ color: '#fff1e6',
|
|
|
|
|
+ name: 'CNNSA',
|
|
|
|
|
+ qandl: ['127.7', '35.13333333'],
|
|
|
|
|
+ textcolor: '#FFF',
|
|
|
|
|
+ value: '5'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ color: '#ffe3cc',
|
|
|
|
|
+ name: 'CNTAO',
|
|
|
|
|
+ qandl: ['129.05', '35.13333333'],
|
|
|
|
|
+ textcolor: '#FFF',
|
|
|
|
|
+ value: '5'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ color: '#ffd6b3',
|
|
|
|
|
+ name: 'CNDLC',
|
|
|
|
|
+ qandl: [-76.61666667, 39.28333333],
|
|
|
|
|
+ textcolor: '#FFF',
|
|
|
|
|
+ value: '5'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ color: '#ffd6b3',
|
|
|
|
|
+ name: 'CNDLC',
|
|
|
|
|
+ qandl: [-86.61666667, 42.28333333],
|
|
|
|
|
+ textcolor: '#FFF',
|
|
|
|
|
+ value: '5'
|
|
|
|
|
+ }
|
|
|
|
|
+])
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
init()
|
|
init()
|
|
|
})
|
|
})
|
|
@@ -50,23 +166,22 @@ onMounted(() => {
|
|
|
<style lang="scss">
|
|
<style lang="scss">
|
|
|
@import 'leaflet/dist/leaflet.css';
|
|
@import 'leaflet/dist/leaflet.css';
|
|
|
#map {
|
|
#map {
|
|
|
- .leaflet-popup-content-wrapper {
|
|
|
|
|
- width: 58px !important;
|
|
|
|
|
- height: 58px;
|
|
|
|
|
- background: transparent !important;
|
|
|
|
|
- box-shadow: none !important;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /* 隐藏默认的弹出窗口箭头 */
|
|
|
.leaflet-popup-tip {
|
|
.leaflet-popup-tip {
|
|
|
- width: 0;
|
|
|
|
|
- height: 0;
|
|
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ }
|
|
|
|
|
+ #map {
|
|
|
|
|
+ .leaflet-touch {
|
|
|
|
|
+ .leaflet-bar {
|
|
|
|
|
+ border: 0;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .leaflet-popup-content-wrapper {
|
|
|
background: transparent !important;
|
|
background: transparent !important;
|
|
|
box-shadow: none !important;
|
|
box-shadow: none !important;
|
|
|
- color: transparent;
|
|
|
|
|
- }
|
|
|
|
|
- .leaflet-popup-tip-container {
|
|
|
|
|
- width: 0;
|
|
|
|
|
- height: 0;
|
|
|
|
|
- color: transparent;
|
|
|
|
|
}
|
|
}
|
|
|
.leaflet-popup-content {
|
|
.leaflet-popup-content {
|
|
|
width: 58px;
|
|
width: 58px;
|
|
@@ -94,4 +209,19 @@ onMounted(() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+/* 自定义重置缩放按钮控件样式 */
|
|
|
|
|
+.reset-zoom-control {
|
|
|
|
|
+ margin-top: 10px; /* 增加上边距,使按钮与默认缩放按钮之间有间距 */
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ background-color: white;
|
|
|
|
|
+ border: 1px solid #ccc;
|
|
|
|
|
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.reset-zoom-button {
|
|
|
|
|
+ background-color: white;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ padding: 6px;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|