美文网首页
vue+vant高德地图点聚合和点标记切换功能

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

作者: 巴比卜 | 来源:发表于2021-12-08 20:45 被阅读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>
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/puztfrtx.html