vue2 集成高德地图实现多边形选择 -进阶版

208 阅读1分钟

相比于前一版,增加了多个矢量图选择的功能,并且初始化的时候按照所传的参数就能达到想要的效果

效果

image.png

baseMap.vue

<template>
    <div>
      <div class="container" id ="container"></div>
      <div class="input-card" style="width: 100%" v-if="isEdit">
        <a-button class="btn1" type="primary" @click="createPolygon()" style="margin-bottom: 5px">新建</a-button>
        <a-button class="btn2" type="primary" @click="openPoly()" style="margin-bottom: 5px">开始编辑</a-button>
        <a-button class="btn3" type="primary" @click="closePoly()" style="margin-bottom: 5px">结束编辑</a-button>
        <a-button class="btn4" type="primary"  @click="clearPoly()">清空</a-button>
      </div>
    </div>
  </template>
  <script>  
  export default {
    name: 'baseMap',
    props: {
      name: {
        type: String,
        default: function() {
          return ''
        }
      },
      isEdit: {
        type: Boolean,
        default: function() {
          return false
        }
      },
      areas: {
        type: Array,
        default: function() {
          return []
        }
      },
      center: {
        type: Array,
        default: function() {
          return [123.842305,42.286129]
        }
      },
      resultList: {
        type: Array
      }
    },
    data() {
      return { polyEditor: null, polygonPaths: [], map: null, polygons: [] }
    },
    watch: {},
    mounted() {
      this.init()
    },
    methods: {
      async init() {
        await this.initMap()
        this.initAreas()
        if (this.isEdit) {
          console.log("this.isEdit",this.isEdit);
          this.initPoly()
        }
      },
      async initMap() {

        this.map = new window.AMap.Map('container', {
          center: this.center,
          zoom: 12,
          plugin: [   //一些工具插件
            {
              pName: 'MapType',  //地图类型
              defaultType: 0,
              events: {
                init(instance) {
                }
              }
            }
          ]
        })
  
        // 缩放地图到合适的视野级别
        this.map.setFitView()
      },
      initAreas() {
        //先循环外层的数据
        for (let j = 0;j < this.resultList.length; j++ ){
          //这是传入的三个字段分别的坐标数组,编码和映射到地图的名称
          let situation = this.resultList[j].situation
          let id = this.resultList[j].id
          let name = this.resultList[j].name
          let path = []
          let centerPoint = this.getPointsCenter(situation)
          for (let i = 0; i < situation.length; i++) {
            let area = situation[i]
            path.push([area.lng, area.lat])
            if (path.length <= 0) {
              continue
            }
            var polygon = new window.AMap.Polygon({
              path: path,
              fillOpacity: 0.05,
              fillColor: this.resultList[j].color,
              zIndex: 50,
              bubble: true,
              extData: {"id":id}
            })
            polygon.on("click", this.polygonClick);
            this.polygons.push(polygon)
          }
          /**if (this.polygons.length <= 0) {
            return
          }**/
          //地图上新增矢量多边形
          this.map.add(this.polygons)
          
          var text = new window.AMap.Text({
                position: new AMap.LngLat(centerPoint[0], centerPoint[1]),
                anchor: 'bottom-center',
                text: name,
                style: {'opacity':'0.8','font-size':'22px'},
            })
          this.map.add(text)
        }
      },
      initPoly() {
        if (this.polygons.length > 0) {
          this.polyEditor = new window.AMap.PolygonEditor(this.map, this.polygons[2])
        } else {
          this.polyEditor = new window.AMap.PolygonEditor(this.map)
        }
        // this.polyEditor.open()
        let _this = this
        //关闭多边形编辑polygonEditor.close()触发该方法;
        this.polyEditor.on('end', function(event) {
          // event.target 即为编辑后的多边形对象,event.target.getPath()得到编辑完成后的点数组
          
          let pointArr = event.target.getPath()
          this.polygonPaths = []
          for (let i = 0; i < pointArr.length; i++) {
            this.polygonPaths.push({ lat: pointArr[i].lat, lng: pointArr[i].lng })
          }
          _this.$emit('getPolygonMap', this.polygonPaths)
        })
      },
      openPoly() {
        this.polyEditor.open()
      },
      createPolygon(){
        this.polyEditor.close();
        this.polyEditor.setTarget();
        this.polyEditor.open();
      },
      closePoly() {
        this.polyEditor.close()
      },
      clearPoly() {
        this.$emit('clearPolygonMap')
        this.map.destroy()
        this.reset()
        this.init()
      },
      reset() {
        this.polyEditor = null
        this.polygonPaths = []
        this.map = null
        this.polygons = []
      },
      //矢量图点击事件
      polygonClick(param){
        console.log("param",param)
        console.log("this.polygons",this.polygons[2])
        this.polyEditor = new window.AMap.PolygonEditor(this.map,param.target)
      },
      //计算中间点
      getPointsCenter(points) {
        var point_num = points.length; //坐标点个数
        var X = 0, Y = 0, Z = 0;
        for(let i = 0; i< points.length; i++) {
          if (points[i] == '') {
            continue;
          }
          var lat, lng, x, y, z;
          lat = parseFloat(points[i].lat) * Math.PI / 180;
          lng = parseFloat(points[i].lng) * Math.PI / 180;
          x = Math.cos(lat) * Math.cos(lng);
          y = Math.cos(lat) * Math.sin(lng);
          z = Math.sin(lat);
          X += x;
          Y += y;
          Z += z;
        }
        X = X / point_num;
        Y = Y / point_num;
        Z = Z / point_num;
 
        var tmp_lng = Math.atan2(Y, X);
        var tmp_lat = Math.atan2(Z, Math.sqrt(X * X + Y * Y));
        var final_lng =  tmp_lng * 180 / Math.PI;
        var final_lat = tmp_lat * 180 / Math.PI;
        return [Math.round(final_lng*1000000)/1000000,Math.round(final_lat*1000000)/1000000];
      },
    }
  }
  </script>
  <style>
  .container {
    width: 100%;
    height: calc(100vh - 59px - 52px - 30px);
    position: absolute;
  }
  .btn1 {
    position: relative;
    width: 90px;
    height: 30px;
    top: 13px;
    left: 10px;
    cursor: pointer;
    z-index: 10;
  }
  .btn2 {
    position: relative;
    width: 90px;
    height: 30px;
    top: 13px;
    left: 20px;
    cursor: pointer;
    z-index: 10;
  }
  .btn3 {
    position: relative;
    width: 90px;
    height: 30px;
    top: 13px;
    left: 30px;
    cursor: pointer;
    z-index: 10;
  }
  .btn4 {
    position: relative;
    width: 90px;
    height: 30px;
    top: 13px;
    left: 40px;
    cursor: pointer;
    z-index: 10;
  }
  
  </style>

调用

<template>
  <div>
    <BaseMap ref="PolygonMap"
                    :isEdit="true"
                    :areas="areas"
                    :center="center"
                    :resultList = "resultList"
                    @getPolygonMap="getPolygonMap"
                    @clearPolygonMap="clearPolygonMap"
    ></BaseMap>
  </div>
</template>
<script>
import BaseMap from './baseMap'

export default {
  name: 'Test',
  components: { BaseMap },
  data() {
    return {
      center: [123.842305,42.286129],
      areas: [],
      resultList:[
          {
              id : "123123123123",
              name : "吉祥社区",
              color : "#F6CB60",
              situation : [{lat: 42.318377, lng: 123.566445},{lat: 42.269618, lng: 123.561982},{lat: 42.267331, lng: 123.660859},{lat: 42.3232, lng: 123.652963},{lat: 42.334114, lng: 123.609361}]
          },
          {
              id : "123412341234",
              name : "水润社区",
              color: "red",
              situation : [{lat: 42.30289, lng: 123.891572},{lat: 42.255389, lng: 123.887452},{lat: 42.274698, lng: 123.985642},{lat: 42.3199, lng: 123.980149},{lat: 42.337667, lng: 123.930367},{lat: 42.340459, lng: 123.893975},{lat: 42.345534, lng: 123.984965}]
          }
      ] 
    }
  },
  created() {
  },
  mounted() {
  },
  methods: {
    getPolygonMap(polygon) {
      //接收坐标集合
      console.log("polygon",polygon);
    },
    clearPolygonMap() {
      //清空坐标集合
      this.areas = []
    }
  }
}
</script>