Map.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <script setup lang="ts">
  2. import { onMounted } from 'vue'
  3. interface DeviceData {
  4. count: number
  5. children?: Record<string, number>
  6. }
  7. interface Window {
  8. BMapGL: any
  9. onBMapCallback: () => void
  10. }
  11. const deviceData: Record<string, DeviceData> = {
  12. '新疆': {
  13. count: 30,
  14. children: {
  15. '克拉玛依': 10,
  16. '乌鲁木齐': 10,
  17. '库尔勒': 10
  18. }
  19. },
  20. '北京': { count: 50 },
  21. '上海': { count: 45 },
  22. '广东': { count: 60 }
  23. }
  24. const loadBMap = (ak: string): Promise<any> => {
  25. return new Promise((resolve) => {
  26. if (window.BMapGL) return resolve(window.BMapGL)
  27. const script = document.createElement('script')
  28. script.src = `https://api.map.baidu.com/api?type=webgl&v=3.0&ak=c0crhdxQ5H7WcqbcazGr7mnHrLa4GmO0&callback=onBMapCallback`
  29. document.head.appendChild(script)
  30. window.onBMapCallback = () => resolve(window.BMapGL)
  31. })
  32. }
  33. const setupMap = async () => {
  34. try {
  35. const BMapGL = await loadBMap('您的AK密钥')
  36. const map = new BMapGL.Map('map-container')
  37. // 地球模式配置
  38. map.centerAndZoom(new BMapGL.Point(105, 35), 5)
  39. map.enableScrollWheelZoom()
  40. // map.setMapType(BMapGL.constants.MapType.EARTH)
  41. // 中国边界绘制
  42. new BMapGL.Boundary().get('中国', (rs: any) => {
  43. rs.boundaries.forEach((boundary: string) => {
  44. map.addOverlay(new BMapGL.Polygon(boundary, {
  45. strokeWeight: 2,
  46. strokeColor: "#ff0000"
  47. }))
  48. })
  49. })
  50. // 初始省级标注
  51. addProvinceLabels(map, BMapGL)
  52. // 缩放事件监听
  53. map.addEventListener('zoomend', () => {
  54. map.getZoom() >= 7
  55. ? showCityLabels(map, BMapGL)
  56. : addProvinceLabels(map, BMapGL)
  57. })
  58. } catch (error) {
  59. console.error('地图加载失败:', error)
  60. }
  61. }
  62. const addProvinceLabels = (map: any, BMapGL: any) => {
  63. map.clearOverlays()
  64. Object.entries(deviceData).forEach(([province, data]) => {
  65. const point = getCenterPoint(province)
  66. if (point) {
  67. const label = new BMapGL.Label(`${province}: ${data.count}台`, {
  68. position: point,
  69. offset: new BMapGL.Size(20, -10)
  70. })
  71. label.setStyle(labelStyle)
  72. map.addOverlay(label)
  73. }
  74. })
  75. }
  76. const showCityLabels = (map: any, BMapGL: any) => {
  77. const xinjiang = deviceData['新疆']
  78. if (xinjiang?.children) {
  79. Object.entries(xinjiang.children).forEach(([city, count]) => {
  80. const point = getCenterPoint(city)
  81. if (point) {
  82. const label = new BMapGL.Label(`${city}: ${count}台`, {
  83. position: point,
  84. offset: new BMapGL.Size(20, -10)
  85. })
  86. label.setStyle({...labelStyle, fontSize: '12px'})
  87. map.addOverlay(label)
  88. }
  89. })
  90. }
  91. }
  92. const labelStyle = {
  93. color: '#333',
  94. fontSize: '14px',
  95. border: '1px solid #ccc',
  96. backgroundColor: 'white',
  97. padding: '5px'
  98. }
  99. const getCenterPoint = (name: string): any => {
  100. const points: Record<string, [number, number]> = {
  101. '新疆': [87.6168, 43.8256],
  102. '北京': [116.4074, 39.9042],
  103. '上海': [121.4737, 31.2304],
  104. '广东': [113.2644, 23.1291],
  105. '克拉玛依': [84.8739, 45.5886],
  106. '乌鲁木齐': [87.6168, 43.8256],
  107. '库尔勒': [86.1467, 41.7686]
  108. }
  109. return points[name] && new BMapGL.Point(...points[name])
  110. }
  111. onMounted(setupMap)
  112. </script>
  113. <template>
  114. <div id="map-container"></div>
  115. </template>
  116. <style scoped>
  117. #map-container {
  118. width: 100%;
  119. height: 100vh;
  120. }
  121. </style>