Kaynağa Gözat

数据分析页面地图组件替换为EvaluationTrafficMap

  - DataAnalysis: 地图组件从TongzhouTrafficMap替换为EvaluationTrafficMap,支持总览/单点/干线/区域四种评价模式
  - 新增currentMapMode计算属性,根据左侧Tab和评价Tab联动切换地图显示模式
画安 2 hafta önce
ebeveyn
işleme
c8256f559f

+ 252 - 0
src/components/ui/EvaluationTrafficMap.vue

@@ -0,0 +1,252 @@
+<template>
+  <div class="map-wrapper">
+    <div ref="mapContainer" class="map-container"></div>
+  </div>
+</template>
+
+<script>
+import AMapLoader from '@amap/amap-jsapi-loader';
+
+export default {
+  name: "EvaluationTrafficMap",
+  props: {
+    amapKey: { type: String, required: true },
+    securityJsCode: { type: String, required: true },
+    mode: { 
+      type: String, 
+      default: 'overview',
+      validator: (val) => ['overview', 'singlePoint', 'trunkLine', 'area'].includes(val)
+    }
+  },
+  data() {
+    return {
+      AMap: null,
+      map: null,
+      overlays: [], // 统一管理当前地图上的所有覆盖物
+    };
+  },
+  watch: {
+    // 监听模式变化,重新绘制地图元素
+    mode(newMode) {
+      this.updateMapDisplay();
+    }
+  },
+  mounted() {
+    this.initAMap();
+  },
+  beforeDestroy() {
+    if (this.map) {
+      this.map.destroy();
+      this.map = null;
+    }
+  },
+  methods: {
+    async initAMap() {
+      window._AMapSecurityConfig = { securityJsCode: this.securityJsCode };
+      try {
+        const AMap = await AMapLoader.load({
+          key: this.amapKey,
+          version: "2.0",
+        });
+        this.AMap = AMap;
+        this.map = new AMap.Map(this.$refs.mapContainer, {
+          zoom: 13,
+          mapStyle: "amap://styles/darkblue",
+          center: [116.66, 39.91], // 通州区
+        });
+
+        this.map.on('complete', () => {
+          this.updateMapDisplay();
+        });
+      } catch (err) {
+        console.error('地图加载失败:', err);
+      }
+    },
+
+    clearOverlays() {
+      if (this.map && this.overlays.length > 0) {
+        this.map.remove(this.overlays);
+        this.overlays = [];
+      }
+    },
+
+    updateMapDisplay() {
+      if (!this.map || !this.AMap) return;
+      this.clearOverlays();
+
+      switch (this.mode) {
+        case 'overview':
+          this.drawOverview();
+          break;
+        case 'singlePoint':
+          this.drawSinglePoint();
+          break;
+        case 'trunkLine':
+          this.drawTrunkLine();
+          break;
+        case 'area':
+          this.drawArea();
+          break;
+      }
+    },
+
+    // 1. 绘制总览:简单的红黄绿圆点
+    drawOverview() {
+      const mockData = [
+        { pos: [116.65, 39.90], color: '#00FF00' }, { pos: [116.66, 39.91], color: '#FF0000' },
+        { pos: [116.67, 39.89], color: '#FFA500' }, { pos: [116.69, 39.92], color: '#00FF00' },
+        { pos: [116.64, 39.93], color: '#FF0000' }, { pos: [116.70, 39.90], color: '#FFA500' },
+        { pos: [116.68, 39.91], color: '#00FF00' }, { pos: [116.66, 39.93], color: '#FF0000' },
+      ];
+
+      mockData.forEach(item => {
+        const marker = new this.AMap.Marker({
+          position: item.pos,
+          content: `<div style="width: 12px; height: 12px; background-color: ${item.color}; border-radius: 50%; box-shadow: 0 0 5px ${item.color}; border: 1px solid #fff;"></div>`,
+          offset: new this.AMap.Pixel(-6, -6),
+        });
+        this.overlays.push(marker);
+      });
+      this.map.add(this.overlays);
+    },
+
+    // 2. 绘制评价监测-单点:带 A-F 字母和对应颜色的点
+    drawSinglePoint() {
+      const colors = { A: '#8fc31f', B: '#d7df23', C: '#fff200', D: '#f39c12', E: '#e74c3c', F: '#c0392b' };
+      const mockData = [
+        { pos: [116.63, 39.90], level: 'A' }, { pos: [116.65, 39.91], level: 'B' },
+        { pos: [116.66, 39.89], level: 'C' }, { pos: [116.68, 39.88], level: 'D' },
+        { pos: [116.70, 39.91], level: 'E' }, { pos: [116.71, 39.90], level: 'F' },
+        { pos: [116.67, 39.90], level: 'B' }, { pos: [116.69, 39.89], level: 'C' },
+        { pos: [116.65, 39.88], level: 'A' }, { pos: [116.69, 39.87], level: 'D' },
+      ];
+
+      mockData.forEach(item => {
+        const marker = new this.AMap.Marker({
+          position: item.pos,
+          content: `
+            <div style="width: 20px; height: 20px; background-color: ${colors[item.level]}; border-radius: 50%; display: flex; justify-content: center; align-items: center; color: #fff; font-weight: bold; font-size: 12px; border: 2px solid rgba(255,255,255,0.5);">
+              ${item.level}
+            </div>
+          `,
+          offset: new this.AMap.Pixel(-10, -10),
+        });
+        this.overlays.push(marker);
+      });
+      this.map.add(this.overlays);
+    },
+
+    // 3. 绘制评价监测-干线:绿色波段线段
+    drawTrunkLine() {
+      const lines = [
+        [[116.65, 39.91], [116.69, 39.92]],
+        [[116.64, 39.90], [116.70, 39.91]],
+        [[116.65, 39.89], [116.70, 39.89]],
+        [[116.66, 39.88], [116.68, 39.85]],
+      ];
+
+      lines.forEach(path => {
+        // 画线
+        const polyline = new this.AMap.Polyline({
+          path: path,
+          isOutline: true,
+          outlineColor: '#fff',
+          borderWeight: 1,
+          strokeColor: "#a6ce39", 
+          strokeOpacity: 0.9,
+          strokeWeight: 5,
+        });
+        this.overlays.push(polyline);
+
+        // 在线段两端或中间画点作为路口标识
+        path.forEach(pos => {
+          const marker = new this.AMap.Marker({
+            position: pos,
+            content: `<div style="width: 10px; height: 10px; background-color: #fff; border-radius: 50%; border: 2px solid #a6ce39;"></div>`,
+            offset: new this.AMap.Pixel(-5, -5),
+          });
+          this.overlays.push(marker);
+        });
+      });
+      this.map.add(this.overlays);
+    },
+
+    // 4. 绘制评价监测-区域:半透明多边形 + 中心文字
+    drawArea() {
+      const areas = [
+        {
+          path: [[116.67, 39.94], [116.70, 39.94], [116.71, 39.92], [116.70, 39.91], [116.67, 39.91]],
+          color: '#d35400', label: '6.2', center: [116.69, 39.925]
+        },
+        {
+          path: [[116.68, 39.90], [116.72, 39.90], [116.72, 39.88], [116.68, 39.88]],
+          color: '#c0392b', label: '4.5', center: [116.70, 39.89]
+        },
+        {
+          path: [[116.67, 39.87], [116.71, 39.87], [116.71, 39.85], [116.67, 39.85]],
+          color: '#c0392b', label: '4.8', center: [116.69, 39.86]
+        }
+      ];
+
+      areas.forEach(area => {
+        // 绘制多边形
+        const polygon = new this.AMap.Polygon({
+          path: area.path,
+          fillColor: area.color,
+          fillOpacity: 0.4,
+          strokeColor: area.color,
+          strokeWeight: 2,
+        });
+        this.overlays.push(polygon);
+
+        // 绘制中心数字标识
+        const textMarker = new this.AMap.Marker({
+          position: area.center,
+          content: `<div style="color: rgba(255,255,255,0.8); font-size: 24px; font-weight: bold; text-shadow: 1px 1px 2px #000;">${area.label}</div>`,
+          offset: new this.AMap.Pixel(-15, -15),
+        });
+        this.overlays.push(textMarker);
+      });
+
+      // 画一个圆形的区域 (对应图中的绿色 9.1)
+      const circle = new this.AMap.Circle({
+        center: [116.64, 39.88],
+        radius: 1800,
+        fillColor: '#27ae60',
+        fillOpacity: 0.4,
+        strokeColor: '#27ae60',
+        strokeWeight: 2,
+      });
+      this.overlays.push(circle);
+
+      const circleText = new this.AMap.Marker({
+        position: [116.64, 39.88],
+        content: `<div style="color: rgba(255,255,255,0.8); font-size: 24px; font-weight: bold; text-shadow: 1px 1px 2px #000;">9.1</div>`,
+        offset: new this.AMap.Pixel(-15, -15),
+      });
+      this.overlays.push(circleText);
+
+      this.map.add(this.overlays);
+    }
+  }
+};
+</script>
+
+<style scoped>
+.map-wrapper {
+  width: 100%;
+  height: 100vh;
+  position: relative;
+  background: #010813;
+}
+.map-container {
+  width: 100%;
+  height: 100%;
+}
+/* 隐藏高德Logo等 */
+::v-deep .amap-logo,
+::v-deep .amap-copyright,
+::v-deep .amap-copyright-logo {
+  display: none !important;
+}
+</style>

+ 17 - 6
src/views/DataAnalysis.vue

@@ -11,10 +11,11 @@
 
         <!-- 地图 -->
         <template #map>
-            <TongzhouTrafficMap amapKey="db2da7e3e248c3b2077d53fc809be63f"
+            <EvaluationTrafficMap 
+                amapKey="db2da7e3e248c3b2077d53fc809be63f"
                 securityJsCode="a7413c674852c5eaf01d90813c5b7ef6"
-                :mode="activeLeftTab === 'crossing' ? '路口' : activeLeftTab === 'trunkLine' ? '干线' : activeLeftTab === 'specialDuty' ? '特勤' : ''"
-                @map-crossing-click="handleMapCrossingClick" />
+                :mode="currentMapMode" 
+            />
         </template>
 
         <template #left>
@@ -163,21 +164,21 @@ import DashboardLayout from '@/layouts/DashboardLayout.vue';
 import DateTimeWidget from '@/components/ui/DateTimeWidget.vue';
 import TechTabs from '@/components/ui/TechTabs.vue';
 import TechTabPane from '@/components/ui/TechTabPane.vue';
-import TongzhouTrafficMap from '@/components/TongzhouTrafficMap.vue';
+import EvaluationTrafficMap from '@/components/ui/EvaluationTrafficMap.vue';
 import PanelContainer from '@/components/ui/PanelContainer.vue';
 
 import { apiGetTongzhouMenuTree, } from '@/api';
 
 
 export default {
-    name: "HomePage",
+    name: "DataAnalysis",
     components: {
         DashboardLayout,
         DateTimeWidget,
         TechTabs,
         TechTabPane,
         PanelContainer,
-        TongzhouTrafficMap,
+        EvaluationTrafficMap,
     },
     data() {
         return {
@@ -186,6 +187,16 @@ export default {
             activeTab: 'singlePoint',
         };
     },
+    computed: {
+        currentMapMode() {
+            if (this.activeLeftTab === 'overview') {
+                return 'overview';
+            } else if (this.activeLeftTab === 'evaluation') {
+                return this.activeTab; 
+            }
+            return 'overview'; 
+        }
+    },
     created() {
 
     },