|
@@ -0,0 +1,140 @@
|
|
|
|
+
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { onMounted } from 'vue'
|
|
|
|
+
|
|
|
|
+interface DeviceData {
|
|
|
|
+ count: number
|
|
|
|
+ children?: Record<string, number>
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+interface Window {
|
|
|
|
+ BMapGL: any
|
|
|
|
+ onBMapCallback: () => void
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const deviceData: Record<string, DeviceData> = {
|
|
|
|
+ '新疆': {
|
|
|
|
+ count: 30,
|
|
|
|
+ children: {
|
|
|
|
+ '克拉玛依': 10,
|
|
|
|
+ '乌鲁木齐': 10,
|
|
|
|
+ '库尔勒': 10
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ '北京': { count: 50 },
|
|
|
|
+ '上海': { count: 45 },
|
|
|
|
+ '广东': { count: 60 }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const loadBMap = (ak: string): Promise<any> => {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ if (window.BMapGL) return resolve(window.BMapGL)
|
|
|
|
+
|
|
|
|
+ const script = document.createElement('script')
|
|
|
|
+ script.src = `https://api.map.baidu.com/api?type=webgl&v=3.0&ak=c0crhdxQ5H7WcqbcazGr7mnHrLa4GmO0&callback=onBMapCallback`
|
|
|
|
+ document.head.appendChild(script)
|
|
|
|
+
|
|
|
|
+ window.onBMapCallback = () => resolve(window.BMapGL)
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const setupMap = async () => {
|
|
|
|
+ try {
|
|
|
|
+ const BMapGL = await loadBMap('您的AK密钥')
|
|
|
|
+ const map = new BMapGL.Map('map-container')
|
|
|
|
+
|
|
|
|
+ // 地球模式配置
|
|
|
|
+ map.centerAndZoom(new BMapGL.Point(105, 35), 5)
|
|
|
|
+ map.enableScrollWheelZoom()
|
|
|
|
+ // map.setMapType(BMapGL.constants.MapType.EARTH)
|
|
|
|
+
|
|
|
|
+ // 中国边界绘制
|
|
|
|
+ new BMapGL.Boundary().get('中国', (rs: any) => {
|
|
|
|
+ rs.boundaries.forEach((boundary: string) => {
|
|
|
|
+ map.addOverlay(new BMapGL.Polygon(boundary, {
|
|
|
|
+ strokeWeight: 2,
|
|
|
|
+ strokeColor: "#ff0000"
|
|
|
|
+ }))
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ // 初始省级标注
|
|
|
|
+ addProvinceLabels(map, BMapGL)
|
|
|
|
+
|
|
|
|
+ // 缩放事件监听
|
|
|
|
+ map.addEventListener('zoomend', () => {
|
|
|
|
+ map.getZoom() >= 7
|
|
|
|
+ ? showCityLabels(map, BMapGL)
|
|
|
|
+ : addProvinceLabels(map, BMapGL)
|
|
|
|
+ })
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('地图加载失败:', error)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const addProvinceLabels = (map: any, BMapGL: any) => {
|
|
|
|
+ map.clearOverlays()
|
|
|
|
+ Object.entries(deviceData).forEach(([province, data]) => {
|
|
|
|
+ const point = getCenterPoint(province)
|
|
|
|
+ if (point) {
|
|
|
|
+ const label = new BMapGL.Label(`${province}: ${data.count}台`, {
|
|
|
|
+ position: point,
|
|
|
|
+ offset: new BMapGL.Size(20, -10)
|
|
|
|
+ })
|
|
|
|
+ label.setStyle(labelStyle)
|
|
|
|
+ map.addOverlay(label)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const showCityLabels = (map: any, BMapGL: any) => {
|
|
|
|
+ const xinjiang = deviceData['新疆']
|
|
|
|
+ if (xinjiang?.children) {
|
|
|
|
+ Object.entries(xinjiang.children).forEach(([city, count]) => {
|
|
|
|
+ const point = getCenterPoint(city)
|
|
|
|
+ if (point) {
|
|
|
|
+ const label = new BMapGL.Label(`${city}: ${count}台`, {
|
|
|
|
+ position: point,
|
|
|
|
+ offset: new BMapGL.Size(20, -10)
|
|
|
|
+ })
|
|
|
|
+ label.setStyle({...labelStyle, fontSize: '12px'})
|
|
|
|
+ map.addOverlay(label)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const labelStyle = {
|
|
|
|
+ color: '#333',
|
|
|
|
+ fontSize: '14px',
|
|
|
|
+ border: '1px solid #ccc',
|
|
|
|
+ backgroundColor: 'white',
|
|
|
|
+ padding: '5px'
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const getCenterPoint = (name: string): any => {
|
|
|
|
+ const points: Record<string, [number, number]> = {
|
|
|
|
+ '新疆': [87.6168, 43.8256],
|
|
|
|
+ '北京': [116.4074, 39.9042],
|
|
|
|
+ '上海': [121.4737, 31.2304],
|
|
|
|
+ '广东': [113.2644, 23.1291],
|
|
|
|
+ '克拉玛依': [84.8739, 45.5886],
|
|
|
|
+ '乌鲁木齐': [87.6168, 43.8256],
|
|
|
|
+ '库尔勒': [86.1467, 41.7686]
|
|
|
|
+ }
|
|
|
|
+ return points[name] && new BMapGL.Point(...points[name])
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+onMounted(setupMap)
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<template>
|
|
|
|
+ <div id="map-container"></div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+#map-container {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100vh;
|
|
|
|
+}
|
|
|
|
+</style>
|