vue结合百度地图绘制工具遇到的问题及解决方案(多边形编辑状态下形状显示不全、marker点添加事件无效)

本文介绍如何在Vue项目中集成百度地图API及其绘制工具,包括异步加载地图和工具的方法,并解决了绘制完成后多边形边界无法正常编辑及标记点事件无效的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue如何引入百度地图绘制工具

1.定义异步加载的js方法

const ak = 'nZVpgxBGRxCHTiznnR2d5kPK'
/**
 * 异步加载百度地图
 * @returns {Promise}
 * @constructor
 */
function loadBaiDuMap () {
  return new Promise(function (resolve, reject) {
    try {
      console.log('BMap is defined:', BMap === undefined || BMap)
      resolve(BMap)
    } catch (e) {
      window.init = function () {
        resolve(BMap)
      }
      let script1 = document.createElement('script')
      script1.type = 'text/javascript'
      script1.src = 'http://api.map.baidu.com/api?v=2.0&ak=' + ak + '&callback=init'
      script1.onerror = reject
      document.body.appendChild(script1)
    }
  })
}

export {loadBaiDuMap}

/**
 * 异步加载百度地图,以及绘制工具
 * @returns {Promise}
 * @constructor
 */
function loadBaiDuDrawMap () {
  return loadBaiDuMap().then(BMap => {
    let loaded = false
    try {
      loaded = (BMapLib && BMapLib.DrawingManager)
    } catch (e) {
      loaded = false
    }
    if (!loaded) {
      console.log('BMapLib.DrawingManager loading!')
      let script2 = document.createElement('script')
      script2.type = 'text/javascript'
      script2.src = 'http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js'
      document.body.appendChild(script2)
      let link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = 'http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css'
      document.body.appendChild(link)
    } else {
      console.log('BMapLib.DrawingManager is loaded!')
    }
    return BMap
  })
}

export {loadBaiDuDrawMap}

2.vue文件中异步加载百度地图,初始化绘制工具

initMap () { // 初始化地图
        let vue = this
        loadBaiDuDrawMap().then(BMap => {
          vue.bmap = new BMap.Map('bmap', {enableMapClick: false})            // 创建Map实例
          if (vue.cityId !== '') {
            vue.bmap.centerAndZoom(vue.cityName, vue.cityZoom)
          }
          vue.bmap.enableScrollWheelZoom()
          vue.bmap.clearOverlays()
          vue.bmap.addControl(new BMap.NavigationControl({anchor: BMAP_ANCHOR_BOTTOM_RIGHT, type: BMAP_NAVIGATION_CONTROL_ZOOM}))
        })
      }

initDrawingManager () { // 初始化地图绘制工具,需要在第一次开启绘制时再初始化,如果随着页面加载一起初始化会报错
        if (!this.drawingManager) {
          this.drawingManager = new BMapLib.DrawingManager(this.bmap, {
            isOpen: false, // 是否开启绘制模式
            enableDrawingTool: false, // 是否显示工具栏
            polygonOptions: this.bizAddForm.polygonStyle // 多边形的样式
          })
          // 添加鼠标绘制工具监听事件,用于获取绘制结果
          // 多边形画完之后的事件
          this.drawingManager.addEventListener('polygoncomplete', this.polygonComplete)
          // marker点画完之后的事件
          this.drawingManager.addEventListener('markercomplete', this.markerComplete)
        }
      }

进入正题

先说一下我使用绘制工具的场景:
要画一个多边形,双击画完之后,让多边形处于编辑状态(我需要再次修改多边形的边界),还要给多边形设置一个中心点和名称,名称显示的位置就是中心点位置,中心点可以拖拽,拖拽过程中,名称位置会跟着中心点移动

这其中遇到两个问题如下:
两个问题的解决思路是一样的,不直接使用绘制工具绘制的覆盖物对象,而是复制一个新的来用

问题1

画好多边形之后再修改多边形的边界就有问题了,边界能改动,但是要是拖动或者缩放了地图,多边形又会变回最一开始画的,边界点还存在,如下图
这里写图片描述

问题代码:

polygonComplete (ply) { // 多边形覆盖物绘制完成之后的事件
   // 直接使用了绘制工具画好的多边形对象
   ply.enableEditing()
}

正确代码:

polygonComplete (ply) { // 多边形覆盖物绘制完成之后的事件
   // new一个新的多边形,将绘制工具画好的多边形抛弃掉
   let newPly = new BMap.Polygon(ply.getPath(), this.bizAddForm.polygonStyle)
   this.bmap.removeOverlay(ply) // 删掉绘制工具绘制的多边形覆盖物
   this.bmap.addOverlay(newPly) // 添加新的多边形覆盖物
   newPly.enableEditing() // 此代码一定要放在addOverlay之后
}

问题2

多边形的中心点画好之后,给中心点添加的事件不起作用

问题代码:

markerComplete (marker) { // 绘制marker点完成之后的事件
        marker.enableDragging()
        // 添加事件,不会起作用
        marker.addEventListener('dragend', function (e) {
          vue.currentEditPly.bizLabel.setPosition(e.point)
        })
        // 添加商圈名称
        vue.currentEditPly.bizLabel = vue.getLabel(marker.getPosition(), vue.currentEditPly.bizData.bizName)
        vue.bmap.addOverlay(vue.currentEditPly.bizLabel)
        vue.drawingManager.close()
 }

正确代码:

markerComplete (marker) { // 绘制marker点完成之后的事件
        // 复制一个新的marker,抛弃绘制工具绘制的marker
        let newMarker = new BMap.Marker(marker.getPosition())
        // 添加事件
        newMarker.addEventListener('dragend', function (e) {
          vue.currentEditPly.bizLabel.setPosition(e.point)
        })
        vue.bmap.addOverlay(newMarker ) // 添加新marker的覆盖物
        vue.bmap.removeOverlay(marker) // 删掉绘制工具绘制的marker覆盖物

        // 添加商圈名称
        vue.currentEditPly.bizLabel = vue.getLabel(marker.getPosition(), vue.currentEditPly.bizData.bizName)
        vue.bmap.addOverlay(vue.currentEditPly.bizLabel)
        vue.drawingManager.close()
 }

分享一下,希望对遇到相同问题的同学有帮助

可以使用高德地图 JavaScript API 中提供的绘制工具库来实现这些功能。以下是简单的封装实现: 1. 引入高德地图 JavaScript API 和绘制工具库: ```html <script src="https://webapi.amap.com/maps?v=1.4.15&key=YOUR_KEY"></script> <script src="https://webapi.amap.com/ui/1.0/main.js"></script> ``` 2. 定义绘制工具类: ```javascript class AMapDrawTool { constructor(map) { this.map = map; this.tool = new AMap.MouseTool(map); this.listeners = []; } addListener(eventType, handler) { this.listeners.push({ eventType, handler }); this.tool.on(eventType, handler); } removeListeners() { this.listeners.forEach(({ eventType, handler }) => { this.tool.off(eventType, handler); }); this.listeners = []; } drawRectangle() { this.tool.rectangle(); } drawCircle() { this.tool.circle(); } drawPolygon() { this.tool.polygon(); } drawMarker() { this.tool.marker(); } drawPolyline() { this.tool.polyline(); } } ``` 3. 创建地图实例和绘制工具实例: ```javascript const map = new AMap.Map('map-container', { center: [116.397428, 39.90923], zoom: 13, }); const drawTool = new AMapDrawTool(map); ``` 4. 添加绘制完成事件监听器并处理绘制结果: ```javascript drawTool.addListener('draw', (e) => { const overlay = e.obj; console.log('绘制完成', overlay); // 处理绘制结果 }); // 移除事件监听器 drawTool.removeListeners(); ``` 5. 调用绘制方法开始绘制: ```javascript drawTool.drawRectangle(); drawTool.drawCircle(); drawTool.drawPolygon(); drawTool.drawMarker(); drawTool.drawPolyline(); ``` 以上是一个简单的封装实现,你可以根据自己的需求进行修改和扩展。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值