vue使用高德地图

224 阅读1分钟

此文章仅用于记录本人的高德地图用法


引入依赖

在public/index.html中引入

<script type="text/javascript"
      src="https://webapi.amap.com/maps?v=2.0&key=********* 高德地图的key *********&plugin=Amap.Geocoder,AMap.GeoJSON,AMap.MarkerClusterer,AMap.Autocomplete,Map3D,AMap.DistrictSearch,AMap.DistrictLayer,AMap.PolylineEditor">
</script>
<script src="https://webapi.amap.com/ui/1.1/main.js"></script>
<script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>

修改配置

在vue.config.js中修改配置

// 高德地图
configureWebpack(config) {
  config.externals = {
    'AMap': 'AMap' // 高德地图配置
  };
},

在页面中渲染高德地图

<template>
  <div id="map"></div>
</template>

<script>
import AMap from 'AMap';
import echarts from 'echarts';
import { getAlarmMarkerContent } from './mapUtil';
import { getPieOption } from './echart.pie.config';
import { screenApi } from '@/common/request/api.js'

export default {
  data() {
    return {
      warnIcon: require('@/assets/image/map-warn-icon.png'), // 警告icon
      fenceIcon: require('@/assets/image/icon-fence.png'), // 道闸icon
      monitorIcon: require('@/assets/image/icon-monitor.png'), // 监控icon
      brendIcon: require('@/assets/image/icon-brend.png'), // 诱导屏icon
      map: null,
      timer: null,
      colorList: ['#F8E71C', '#EB646A', '#50E3C2', '#4A90E2', '#4D63EE'], // 五种虚线描边随机取
      colorCurIndex: 0, // 虚线描边颜色当前位置
      allMarker: [], // 所有的警告maker点位
      polylineList: [], // 所有的道路线条
      parkingSpaceMarker: [], // 停车场饱和度饼图marker
      parkingNameMarker: [], // 停车场名称marker
    }
  },
  mounted() {
    this.MapInit(); // 初始化地图
    this.getParkingPosxy(); // 绘制停车场边界
    this.getAlarmList(); // 警告点位(设备故障marker)
    this.getRoadLine(); // 获取道路线段(矢量图)
    this.parkingSpaceChart(); // 获取停车场饱和度(饼图)
    
    this.timer = setInterval(this.parkingSpaceChart, 10000); // 停车场饱和度10秒一刷新
  },
  beforeDestroy() {
    clearInterval(this.timer)
  },
  methods: {
  	// 高德地图实例化
    MapInit() {
      this.map = new AMap.Map("map", {
        center: [113.348489, 23.006061],
        mapStyle: "amap://styles/3f5a24469182216607b4d03abc5c3efe", //设置地图的显示样式,这里是UI设计的样式key
        resizeEnable: true,
        zoom: 16,
        draggable: true,
        showLabel: true,
      });
    },
    // 接口:获取停车场边界(地图画区域)
    async getParkingPosxy() {
      const res = await screenApi.parkingPosxy();
      const allParkingPosxyList = res.data || [];
      allParkingPosxyList.forEach(item => {
        const posxy = item.posxy || [];
        this.addArea(posxy); // 绘制边界
      })
      this.dragParkingName(allParkingPosxyList); // 绘制停车场名称marker
    },
    // 接口:获取设备报警列表(地图画点位)
    async getAlarmList() {
      const res = await screenApi.getAlarmList();
      const alarmList = res.data || [];
      if(!Array.isArray(alarmList) || alarmList.length <= 0) return;
      this.dragMapAlarmMarker(alarmList); // 绘制设备报警点位
    },
    // 接口:获取道路线段(矢量图)
    async getRoadLine() {
      const res = await screenApi.roadPosxy();
      const roadLineList = res.data || [];
      if(!Array.isArray(roadLineList) || roadLineList.length <= 0) return;
      this.dragMapRoadLine(roadLineList); // 绘制道路轨迹图
    },
    // 获取停车场饱和度(饼图)
    async parkingSpaceChart() {
      const res = await screenApi.parkingSpaceChart();
      const parkingList = res.data || [];
      if(!Array.isArray(parkingList) || parkingList.length <= 0) return;
      this.dragMapParkingPie(parkingList); // 绘制停车场饱和度饼图
    },
    // 描线(区域)
    addArea(posxy) {
      if(!posxy || !Array.isArray(posxy) || posxy.length <= 0) return;
      var path = [];
      posxy.forEach(item => {
        path.push(new AMap.LngLat(item.x, item.y))
      })
      const polygon = new AMap.Polygon({
        path: path,  
        fillColor: this.colorList[this.colorCurIndex], // 多边形填充颜色
        fillOpacity: 0.2, // 多边形填充透明度,取值范围[0,1],0表示完全透明,1表示不透明。默认为0.9
        borderWeight: 2, // 线条宽度,默认为 1
        strokeColor: this.colorList[this.colorCurIndex], // 线条颜色
        strokeStyle: 'dashed', // 轮廓线样式,实线:solid,虚线:dashed
      });
      this.map.add(polygon);
      this.colorCurIndex = this.colorCurIndex + 1;
      if(this.colorCurIndex > 4) this.colorCurIndex = 0;
    },
    // 绘制停车场名称marker
    dragParkingName(parkList) {
      this.map.remove(this.parkingNameMarker)
      this.parkingNameMarker= []
      this.colorCurIndex = 0;
      parkList.forEach(item => {
        var marker = new AMap.Marker({
          position: new AMap.LngLat(item.longitude, item.latitude),
          offset: new AMap.Pixel(-70, -15),
          content: `<div style="color: ${this.colorList[this.colorCurIndex]}; font-size: 20px; width: 120px;">${item.parkingName}</div>`
        });
        this.parkingNameMarker.push(marker)
        this.colorCurIndex = this.colorCurIndex + 1;
        if(this.colorCurIndex > 4) this.colorCurIndex = 0;
      })
      this.map.add(this.parkingNameMarker);
    },
    // 绘制设备报警点位
    dragMapAlarmMarker(alarmList) {
      this.map.remove(this.allMarker)
      this.allMarker= []
      alarmList.forEach(item => {
        // 设备类型  0:一体机、1:视频监控设备、2:环路车流量卡口设备、3:蓝牙设备、4:服务器、5:引导屏、
        // 6:交换机、7:道闸、8:泊位感知设备、9:广播设备、10:虚拟卡口设备 、11 报警按钮设备
        let imgIcon = ''
        switch(item.equipmentType) {
          case '1': imgIcon = this.monitorIcon; break; // 1:视频监控设备
          case '5': imgIcon = this.brendIcon; break; // 5:引导屏
          case '7': imgIcon = this.fenceIcon; break; // 7:道闸 
        }
        const content = getAlarmMarkerContent(this.warnIcon, imgIcon)
        var marker = new AMap.Marker({
          position: new AMap.LngLat(item.longitude, item.latitude),
          offset: new AMap.Pixel(-15, -15),
          content: content
        });
        this.allMarker.push(marker)
      })
      this.map.add(this.allMarker);
    },
    // 绘制道路轨迹图
    dragMapRoadLine(roadLineList) {
      this.map.remove(this.polylineList);
      this.polylineList = [];
      roadLineList.forEach(item => {
        if(!Array.isArray(item.posxy)) return;
        const path = [];
        item.posxy.forEach(posxy => path.push(new AMap.LngLat(posxy.x, posxy.y)))
        const polyline = new AMap.Polyline({
          path: path,  
          strokeWeight: 5, // 线条宽度,默认为 1
          strokeColor: item.color || 'red', // 线条颜色
          lineJoin: 'round' // 折线拐点连接处样式
        });
        this.polylineList.push(polyline)
      })
      this.map.add(this.polylineList);
    },
    // 绘制停车场饱和度饼图
    dragMapParkingPie(parkingList) {
      this.map.remove(this.parkingSpaceMarker);
      this.parkingSpaceMarker = [];
      for(let i=0; i<parkingList.length; i++) {
        this.parkingSpaceMarker.push(
          new AMap.Marker({
            position: new AMap.LngLat(parkingList[i].longitude, parkingList[i].latitude),
            offset: new AMap.Pixel(-80, -80),
            content: `<div style='height: 160px; width: 160px; background: transparent;' id='echartBox${i}'></div>`
          })
        )
        parkingList[i].elementId = `echartBox${i}`;
      }
      this.map.add(this.parkingSpaceMarker);

      parkingList.forEach(item => {
        const dom = document.getElementById(item.elementId);
        const myChart = echarts.init(dom);
        const option = getPieOption(item);
        myChart.setOption(option, true);
      })
    },
  }
}
</script>

饼图的配置

echart.pie.config.js文件

export const getPieOption = dataRes => {
  const emptyNum = dataRes.emptyBerthNum || 0; // 空闲数量
  const totalNum = dataRes.berthNumTotal || 0; // 总数量
  return {
    background: 'transparent',
    animation: false, // 关闭动画
    title: [{
      text: '余位',
      x: 'center',
      top: '50%',
      textStyle: {
        color: '#fff',
        fontSize: 14,
      }
    }, {
      text: emptyNum,
      x: 'center',
      top: '36%',
      textStyle: {
        fontSize: 26,
        color: '#fff',
        fontFamily: 'myFont',
        foontWeight: 700,
      },
    }],
    polar: {
      radius: ['44%', '50%'],
      center: ['50%', '50%'],
    },
    angleAxis: {
      max: totalNum,
      show: false,
    },
    radiusAxis: {
      type: 'category',
      show: true,
      axisLabel: {
        show: false,
      },
      axisLine: {
        show: false,
      },
      axisTick: {
        show: false
      },
    },
    series: [
      {
        type: 'pie',
        radius: ['40%', '50%'],
        silent: true,
        clockwise: true,
        startAngle: 90,
        z: 0,
        zlevel: 0,
        label: {
          show: false
        },
        data: [
          {
            value: emptyNum,
            name: "",
            itemStyle: {
              normal: {
                color: { // 完成的圆环的颜色
                  colorStops: [{
                    offset: 0,
                    color: '#FF4824' // 0% 处的颜色
                  }, {
                    offset: 0.5,
                    color: '#FADA16' // 50% 处的颜色
                  }, {
                    offset: 1,
                    color: '#B8E986' // 100% 处的颜色
                  }]
                },
              }
            }
          },
          {
            value: totalNum - emptyNum,
            name: "",
            label: {
              normal: {
                show: false
              }
            },
            itemStyle: {
              normal: {
                color: "rgba(255,255,255,0.27)"
              }
            }
          }
        ]
      },
      {
        type: 'gauge',
        radius: '35%',
        startAngle: '0',
        endAngle: '-359.99',
        splitNumber: '50',
        center: ['50%', '50%'],
        pointer: {
          show: false
        },
        title: {
          show: false
        },
        detail: {
          show: false
        },
        data: [{
          value: totalNum,
          name: ''
        }],
        axisLine: {
          lineStyle: {
            width: 20,
            opacity: 0
          }
        },
        axisTick: {
          show: false
        },
        splitLine: {
          show: true,
          length: 2,
          lineStyle: {
            color: '#fff',
            width: 1,
            type: 'solid',
          },
        },
        axisLabel: {
          show: false
        }
      },
      {
        name: '',
        type: 'pie',
        startAngle: 90,
        radius: ['50%', '57%'],
        hoverAnimation: false,
        center: ['50%', '50%'],
        itemStyle: {
          normal: {
            labelLine: {
              show: false
            },
            color: 'rgba(0, 0, 0, 0.27)',
          }
        },
        data: [{ value: totalNum }]
      },
      {
        name: '',
        type: 'pie',
        startAngle: 90,
        radius: ['57%', '59%'],
        hoverAnimation: false,
        center: ['50%', '50%'],
        itemStyle: {
          normal: {
            labelLine: {
              show: false
            },
            color: 'rgba(255, 255, 255, 0.31)',
          }
        },
        data: [{ value: totalNum }]
      },
    ]
  };
}

mapUtil.js

// 获取设备报警点位样式marker的content
export const getAlarmMarkerContent = (firstIcon, secendIcon) => {
  const content = `<div style="display: flex; align-items: center;">
    <img style="width: 25px; height:25px; margin-right: 5px;" src="${firstIcon}" />
    <div style="display: flex; align-items: center; background: rgba(0,0,0,0.67); border: 1px solid #ff4133; border-radius: 7px; box-shadow: 0px 0px 30px 0px rgba(0,0,0,0.20); padding: 2px 10px;">
      <img style="width: 25px; height:25px;" src="${secendIcon}" />
      <span style="font-size: 16px; color: #FF4133; width: 70px; margin-left: 5px;">设备故障</span>
    </div>
  </div>`
  return content;
}

地图效果