vue 实现 高德地图绘制并编辑区域功能

业务需要参考很多文章最后实现的功能 仍有缺陷 先展示
1.根据所在区域自动绘制范围
2.切换区域自动切换所画范围
3.回显其他人绘制的范围(业务需求绘制范围不可以重复)
4.绘制的区域可编辑 可删除
(删除功能仍有瑕疵 实现了部分删除功能 都是比较傻瓜试的操作 不喜勿喷)
在这里插入图片描述
编辑的时候白色点是可以取消掉的
在这里插入图片描述
高德地图开放平台https://lbs.amap.com/api/javascript-api-v2/summary/
要在控制台见一个key才可以运行高德地图插件 要选web服务的才行
在这里插入图片描述
下载插件

npm i @amap/amap-jsapi-loader --save

上代码
我的是弹窗的形式 主页面

<el-dialog
        title="绘制区域"
        width="80%"
        top="8vh"
        :visible.sync="dialogVisible"
        :before-close="hideDialog"
        :close-on-click-modal="false"
        class="dialogPa"
      >
        <div class="dialog-body" >
        //centerDrop: [123.455551,41.798729]地图中心点 allCoordinates其他人绘制的区域数据 address当前区域文字areaCode当前区域code isUpdateBtn是否显示编辑按钮 updateId可修改数据的id  isaddBtn是否是新增 mapIdDiv地图画布id
          <seeAddIndex v-if="dialogVisible" :center="centerDrop"  :allCoordinates="alllist"  :address="dataForm.address" :areaCode="dataForm.areaCode"  :isUpdateBtn="true"  @mapList="mapList"  :updateId="updateId"  :isaddBtn="isaddBtnMap"  :mapIdDiv="'mapIdDiv'+updateId"></seeAddIndex>
        </div>
      </el-dialog>
     

js部分

import seeAddIndex from "@/components/AMapLoader/seeAddIndex.vue"; //自定义高德地图绘制区域
 components: {seeAddIndex },
 //组件点击确定或取消 istype确定/取消  date点集合数据 mapname切换后的区域数据
  mapList(istype,date,mapname) {
      var that = this;
      if(istype){// 确定
        that.newlatlng = date;
      console.log("---", date);
      //...调用保存接口
      }else{//取消
        that.newlatlng = [];
        that.dialogVisible = false;
      }
    }

组件代码

<template>
  <div class="container">
    <div class="input-card mapNewCss">
      <div class="input-item">
        <div class="input-item-prepend">
          <span class="input-item-text">省市区:</span>
        </div>
        <el-select
          style="width: 70%;"
          v-model="province"
          @change="searchNew('province')"
        >
          <el-option
            v-for="item in provinceList"
            :key="item.adcode"
            :label="item.name"
            :value="item.adcode"
            @click.native="getName('province',item)"
          >
          </el-option>
        </el-select>
      </div>
      <div class="input-item">
        <div class="input-item-prepend">
          <span class="input-item-text">地级市:</span>
        </div>
        <el-select
          style="width: 70%;"
          v-model="city"
          @change="searchNew('city')"
        >
          <el-option
            v-for="item in cityList"
            :key="item.adcode"
            :label="item.name"
            :value="item.adcode"
            @click.native="getName('city',item)"
          >
          </el-option>
        </el-select>
      </div>
      <div class="input-item">
        <div class="input-item-prepend">
          <span class="input-item-text">区县:</span>
        </div>
        <el-select
          style="width: 70%;"
          v-model="district2"
          @change="searchNew('district')"
        >
          <el-option
            v-for="item in districtList"
            :key="item.adcode"
            :label="item.name"
            :value="item.adcode"
            @click.native="getName('district2',item)"
          >
          </el-option>
        </el-select>
      </div>
    </div>
    <div :id="mapIdDiv" style="width: 100%;height: 65vh;"></div>
   //两个编辑方法 一个是新增的编辑  一个是修改的编辑 获取到的绘制区域图层不一样 数据格式对不上就不会显示 所以就很笨拙的实现基本功能  希望有大神可以优化
    <div class="input-card">
      <el-button v-if="isaddBtnOne"
      class="filter-item"
      type="primary"
      @click="upPolygon"
      :disabled="isDisabled"
      >编辑</el-button
    >
      <el-button
        v-if="!isaddBtnOne"
        class="filter-item"
        type="primary"
        @click="getPoly"
        :disabled="isDisabled"
        >编辑</el-button
      >
//删除功能部分数据实现了
      <el-button
        v-if="isClear"
        class="filter-item"
        type="primary"
        @click="clearPolygon"
        :disabled="isDisabled"
        >删除</el-button
      >
      <div style="float: right;" v-if="isUpdateBtn">
        <el-button @click="hideDialog">取 消</el-button>
        <el-button type="primary" @click="getOk"  :disabled="isDisabled">确 定</el-button>
      </div>
    </div>
    
  </div>
</template>

<script>
import AMapLoader from "@amap/amap-jsapi-loader";

export default {
  name: "AreaMapSee",
  props: {
    //地图id
    mapIdDiv: {
      type: '',
      default: 'container'
    },
    //中心点
    center: {
      type: '',
      default: null
    },
      //所有数据
    allCoordinates:{
    type: '',
    default: null
    },
     //回显区域数据
    //  coordinates: {
    //   type: Object / Array,
    //   default: []
    // },
    address:{
      type: "",
      default: null
    },
    areaCode:{
      type: "",
      default: null
    },
        //编辑按钮
    isUpdateBtn: {
      type: Boolean,
      default: false
    },
    //待修改的id
    updateId: {
      type: '',
      default: null
    },
     // 新增按钮
     isaddBtn: {
      type: Boolean,
      default: false
    },
  },
  data() {
    return {
      map: null,
      polyEditor: null,
      polyEditorNew: null,
      addNumber:0,
      updatePolygon:null,
      updateCoordinates:[],
      isaddBtnOne: false,
      isDisabled: false,
      district: null,
      polygonArea: [],
      serviceList: [],
      province: "",
      provinceName:'',
      provinceList: [],
      city: "",
      cityName: "",
      cityList: [],
      district2: "",
      district2Name: "",
      districtList: [],
      street: "",
      streetList: [],
      addOne:false,
      mapSeeA:0,//第一次进入页面
      mapAreaCode:'',
      mapAreaName:'',
      newMap:false,
      isClear:true,
    };
  },
  mounted() {
    console.log("mounted",this.address,this.areaCode);
    //对当时接口返回参数的处理
    if (this.address) {
        let address = this.address.split(",");
        this.province=address[0]
        this.provinceName=address[0]
        this.city=address[1]
        this.cityName=address[1]
        this.district2=address[2]
        this.district2Name=address[2]
        this.mapAreaCode=this.areaCode
      }
    this.isaddBtnOne = this.isaddBtn;
    this.echart();
  },
  methods: {
    echart() {
      let that=this
      AMapLoader.reset()
      AMapLoader.load({
        key: "", // 申请好的Web端开发者Key,首次调用 load 时必填
        version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
        plugins: [
          "AMap.ToolBar",
          "AMap.Driving",
          "AMap.PolygonEditor",
          "AMap.PlaceSearch",
          "AMap.ControlBar",
          "AMap.Scale",
          "AMap.Geocoder",
          "AMap.DistrictSearch"//区域查询

        ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
      })
        .then((AMap) => {
          that.map = new AMap.Map(that.mapIdDiv, {
            resizeEnable: true,
            // viewMode: '3D',
            pitch: 45,
            zoom: 13, // 初始化地图级别
            center:that.center, // 初始化地图中心点位置
          });
          const ControlBar = new AMap.ControlBar({
            position: { top: '0', right: '10px' }
          })
          that.map.addControl(ControlBar);
    //       //数据格式化;
          let allList=that.allCoordinates//列表所有数据
          let data=[]
          for (var i = 0; i < allList.length; i++) {
              if (allList[i].serviceRange) {
                let data2 = JSON.parse(allList[i].serviceRange);
                if(data2.coordinates[0]){
                  let list=data2.coordinates[0]
                  if(allList[i].id!=that.updateId){
                    console.log('allList[i].id',allList[i].id,that.updateId)
                    data.push({list:list,name:allList[i].name,id:allList[i].id})
                    // data.push(list)
                    }else{
                    //可编辑数据
                      console.log('that.updateId',that.updateId)
                      that.updateCoordinates={list:list,name:allList[i].name,id:allList[i].id}
                    }
                 
                  }
                } 
              }
          console.log('data',data)
          let lengthaaa=data.length
          that.polygonList=[]
          for (var j = 0; j < data.length; j++) {
              var points 
              var name
              //循环遍历添加多边形;
                points = data[j].list;
                name=data[j].name
                let polygon1 = new AMap.Polygon({
                  path: points,
                  strokeColor: "#FF0000",
                  strokeWeight: 1,
                  strokeOpacity: 0.2,
                  fillOpacity: 0.24,
                  fillColor: "#FF0000",
                  zIndex: 20,
                  
                });
                that.polygonList.push(polygon1);
                that.map.add([polygon1]);

                let marker = new AMap.Marker({
                position: points[0],
                offset: new AMap.Pixel(0, 0),
                direction:'right',
              })
                marker.setLabel({
                position: points[0],
                icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
                direction:'right',
                offset: new AMap.Pixel(0, 0),  //设置文本标注偏移量
                content: "<div style='background-color: #D9EAFF;color:#333;padding:3px;'>"+name+"</div>", //设置文本标注内容
              });
              that.map.add(marker)     
          }
          //可编辑数据
          that.updatePolygon = new AMap.Polygon({
            path: that.updateCoordinates.list,
            strokeColor: "#0075FF",
            strokeWeight: 1,
            strokeOpacity: 0.2,
            fillOpacity: 0.24,
            fillColor: "#0075FF",
            zIndex: 20,
            extData:{
              id:that.updateCoordinates.id
            }
          });
          that.polygonList.push(that.updatePolygon);
          that.map.add([that.updatePolygon]);

          that.map.setFitView();
          that.polyEditor = new AMap.PolygonEditor(that.map,that.updatePolygon);//编辑数据
              //行政区划查询
              var opts = {
            subdistrict: 1, //返回下一级行政区
            showbiz: false //最后一级返回街道信息
          };
          that.district = new AMap.DistrictSearch(opts);
          that.district.search("中国", function(status, result) {
            if (status == "complete") {
              that.getData(result.districtList[0], "province");
              that.searchNew("province","no",1); //默认城市
            }
          });
        })
        .catch((e) => {
          console.log("---",e);
        });

    },
      //删除当前编辑区域
      clearPolygon(){
      let that=this
      that.polyEditor.close()
      if(that.isaddBtnOne){//新增
        let polygonDiv = that.map.getAllOverlays("polygon"); //获取所有的polygon
        let number=polygonDiv.length
        console.log('polygonDiv',polygonDiv)
        that.map.remove(polygonDiv[number-1])	// 移除覆盖物

      }else{//编辑
        let overlaysList=that.polygonList
        for(var i = 0; i < overlaysList.length; i++){
            // 获取存在每个 extData 中的 id
            var id = overlaysList[i].getExtData().id;
            console.log('that.updateId',that.updateId)
                if(id === that.updateCoordinates.id){//可编辑的id区域
                that.map.remove(overlaysList[i])	// 移除覆盖物
                  console.log('id',id)
                  break;
                }
            }
      } 
      that.isClear=false
      that.isDisabled=true 
    },
    getPoly() {
      this.polyEditor.open();
    },
    showInfoClick(e) {
      console.log("**", e.lnglat.getLng() + "," + e.lnglat.getLat());
      this.isDisabled = false;
    },
    getOk(){
      let overlaysList = this.map.getAllOverlays('polygon'); //获取所有的polygon
      let pathList=[]
      for(let i=0;i<overlaysList.length;i++){ 
      let path=overlaysList[i]._opts.path
      if(path&&path.length>0){
          pathList.push(path)
        }
      };
      let number=pathList.length
      console.log('==all',pathList)
      var mapname={
        provinceName:this.provinceName,
        cityName:this.cityName,
        district2Name:this.district2Name,
        mapAreaCode:this.mapAreaCode

      }
      console.log("mapname",mapname)
      if(this.newMap||this.isaddBtn){//新增
        console.log('==2',[pathList[number-1]])
        this.$emit("mapList",true,[pathList[number-1]],mapname);
      }else{//编辑
        console.log('==1',[pathList[number-2]])
        this.$emit("mapList",true,[pathList[number-2]],mapname);
      }
       
      
    },
    hideDialog() {
      this.$emit("mapList", false);
    },
    getData(data, level,numbera) {
      var that = this;
      var bounds = data.boundaries;
      console.log("bounds", bounds);
      if (bounds) {
        for (var i = 0, l = bounds.length; i < l; i++) {
          var polygon = new AMap.Polygon({
            map: that.map,
            strokeWeight: 1,
            strokeColor: "#0091ea",
            fillColor: "#80d8ff",
            fillOpacity: 0.2,
            path: bounds[i]
          });
          that.polygonArea.push(polygon);
        }
        that.map.setFitView(); //地图自适应
      }
      console.log(numbera,'that.polygonArea',that.polygonArea)
      let newList=that.polygonArea
      let polygonAreaList=[]
      var subList = data.districtList;
      if (subList) {
        if (level === "province") {
          that.provinceList = subList;
        } else if (level === "city") {
          that.cityList = subList;
        } else if (level === "district") {
          that.districtList = subList;
          console.log('that.districtList',that.districtList)
        } else if (level === "street") {
          for (var i = 0, l = subList.length; i < l; i++) {
            subList[i].adcodeKey = i + "key" + subList[i].adcode;
          }
          that.streetList = subList;
          console.log('that.streetList')
          that.isDisabled=false 
          console.log('that.isDisabled',that.isDisabled)
        }
        console.log("curList", level, subList);
        if(that.mapSeeA==0){
          that.setCenter(that.center);
          that.mapSeeA++
        }
        
      }
      if(numbera==1){
        that.searchNew("city","no",2); //默认城市
      }else if(numbera==2){
        that.district2=that.areaCode
        that.searchNew("district","no",3); //默认城市
      }
    },
    getName(type,data){
      var that=this
      if(type=='province'){
        that.provinceName=data.name
      }
      if(type=='city'){
        that.cityName=data.name
      }
      if(type=='district2'){
        that.isaddBtnOne=true
        that.newMap=true
        that.district2Name=data.name
      }
    },
    //选择type no不清空加载默认数据
    searchNew(type,clearType,numbera) {
      var that = this;
      that.polyEditor.close();
      that.$forceUpdate();
      //清除地图上所有覆盖物
      for (var i = 0, l = that.polygonArea.length; i < l; i++) {
        that.polygonArea[i].setMap(null);
      }
      var adcode = "";
      var typeNext = "";
      if (type == "province") {
        adcode = that.province;
        typeNext = "city";
        //清空下一级别的下拉列表
        if(clearType!='no'){
          that.city = "";
          that.cityList = [];
          that.district2 = "";
          that.districtList = [];
        }
      }
      if (type == "city") {
        adcode = that.city;
        typeNext = "district";
        //清空下一级别的下拉列表
        if(clearType!='no'){
          that.district2 = "";
          that.districtList = [];
        }
      }
      if (type == "district") {
        adcode = that.district2;
        typeNext = "street";
      }
      that.district.setLevel(type); //行政区级别
      that.district.setExtensions("all");
      //行政区查询
      //按照adcode进行查询可以保证数据返回的唯一性
      this.mapAreaCode=adcode
      console.log('this.mapAreaCode',this.mapAreaCode)
      that.district.search(adcode, function(status, result) {
        if (status === "complete") {
          that.getData(result.districtList[0], typeNext,numbera);
        }
      });
    },
    setCenter(obj) {
      this.map.setCenter(obj);
      console.log('obj',obj)
    },
    upPolygon(){
      let that=this
      let overlaysList = this.map.getAllOverlays('polygon'); //获取所有的polygon
      let pathList=[]
      for(let i=0;i<overlaysList.length;i++){ 
      let path=overlaysList[i]._opts.path
      if(path&&path.length>0){
          pathList.push(path)
        }
      };
      let number=pathList.length
      console.log('==all',pathList)
      console.log('==ADD',[pathList[number-1]])
      var pathLista=[pathList[number-1]]
       //可编辑数据
       that.updatePolygon = new AMap.Polygon({
            path: pathLista,
            strokeColor: "#0075FF",
            strokeWeight: 1,
            strokeOpacity: 0.2,
            fillOpacity: 0.24,
            fillColor: "#0075FF",
            zIndex: 20,
            extData:{
              id:''
            }
          });
          that.polygonList.push(that.updatePolygon);
          that.map.add([that.updatePolygon]);
          that.map.setFitView();
          that.polyEditor = new AMap.PolygonEditor(that.map,that.updatePolygon);//编辑数据
          that.polyEditor.open();
    },
    //编辑区域数据
    upPolygon2(){
      var that=this
      let polygonAreaList=[]
      let newList=that.polygonArea
      console.log('this.polygonArea',that.polygonArea)
      for (var j = 0; j < newList.length; j++){
        //可编辑数据
        let path=newList[j]._opts.path
      let updatePolygon = new AMap.Polygon({
            path:path,
            strokeColor: "#0075FF",
            strokeWeight: 1,
            strokeOpacity: 0.2,
            fillOpacity: 0.24,
            fillColor: "#0075FF",
            zIndex: 20,
          });
      polygonAreaList.push(updatePolygon)
       that.map.add([updatePolygon]);
      }
     
      console.log('polygonAreaList',polygonAreaList)
      //可编辑数据
      // that.updatePolygon = new AMap.Polygon({
      //       path: that.updateCoordinates.list,
      //       strokeColor: "#0075FF",
      //       strokeWeight: 1,
      //       strokeOpacity: 0.2,
      //       fillOpacity: 0.24,
      //       fillColor: "#0075FF",
      //       zIndex: 20,
      //       extData:{
      //         id:that.updateCoordinates.id
      //       }
      //     });
          // that.polygonList.push(that.updatePolygon);
          // that.map.add([that.updatePolygon]);
      that.polyEditorNew = new AMap.PolygonEditor(that.map,polygonAreaList);//编辑数据
      that.polyEditorNew.open();
      // that.polyEditorNew.close();
      // this.polyEditorNew.setTarget();
      // this.polyEditorNew.open();
      }
    
  },
};
</script>

<style lang="scss" scoped>
.input-card{
  margin-top: 10px;
}
/deep/ .amap-marker-label{
  border: 1px solid #D9EAFF;
  padding: 0;
  border-radius: 6px;
}
.cityListCss {
  display: inline-block;
  min-width: 50px;
  color: #333;
  cursor: pointer;
  padding: 4px 10px;
}
.activeCss {
  color: #1d6bff;
}
/* 行政查询样式 */
.mapNewCss{
  margin-top: -40px !important;
  margin-bottom: 10px;
}
.mapNewCss .input-item {
  display: inline-block;
  width: 30%;
  text-align: right;
}
.mapNewCss .input-item .input-item-text{
  display: inline-block;
  text-align: right;
}
.mapNewCss .input-item .input-item-prepend {
  display: inline-block;
  width: 20%;
}
</style>


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值