美文网首页
使用vue-amap实现多边形绘制和编辑

使用vue-amap实现多边形绘制和编辑

作者: 子夜照弦歌 | 来源:发表于2020-07-29 17:31 被阅读0次

    原创文章,转载请注明出处
    官方文档
    借鉴文章

    <template>
      <div class="content">
        <div class="amap-wrapper">
          <!-- <el-amap-search-box
            class="search-box"
            :search-option="searchOption"
            :on-search-result="onSearchResult"
          ></el-amap-search-box>-->
          <el-amap
            class="amap-box"
            ref="map"
            :zoom="zoom"
            :center="center"
            :events="events"
            :mapStyle="mapStyle"
          >
            <el-amap-polygon
              v-for="(polygon, index) in polygons"
              :key="index"
              :vid="index"
              :ref="`polygon_${index}`"
              :path="polygon.path"
              editable="true"
              strokeStyle="dashed"
              strokeColor="#FF0000"
              strokeWeight="2"
              strokeOpacity="0.8"
              fillOpacity="0.3"
              fillColor="#1791fc"
              :events="polygon.events"
            ></el-amap-polygon>
          </el-amap>
        </div>
    
        <div style="width: 360px;position: absolute; top: 100px;left:40px">
          <el-card class="box-card">
            <el-table :data="polygons" border size="mini" style="width: 100%">
              <el-table-column align="center" label="名称">
                <template>
                  <div>{{name}}</div>
                </template>
              </el-table-column>
              <el-table-column align="center" label="操作" width="100">
                <template slot-scope="scope">
                  <el-button
                    @click="edit(scope.$index)"
                    v-if="scope.row.path.length>0"
                    type="text"
                    size="small"
                  >编辑</el-button>
                  <el-button @click="draw(scope.$index)" v-else type="text" size="small">绘制</el-button>
                  <el-button @click="del(scope.$index)" type="text" size="small">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-card>
        </div>
        <div class="Y-text-align-right Y-avg-1" style="margin-top:10px">
          <el-button type="primary" @click="addArea">添加行政区域</el-button>
          <!-- <el-button type="primary" v-if="isEdit" @click="end">结束编辑</el-button>
          <el-button type="primary" v-if="isDraw" @click="endDraw">结束绘制</el-button>-->
          <el-button type="primary" @click="sure">确定</el-button>
        </div>
      </div>
    </template>
    <script>
    export default {
      props: {
        path: {
          type: Array,
          default: function () {
            return [];
          },
        },
        name: {
          type: String,
          default: function () {
            return "";
          },
        },
      },
      data() {
        let _this = this;
        return {
          center: [117.120098, 36.6512], //地图中心点坐标 济南市
          zoom: 12, //初始化地图显示层级
          mapStyle: "amap://styles/8b6be8ec497009e17a708205348b899a", //设置地图样式
          // searchOption: {
          //   city: "济南",
          //   citylimit: true,
          // },
          isEdit: false,
          pIdx: 0,
          zoom: 14,
          events: {
            init: (o) => {},
            click: (e) => {
              let { lng, lat } = e.lnglat;
              if (_this.isDraw) {
                let arr = [e.lnglat.lng, e.lnglat.lat];
                _this.polygons[_this.pIdx].path.push(arr);
              }
            }
          },
          polygons: [
            // {
            //   path: [],
            //   events: {
            //     click(e) {
            //       _this.clickEdit(_this, this);
            //     },
            //   },
            // },
          ],
          polygonEditor: null,
          isDraw: false,
        };
      },
      watch: {
      },
      mounted() {
        let _this = this;
        setTimeout(function () {
          this.polygons = [];
          let path = _this.path;
          if (path.length > 0) {
            for (let i = 0; i < path.length; i++) {
              const element = path[i];
              let arr = [];
              if (element.aroundLocations.length > 0) {
                for (let j = 0; j < element.aroundLocations.length; j++) {
                  const item = element.aroundLocations[j];
                  arr.push([item.lng, item.lat]);
                }
              }
              element.path = arr;
              element.events = {
                click(e) {
                  _this.clickEdit(_this, this);
                }
              };
              delete element.aroundLocations;
            }
            _this.polygons = path;
          }
        }, 500);
      },
      methods: {
        // onSearchResult(pois) {
        //   let latSum = 0;
        //   let lngSum = 0;
        //   if (pois.length > 0) {
        //     let center = pois[0];
        //     this.lng = center.lng;
        //     this.lat = center.lat;
        //     this.address = center.name;
        //     this.center = [center.lng, center.lat];
        //     this.markers = [[center.lng, center.lat]];
        //   }
        // },
        // 添加多边形区域
        addArea() {
          let _this = this
          if (this.isDraw) {
            this.endDraw();
          }
          if (this.isEdit) {
            this.end();
          }
          let obj = {
            path: [],
            events: {
              click(e) {
                _this.clickEdit(_this, this);
              },
            },
          };
          this.polygons.push(obj);
          if (this.polygons.length > 0) {
            this.draw(this.polygons.length - 1);
          }
        },
    
        // 绘制多边形
        draw(idx) {
          if (this.isEdit) {
            this.end();
          }
          this.pIdx = idx;
          this.isDraw = true;
        },
        // 删除多边形区域
        del(idx) {
          this.polygons.splice(idx, 1);
        },
    
        clickEdit(vm, polygon) {
          if (vm.isDraw) {
            vm.endDraw();
          }
          if (vm.polygonEditor) {
            vm.end();
          }
          vm.isEdit = true;
          let map = vm.$refs.map.$$getInstance();
          //构造折线编辑对象,并开启折线的编辑状态
          let polygonEditor = new AMap.PolyEditor(map, polygon);
          vm.polygonEditor = polygonEditor;
          polygonEditor.open();
          //关闭多边形编辑polygonEditor.close()触发该方法;
          polygonEditor.on("end", function (event) {});
        },
    
        // 编辑多边形区域
        edit(idx) {
          if (this.isDraw) {
            this.endDraw();
          }
          if (this.polygonEditor) {
            this.end();
          }
          this.isEdit = true;
          let pStr = "polygon_" + idx;
          let vm = this;
          let map = vm.$refs.map.$$getInstance();
          let polygon = vm.$refs["polygon_" + idx][0].$$getInstance();
          // 缩放地图到合适的视野级别
          // map.setFitView([polygon]);
          //构造折线编辑对象,并开启折线的编辑状态
          let polygonEditor = new AMap.PolyEditor(map, polygon);
          vm.polygonEditor = polygonEditor;
          polygonEditor.open();
          //关闭多边形编辑polygonEditor.close()触发该方法;
          polygonEditor.on("end", function (event) {
            // event.target 即为编辑后的多边形对象,event.target.getPath()得到编辑完成后的点数组
            let pointArr = event.target.getPath();
            vm.polygons[idx].path = pointArr;
          });
        },
        // 结束编辑
        end() {
          this.polygonEditor.close();
          this.isEdit = false;
        },
        // 结束绘制
        endDraw() {
          this.isDraw = false;
        },
        // 确定 传数据给父组件
        sure() {
          if (this.isDraw) {
            this.endDraw();
          }
          if (this.isEdit) {
            this.end();
          }
          let polygons = this.polygons;
          this.$emit("update", polygons);
        },
      },
    };
    </script>
    <style scoped lang="scss">
    .search-box {
      position: absolute;
      top: 25px;
      left: 20px;
    }
    .amap-wrapper {
      width: 100%;
      height: 500px;
      position: relative;
    }
    </style>
    
    • 父组件调用
    <map-area @update="update" :name="areaName" :path="pathArea"></map-area>
     update(arr) {
          let _this = this;
          let around = [];
          for (let i = 0; i < arr.length; i++) {
            let o = {};
            const element = arr[i];
            element.aroundLocations = element.path;
    
            let aroundLocations = [];
            for (let j = 0; j < element.path.length; j++) {
              const item = element.path[j];
              let obj = {};
              if (item instanceof Array) {
                obj = {
                  lng: item[0],
                  lat: item[1],
                };
              } else {
                obj = {
                  lng: item.lng,
                  lat: item.lat,
                };
              }
    
              aroundLocations.push(obj);
            }
            o.aroundLocations = aroundLocations;
    
            around.push(o);
          }
          if (around.length > 0) {
            _this
              .$confirm("是否修改?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
              })
              .then(() => {
                let data = {
                  groupId: _this.groupId,
                  around: around,
                };
                addAroundListFun(data).then((res) => {
                  _this.$message.success("添加成功");
                  _this.dialogVisible = false;
                });
              })
              .catch(() => {
                _this.$message.success("已取消");
              });
          } else {
            this.$message.error("未划分区域");
            return
          }
        },
    

    最后附上效果图:


    效果图

    相关文章

      网友评论

          本文标题:使用vue-amap实现多边形绘制和编辑

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