百度地图BMap vue 绘制电子围栏--模拟矩形编辑--测距工具
后台-插件-广告管理-内容页头部广告(手机) |
需求:由于项目需求,需要集成百度地图并会有相关坐标点展示,且需要绘制围栏等等操作。
需求开发遇到的坑:==>由于前期集成了vue-baidu-map 官方地址 具体集成请自行参考百度,页面地图是使用BMap,后面打算引入百度地图绘制辅助工具BMapGLLib,结果并不能正常显示绘制工具和进行绘制;仔细分析后发现是集成的地图不匹配。(辅助工具BMapGLLib只能用于创建的BMapGL地图,而BMap不能使用),BMapGLLib工具实在是好用,可自动开启编辑(主要是矩形编辑的问题)。因此只能另开途径进行开发。
注意:以下方法皆是居于BMap实现的,如引入百度地图为BMapGL,请自行参考百度地图api
open | 百度地图API SDK 辅助工具目录
解决方案步骤:
1、在vue项目的index.html里面加上以下代码: 这个是BMap的引入
2、继续引入绘制工具,适用于BMap地图
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.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |