vue+vant高德地图点聚合和点标记切换功能

2021-12-08  本文已影响0人  巴比卜
image image

1、首先引入高德地图api地址,key要去高德开发平台去申请。

<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=''&plugin=AMap.MarkerClusterer"></script>

申请步骤:点击控制台——点击我的应用创建一个应用就会得到key。


image image

2、在页面引入 import AMap from 'AMap' 如果不引用new AMap会报红

3、在vue.config文件中写入

configureWebpack: () => {
    const configNew = {}
    configNew.externals = {
      AMap: 'AMap' // 高德地图配置
    }
    return configNew
  },

4、我们要去实现我们的功能了

<template>
  <div>
    <div id="mapView" style="width:100%; height:calc(100vh - 306px);"> </div>
    <div class="tabs">
      <div class="tabs-view" v-for="item in tabsList" :key="item.name" @click="tabsClick(item.name)">
        <img :src="tabsActive==item.name?item.active:item.normal"/>
        <p :class="tabsActive==item.name?'tabs-p':''">{{item.title}}</p>
      </div>
    </div>
  </div>
</template>
<script>
import AMap from 'AMap'
export default {
  name: 'index',
  data () {
    return {
      // 中心点
      areaCenterPoint: [120.149147,30.292936],
      // 地图
      map: '',
      zoom:16,
      //地图-标点
      marker:[],
      //地图-聚合
      markers:[],
      cluster:{},
      selectedIds:[],
      //切换
      tabsActive:0,
      tabsList:[
        {
          'title': '任务',
          'normal': require('assets/img/index/icon-task.png'),
          'active': require('assets/img/index/icon-task-active.png'),
          'name': 0
        },
        {
          'title': '楼房',
          'normal': require('assets/img/index/icon-floor.png'),
          'active': require('assets/img/index/icon-floor-active.png'),
          'name': 1
        }
      ]
    }
  },
  async mounted() {
    try {
      this.$toast.loading({
        message: '加载中...',
        forbidClick: true,
        loadingType: 'spinner'
      })
      await this.initMap()
    } catch (e) {
      console.log(e)
    } finally {
      this.$toast.clear()
    }
  },
  methods: {
    /**
     * 任务/楼房切换
     * **/
    tabsClick(num){
      this.tabsActive = num
      if(num){
        //楼房
        //清除点聚合
        this.map.remove(this.markers)
        this.cluster.setMap(null)
        this.getMarker()
      }else{
        //任务  
        this.map.remove(this.marker)  //清除点标记
        this.getMarkerClusterer()
      }
    },
    /**
     * 初始化
     * **/
    async initMap() {
      this.map = new AMap.Map('mapView', {
        resizeEnable: true,
        center: this.areaCenterPoint,
        zoom: this.zoom
      })
      await this.getMarkerClusterer()
    },
    /**
       * 点标记
       * **/
      getMarker(){
        const list=[
            {
                "buildingName": "1幢",
                "centerPoint": "[120.150746,30.29166]",
            },
            {
                "buildingName": "2幢",
                "centerPoint": "[120.150295,30.291442]",
            },
            {
                "buildingName": "3幢",
                "centerPoint": "[120.150509,30.291863]",
            }
        ]
        list.map((v, i) => {
          if(v.centerPoint!=''){
            const lngLat=JSON.parse(v.centerPoint)
            const marker=new AMap.Marker({
              position: new AMap.LngLat(lngLat[0], lngLat[1]),
              offset: new AMap.Pixel(0, 0),
              content: `<div class="floor floor-mr"></div>`,
              extData: v,
              clickable:true
            })
            this.marker.push(marker)
            marker.on('click', this.resetMap)
          }
        });
        // 创建覆盖物群组,并将 marker 传给 OverlayGroup
        var overlayGroups = new AMap.OverlayGroup(this.marker)
        // 添加覆盖物群组
        this.map.add(overlayGroups)
        // 点击地图事件
        this.map.on("click", (ev) => {
            for (var i = 0; i < this.marker.length; i++) {
                this.marker[i].setContent('<div class="floor floor-mr"></div>')
            }
        })
      },
    /**
       * 点聚合
       * **/
      getMarkerClusterer() {
       const list=[
            {
                "incidentLevel": "3",
                "jwd": "120.146143,30.291471",
            },
            {
                "incidentLevel": "2",
                "jwd": "120.148035,30.291725",
            },
            {
                "incidentLevel": "2",
                "jwd": "120.145837,30.291309",
            }
        ]
        this.markers = []
        list.map((v, i) => {
          if(v.jwd.includes(',')){
            const lng=v.jwd.split(',')[0]
            const lat=v.jwd.split(',')[1]
            const marker=new AMap.Marker({
              position: new AMap.LngLat(lng, lat),
              offset: new AMap.Pixel(0, 0),
              content: v.incidentLevel=='3'?'<div class="container container-gj"></div>':v.incidentLevel=='2'?'<div class="container container-zj"></div>':'<div class="container container-dj"></div>',
              extData: v
            })
            this.markers.push(marker)
            marker.on('click', resetMap)
          }
        });
        // 地图放大最大点标记事件
        function resetMap(e){
          console.log(e.target.w.extData,4566)
        }
        this.selectedIds = new Set();
        this.cluster = new AMap.MarkerClusterer(this.map, [], {
          gridSize: 80,
          renderClusterMarker: this._renderClusterMarker,
          minClusterSize: 1,
          zoomOnClick: false
        });
        this.setMarkers(this.markers, this.selectedIds)
        // 点聚合点击事件
        this.cluster.on("click", (ev) => {
          this.selectedIds.clear();
          const taskList=[]
          ev.markers.forEach((v) => {
             taskList.push(v.getExtData())
            this.selectedIds.add(v.getExtData())
          })
          if(taskList.length>1){
            //多个聚合
            console.log(taskList)
          }else{
            //单个聚合
            console.log(taskList)
          }
          this.setMarkers(this.markers, this.selectedIds);
        });
        // 点击地图事件
        this.map.on("click", (ev) => {
          if (this.selectedIds.size > 0) {
            this.selectedIds.clear();
            this.setMarkers(this.markers, this.selectedIds);
            this.taskPopupVisible=false
          }      
        })
      },
      /**
       * 进行点聚合显示的点标记集合
       * **/
      setMarkers(markers, selectedIds) {
        this.cluster.setMarkers(markers);
      },
      _renderClusterMarker(context) {
        let isSelected = false;
        let clusterData=[]
        context.markers.forEach((v) => {
          clusterData.push(v.getExtData())
          if (this.selectedIds.has(v.getExtData())) {
            isSelected = true;
          }
        });
        context.marker.setOffset(new AMap.Pixel(-36 / 2, -39 / 2));
        if (isSelected) {
          if(clusterData.length>1){
            if (_.some(clusterData, ['incidentLevel', '3'])) {
              // 高级
              context.marker.setContent(
              `<div class="container container-gj-selected">${context.count}</div>`
              );
            } else if (_.some(clusterData, ['incidentLevel', '2'])) {

              // 中级
              context.marker.setContent(
                `<div class="container container-zj-selected">${context.count}</div>`
              );
            } else {
              // 低级
              context.marker.setContent(
                `<div class="container container-dj-selected">${context.count}</div>`
              );
            }
          }else{
            if (_.some(clusterData, ['incidentLevel', '3'])) {
              // 高级
              context.marker.setContent(`<div class="container container-gj"></div>`);
            } else if (_.some(clusterData, ['incidentLevel', '2'])) {
              // 中级
              context.marker.setContent(`<div class="container container-zj"></div>`);
            } else {
              // 低级
              context.marker.setContent(`<div class="container container-dj"></div>`);
            }
          }
        } else {
          if(clusterData.length>1){
            if (_.some(clusterData, ['incidentLevel', '3'])) {
              // 高级
              context.marker.setContent(`<div class="container container-gj-mr">${context.count}</div>`);
            } else if (_.some(clusterData, ['incidentLevel', '2'])) {
              // 中级
              context.marker.setContent(`<div class="container container-zj-mr">${context.count}</div>`);
            } else {
              // 低级
              context.marker.setContent(`<div class="container container-dj-mr">${context.count}</div>`);
            }
          }else{
            if (_.some(clusterData, ['incidentLevel', '3'])) {
              // 高级
              context.marker.setContent(`<div class="container container-gj"></div>`);
            } else if (_.some(clusterData, ['incidentLevel', '2'])) {
              // 中级
              context.marker.setContent(`<div class="container container-zj"></div>`);
            } else {
              // 低级
              context.marker.setContent(`<div class="container container-dj"></div>`);
            }
          }
        }
      }
  }
}
</script>

<style lang="scss" scoped>
::v-deep #mapView{
  .container {
    width: 36px;
    height: 39px;
    color: #fff;
    font-size: 12px;
    text-align: center;
    line-height: 32px;
    transition: all 0.5s;
    background-size: 100% 100%;
  }
  .container-gj{
    width: 28px;
    height: 31px;
    background-image: url('~assets/img/index/icon-gj.png');
  }
  .container-zj{
    width: 28px;
    height: 31px;
    background-image: url('~assets/img/index/icon-zj.png');
  }
  .container-dj{
    width: 28px;
    height: 31px;
    background-image: url('~assets/img/index/icon-dj.png');
  }
  .container-gj-mr{
    background-image: url('~assets/img/index/icon-gj-mr.png');
  }
  .container-zj-mr{
    background-image: url('~assets/img/index/icon-zj-mr.png');
  }
  .container-dj-mr{
    background-image: url('~assets/img/index/icon-dj-mr.png');
  }
  .container-gj-selected{
    background-image: url('~assets/img/index/icon-gj-xz.png');
  }
  .container-zj-selected{
    background-image: url('~assets/img/index/icon-zj-xz.png');
  }
  .container-dj-selected{
    background-image: url('~assets/img/index/icon-dj-xz.png');
  }
  .floor{
    width: 20px;
    height: 22px;
    background-size: 100% 100%;
  }
  .floor-mr{
    background-image: url('~assets/img/index/icon-house.png');
  }
  .floor-xz{
    background-image: url('~assets/img/index/icon-house-xz.png');
  }
}
.tabs{
    background: #fff;
    border-radius:nth($radius,1);
    position: absolute;
    top:12px;
    right: 10px;
    text-align: center;
    .tabs-view{
      padding: 7px 6px;
      position: relative;
      img{
        width: 15px;
        margin-bottom: 2px;
      }
      p{
        font-size: 9px;
      }
      .tabs-p{
        color: nth($color, 4);
      }
    }
    .tabs-view:first-child{
      &::after{
        position: absolute;
        content: '';
        width: 20px;
        height: 1px;
        background: #EBEDF0;
        bottom:0;
        left: 50%;
        margin-left: -10px;
      }
    }
  }
</style>
上一篇下一篇

猜你喜欢

热点阅读