百度地图BMap vue 绘制电子围栏--模拟矩形编辑--测距工具

需求:由于项目需求,需要集成百度地图并会有相关坐标点展示,且需要绘制围栏等等操作。

需求开发遇到的坑:==>由于前期集成了vue-baidu-map 官方地址 具体集成请自行参考百度,页面地图是使用BMap,后面打算引入百度地图绘制辅助工具BMapGLLib,结果并不能正常显示绘制工具和进行绘制;仔细分析后发现是集成的地图不匹配。(辅助工具BMapGLLib只能用于创建的BMapGL地图,而BMap不能使用),BMapGLLib工具实在是好用,可自动开启编辑(主要是矩形编辑的问题)。因此只能另开途径进行开发。

注意:以下方法皆是居于BMap实现的,如引入百度地图为BMapGL,请自行参考百度地图api

open | 百度地图API SDK   辅助工具目录

解决方案步骤:

1、在vue项目的index.html里面加上以下代码: 这个是BMap的引入

<script type="text/javascript" src="//api.map.baidu.com/api?v=3.0&ak=您的密钥"></script>

2、继续引入绘制工具,适用于BMap地图

 <!--绘制工具-->

    <script type="text/javascript" src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script>

    <script type="text/javascript" src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css"></script>

<!-- 测距工具 -->

    <script type="text/javascript" src="http://api.map.baidu.com/library/DistanceTool/1.2/src/DistanceTool_min.js"></script>

3、创建地图,具体创建方法参考自己项目,本处只是例子参考

<script>
createMap(lgt, lat) {
      // this.maploading=true;
      this.map = new BMap.Map("XXX", { enableMapClick: false }) // 创建Map实例空间为BMap(鼠标右键控制倾斜角度)
      this.map.centerAndZoom(new BMap.Point(lgt, lat), 11)      // 初始化地图,设置中心点坐标和地图级别
      this.map.enableScrollWheelZoom(true)// 开启鼠标滚轮缩放
    },
</script>

4、通过按钮点击进行圆形,矩形,多边形进行选择绘制,具体参考代码,本代码是放在methods下

<script>
  //绘制围栏(圆形,矩形,多边形)
    createEnS(drawingType){
    let self=this
       
      //画图样式
      let styleOptions = {
        strokeColor:"rgb(27, 167, 229)",    //边线颜色。
        fillColor:"rgb(27, 167, 229)",      //填充颜色。当参数为空时,圆形将没有填充效果。
        strokeWeight: 2,       //边线的宽度,以像素为单位。
        strokeOpacity: 0.8,	   //边线透明度,取值范围0 - 1。
        fillOpacity: 0.3,      //填充的透明度,取值范围0 - 1。
        strokeStyle: 'dashed', //边线的样式,solid或dashed。
      };
      //生成鼠标绘制工具
      var drawingManager = new BMapLib.DrawingManager(self.map , {
        isOpen: false, 
        // drawingType: BMAP_DRAWING_CIRCLE,
       // enableDrawingTool:false, //是否显示工具栏
        // drawingToolOptions: {
        //   anchor: BMAP_ANCHOR_TOP_LEFT,
        //   offset: new BMap.Size(5, 50),
        //   drawingModes:[
        //     // BMAP_DRAWING_POLYGON,
        //     BMAP_DRAWING_CIRCLE
        //   ]
        // },
        // enableCalculate: true, // 绘制是否进行测距测面
        enableSorption: true, // 是否开启边界吸附功能
        sorptiondistance: 20, // 边界吸附距离
        //图形默认样式
        circleOptions: styleOptions,
        polylineOptions: styleOptions,
        polygonOptions: styleOptions,
        rectangleOptions: styleOptions
      });
      let drawingMode
       if(drawingType=='circular'){
        drawingMode=BMAP_DRAWING_CIRCLE
       }else if(drawingType=='rectangular'){
        drawingMode=BMAP_DRAWING_RECTANGLE
       }else if(drawingType=='polygon'){
        drawingMode=BMAP_DRAWING_POLYGON
       }
       drawingManager.setDrawingMode(drawingMode)
       drawingManager.open()
     
      //判断图案类型
      let overlaycomplete = function(e){
            drawingManager.close();    
            //判断画图的类型
            if(e.drawingMode=='circle'){
              //圆形
              let radius=e.overlay.getRadius();//圆半径
              let circlecenter=e.overlay.getCenter(); //圆心坐标
              //开启编辑
              e.overlays.enableEditing()  
              //监听编辑
              e.overlays.addEventListener("lineupdate",function(e){
                e.overlays.center=e.target.point; //圆心
                e.overlays.radius=e.target.xa; //半径
              });
            }else if (e.drawingMode=='rectangle') {
              //矩形,特殊--由四个标记点带动编辑的改变
                var myIcon = new BMap.Icon(self.url+'checkbox.png', new BMap.Size(13,13));//增加icon,可以截取百度默认的选择框增加相似度
              let startPoint
              let endPoint
              let startPointTwo
              let endPointTwo
              e.overlay.getPath().forEach((item,index)=>{
                  if (index==0) {//左上角点
                      startPoint=item
                      let markerStart= new BMap.Marker(item,{icon:myIcon})
                      markerStart.enableDragging()
                     markerStart.addEventListener('dragging',(target)=>{
                          startPoint = target.point
                          e.overlay.setPath(this._getRectanglePoint(target.point,endPoint));
                         
                      })
                       self.map.addOverlay(markerStart); 
                  }else if (index==2) {//右下角点
                      endPoint=item
                      let markerEnd = new BMap.Marker(item,{icon:myIcon})
                      markerEnd.enableDragging()
                      markerEnd.addEventListener('dragging',(target)=>{
                          endPoint=target.point
                          e.overlay.setPath(this._getRectanglePoint(startPoint,target.point));
                          
                      })
                       self.map.addOverlay(markerEnd); 
                      }
              })
              
          }else{
            //多边形
              //其它图形打开编辑功能                                                                                                                               
              e.overlay.enableEditing();
              e.overlay.addEventListener("lineupdate",function(p){
             
              })
          }
          };
           //监听整个绘制围栏方法
      drawingManager.addEventListener('overlaycomplete', overlaycomplete);
    },
    _getRectanglePoint(startPoint,endPoint){
      return [
          new BMap.Point(startPoint.lng,startPoint.lat),
          new BMap.Point(endPoint.lng,startPoint.lat),
          new BMap.Point(endPoint.lng,endPoint.lat),
          new BMap.Point(startPoint.lng,endPoint.lat)
      ];
    }
</script>

注意:由于矩形特殊,且new BMapLib.DrawingManager绘制工具没有自带的矩形编辑功能,只能通过捷径进行模拟矩形绘制,本文只进行两个顶点的模拟拉动,如想四顶点一起模拟请自行编写(思路一致,处理好拉动一个顶点其余三顶点逻辑关系就好==>可参考如下方法:虽然比较笨,但可实现,如有高效便捷方法请分享呗)

模拟绘制矩形编辑四顶点关系大概逻辑:

<script>
 /*只是为了好看才用写在方法内,具体结合上文打开编辑后模拟的矩形顶点监听器内,
e表示模拟矩形顶点Marker移动属性,index为模拟矩形顶点的顺序(左上角为0,
右上角为1,右下角为2,左下角为3),具体传参结合上文模拟矩形顶点编辑,
此处只提供较笨的大概逻辑;polygonPath表示绘制矩形的四顶点坐标==>
e.overlay.getPath()
注意:polygonPath计算完坐标后返回给上文e.overlay.setPath
(rectangularDragend(e, index));重新赋值模拟矩形坐标才能实现矩形移动,当然,
其余模拟顶点Marker也要重新更新坐标,请自行编写代码更新*/
    rectangularDragend(e, index,polygonPath) {
      let self = this
       let newArr = [], point0, point1, point2, point3
       switch (index) {
         case 0:
           point2 = polygonPath[2]
           point0 = e.point
           point1 = { lng: polygonPath[2].lng, lat: e.point.lat }
           point3 = { lng: e.point.lng, lat: polygonPath[2].lat }
           break;
         case 1:
           point0 = { lng: polygonPath[3].lng, lat: e.point.lat }
           point3 = polygonPath[3]
           point1 = e.point
           point2 = { lng: e.point.lng, lat: polygonPath[3].lat }
           break;
         case 2:
           point0 = polygonPath[0]
           point1 = { lng: e.point.lng, lat: polygonPath[0].lat }
           point2 = e.point
           point3 = { lng: polygonPath[0].lng, lat: e.point.lat }
           break;
         case 3:
           point0 = { lng: e.point.lng, lat: polygonPath[1].lat }
           point1 = polygonPath[1]
           point2 = { lng: polygonPath[1].lng, lat: e.point.lat }
           point3 = e.point
           break;
       }
       self.$nextTick(() => {  //self.$nextTick可去除,根据实际情况
         newArr.push(point0)
         newArr.push(point1)
         newArr.push(point2)
         newArr.push(point3)
         //此处可返回newArr给调用方法
        return newArr
       })
    },
</script>

5、鼠标测距工具,由于步骤2处已引入相关控件,直接使用即可,代码如下:

<script>
      // 测距工具
    distanceTool(){
         var distance= new BMapLib.DistanceTool(this.map)
         distance.open()
			// //监听测距尺鼠标右击测距尺添加完成的时候触发的事件
        distance.addEventListener('drawend', function(e) {
          //自身项目处理逻辑
        });
        },
</script>

矩形编辑模拟情况效果如下:

 本人开发过程经历的一个大坑分享:

      前期发现BMap无法使用辅助工具BMapGLLib后,考虑过辅助工具BMapLib,但百度一番没找到辅助工具BMapLib下矩形编辑的问题,由于第一次接触vue和百度地图(我是写后端Java的,被项目经理拉来帮忙干前端vue),所以开始实现思路是利用鼠标点击、移动和结合vue-baidu-map官网的圆形,多边形绘制方法进行手动绘制==>即编写自己的控件,后面经历三天后完成控件的编写,成功实现了圆形,矩形,多边形各自绘制和编辑,但后面本人发现了一个大坑;

==================================大坑========================

        由于vue-baidu-map是需要操作DOM元素进行地图上添加各种覆盖物,而我手动编写的控件就是基于vue-baidu-map进行开发,当地图上出现大量的覆盖物时,此时进行电子围栏的绘制(圆形,矩形,多边形)都会超级卡顿,让人一看就觉得是bug;后来才发现是手动绘制不断更新坐标位置和覆盖物位置大量操作了DOM元素导致的,只能放弃自编的控件而采用百度地图给出的控件辅助工具BMapLib,进行一定程度功能修改。一次难忘的制造bug经历。。。。。

自己吐槽下,原本是想把BMap更改为BMapGL地图,害怕更改后前面编写的信息窗口,标志,路书(轨迹)等出现问题且能力有限不知到如何全局更改只能放弃了。

至此本文结束。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值