头图

效果展示:
image.png
功能点:

  1. 搜索地点定位
  2. 绘制多边形(可删除、二次编辑形状)
  3. 定位到已绘制好的图形
  4. 一键清除所有图形
  5. 确认保存图形数据
    image.png

因为做的项目很多都会涉及到一些位置的记录或者项目范围的记录,所以经常需要做类似的功能,一般我都是使用百度地图的鼠标绘制工具,这里做个记录,也希望能帮到有需要的朋友们~

第一步肯定是引入百度地图,这一部分下次有时间专门写一篇。


项目需求:是点击按钮后进入到绘制项目范围的页面。
image.png

        <!-- 项目弹窗 -->
        <el-dialog
          :title="dialogType_Project === 'edit' ? '修改项目' : '新建项目'"
          :visible.sync="dialogVisible_Project"
          width="600px"
          :close-on-press-escape="false"
          :close-on-click-modal="false"
          :show-close="false"
          class="dialog-box"
         >
            <el-form
                ref="createForm_Project"
                :model="createForm_Project"
                label-width="120px"
            >
                <el-form-item label="项目名称" prop="projectName">
                    <el-input v-model="createForm_Project.projectName" clearable></el-input>
                </el-form-item>
                <el-form-item label="项目方案范围" prop="projectBoundary">
                    <el-button :type="overlays.length?'success':'primary'" @click="setMap()" size="small">
                      <!-- 选择项目方案范围 -->
                      <span>{{overlays.length?'查看项目方案范围':'绘制项目方案范围'}}</span>
                    </el-button>
                
                    <!-- <el-input v-model="createForm_Project.projectBoundary" clearable></el-input> -->
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="confirmCreate">提交</el-button>
                    <el-button @click="handleClose">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>

        <!-- 项目方案范围弹窗 -->     
        <el-dialog 
          :visible.sync="boundaryMapVisible" 
          :fullscreen="true" 
          width="600px" 
          :close-on-click-modal="false"
          class="dialog-box" 
          title="绘制项目方案范围"
        >
          <el-form ref="boundaryForm"  :model="boundaryForm">
            <el-row class="searchform">
              <el-col :span="5" id="r-result">
                <el-form-item>
                  <el-input v-model.trim="address_detail" placeholder="请输入地点描述关键字" clearable id="suggestId">
                    <el-button slot="append" icon="el-icon-search" @click="setPlace"></el-button>
                  </el-input>
                  <div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div>
                </el-form-item>
              </el-col>
              <el-col :span="7" :offset="1">
                <!-- <el-button @click="overlaysLength" type="primary">定位</el-button> -->
                <el-button @click="clearAll" type="danger">清除</el-button>
                <el-button type="success" @click="closeMap()">确定</el-button>
              </el-col>
            </el-row>
          </el-form>
          <div class="mymap-box">
            <div id="mymap" ></div> 
            <!-- 地图容器 -->
          </div>
        </el-dialog>

JS部分

export default {
    data(){
        return{
            //项目
            dialogType_Project:'add',
            dialogVisible_Project:false,
            createForm_Project:{
                projectName:'',
                projectBoundary:[],  //项目方案范围
            },
            //项目方案范围
            boundaryMapVisible:false,
            address_detail: null,
            serachMarker: null,
            editMarker: null,
            removeMarker: null,
            boundaryForm:{},
            mymap:null,
            overlays:[],
        }
    },
    methods:{
        // 项目编辑=》项目方案范围
        /**地图弹窗 */
        setMap() {
          this.address_detail = "";
          this.boundaryMapVisible = true;
          // 在这里使用$nextTick初始化地图插件即可
          if (this.mymap == null) {
            this.$nextTick(async () => {
              this.mapInit();
              this.showOverlays();
            });
          } else {
            // this.mymap.clearOverlays()
            this.showOverlays()
            if (this.serachMarker) {
              this.mymap.removeOverlay(this.serachMarker);
            }
            this.overlaysLength();
          }
        },
        /**地图初始化(加载百度地图)*/
        mapInit() {
          const that = this;
          that.mymap = this.$mapUtils.bdMapInnit("mymap");
          //实例化鼠标绘制工具
          let drawingManager = new BMapLib.DrawingManager(that.mymap, {
            isOpen: false, //是否开启绘制模式
            enableDrawingTool: true, //是否显示工具栏
            drawingMode: BMAP_DRAWING_POLYGON, //绘制模式  多边形
            drawingToolOptions: {
              anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
              offset: new BMap.Size(100, 5), //偏离值
              drawingModes: [
                BMAP_DRAWING_POLYGON //仅支持多边形
              ]
            },
            polygonOptions: this.$polygonStyleOptions //设置多边形的样式
          });
          //添加鼠标绘制工具监听事件,用于获取绘制结果
          drawingManager.addEventListener("overlaycomplete", function(e) {
            let points = e.overlay.getPath();
            //创建右键菜单
            let markerMenu = new BMap.ContextMenu();
            markerMenu.addItem(
              new BMap.MenuItem("删除", removeMarker.bind(e.overlay))
            );
            markerMenu.addItem(
              new BMap.MenuItem("编辑", editMarker.bind(e.overlay))
            );
            e.overlay.addContextMenu(markerMenu);
            e.overlay.disableMassClear();
            //将多边形保存到数组
            that.overlays.push(e.overlay);
          });
          //修复画多边形过程中如果误点‘手指’后出现的bug
          document.getElementsByClassName(
            "BMapLib_Drawing_panel"
          )[0].childNodes[0].onclick = function(e) {
            // that.overlays.map(v=>{
            //   v.disableMassClear()
            // })
            that.mymap.clearOverlays();
          };
          // 创建双击事件
          that.mymap.addEventListener("dblclick", function(e) {
            that.mymap.disableDoubleClickZoom();
            if (that.overlays.length != 0) {
              for (let j = 0; j < that.overlays.length; j++) {
                that.overlays[j].disableEditing();
              }
            }
          });
          //删除多边形
          let removeMarker = function(e, ee, marker) {
            that.mymap.removeOverlay(marker);
            for (let i = 0; i < that.overlays.length; i++) {
              if (that.overlays[i] == marker) {
                that.overlays.splice(i, 1);
              }
            }
          };
          that.removeMarker = removeMarker;
          //编辑多边形
          let editMarker = function(e, ee, marker) {
            marker.enableEditing();
          };
          that.editMarker = editMarker;
          //按照路名智能查询道路
          //建立一个自动完成的对象
          var ac = new BMap.Autocomplete({
            input: "suggestId",
            location: that.mymap
          });
        },
        // 查询关键字搜索
        setPlace() {
          const that = this;
          that.mymap.removeOverlay(that.serachMarker);
          //智能搜索
          var local = new BMap.LocalSearch(that.mymap, {
            onSearchComplete: () => {
              //获取第一个智能搜索的结果
              let userlocation = local.getResults().getPoi(0).point;
              that.mymap.centerAndZoom(userlocation, 18);
              //添加标注
              that.serachMarker = new BMap.Marker(userlocation);
              that.mymap.addOverlay(that.serachMarker);
            }
          });
          local.search(that.address_detail);
        },
        /**定位到绘制区域 */
        overlaysLength() {
          if (this.overlays.length > 0) {
            this.$mapUtils.polygonsLocationMap(this.overlays, this.mymap);
          } else {
            // this.$mapUtils.polygonsLocationMap([this.regionPolygon], this.mymap);
          }
        },
        /**清除所有绘制的多边形 */
        clearAll() {
          for (let i = 0; i < this.overlays.length; i++) {
            this.mymap.removeOverlay(this.overlays[i]);
          }
          this.overlays = [];
          this.createForm_Project.projectBoundary = [];
        },
        /**保存地图 */
        saveMap() {
          const that = this;
          let arr = [];
          if (that.overlays.length == 0) {
            return [];
          } else {
            for (let j = 0; j < that.overlays.length; j++) {
              that.overlays[j].disableEditing();
              let s = [];
              let overlays = that.overlays[j].getPath();
              for (let i = 0; i < overlays.length; i++) {
                s.push([overlays[i].lng, overlays[i].lat]);
              }
              s.push([overlays[0].lng, overlays[0].lat]); //形成闭环
              arr.push(s);
            }
            let roadArea = arr;
            return roadArea;
          }
        },
        /**刷新overlays数据 */
        showOverlays() {
          this.overlaysLength();
          // 加载overlayers到地图上
          for (let i = 0; i < this.overlays.length; i++) {
            this.mymap.addOverlay(this.overlays[i]);
            //创建右键菜单
            let markerMenu1 = new BMap.ContextMenu();
            markerMenu1.addItem(
              new BMap.MenuItem("删除", this.removeMarker.bind(this.overlays[i]))
            );
            markerMenu1.addItem(
              new BMap.MenuItem("编辑", this.editMarker.bind(this.overlays[i]))
            );
            this.overlays[i].addContextMenu(markerMenu1);
          }
        },
        //关闭地图弹窗
        closeMap(){
          this.boundaryMapVisible=false
           for (let i = 0; i < this.overlays.length; i++) {
            this.mymap.removeOverlay(this.overlays[i]);
          }
        },
        //在获取项目信息时,对获取到的项目范围点位数据进行处理,方便回显已绘制地区
        pointsArr2Overlays(data) {
          // let myOverlay = [];
          let overlays = [];
          if (data && data != "") {
            let pointsArr = JSON.parse(data);
            // console.log(pointsArr);
            if (pointsArr && pointsArr.length > 0) {
              pointsArr.forEach((item, i) => {
                // console.log(item)
                let myOverlay = [];
                item.forEach((arr, j) => {
                  let point = new BMap.Point(arr[0], arr[1]);
                  myOverlay.push(point);
                });
                let myPolygon = new BMap.Polygon(
                  myOverlay,
                  this.$polygonStyleOptions
                );
                myPolygon.disableMassClear();
                //         //将加载的多边形保存到数组里面
                overlays.push(myPolygon);
              });
            }
            return overlays;
          } else {
            return overlays;
          }
        },
        //编辑项目(外层弹窗)
        editForm(id){
            programEval.getProjectInfo(id).then((data ) => {
                this.createForm_Project = JSON.parse(JSON.stringify(data.data)); 
                //处理项目范围数据
                this.overlays = this.pointsArr2Overlays(this.createForm_Project.projectBoundary);
            });
                this.dialogVisible_Project = true;
        },

    },
    mounted(){
    }
}

CSS部分

<style scoped lang="scss">
.searchform {
    height: 52px;
    z-index: 3500;
    width: 100%;
    min-width: 1390px;
  }
  .mymap-box {
    min-width: 1400px;
    position: absolute;
    top: 70px;
    bottom: 30px;
    left: 25px;
    right: 25px;

    /*地图样式*/
    #mymap {
      position: absolute;
      top: 60px;
      bottom: 0px;
      width: 100%;
      border: 1px solid #1b86b9;
      /* height: 100%; */
      overflow: hidden;
      z-index: 1;
    }
    /*地图结果查询*/
    #result {
      border-left: 1px dotted #999;
      background: #fff;
      /* height: 100%; */
      width: 400px;
      position: absolute;
      top: 65px;
      left: 20px;
      font-size: 12px;
    }
  }
</style>

ChenW1
1 声望0 粉丝