文章目录

  • 前言
  • 测距实现思路
  • 使用测距插件
  • 开启测距
  • 关闭测距



前言

高德提供了一个距离测量插件可直接使用,但是没有完全满足需求。在测距过程中只会显示新增节点到起始点的总长度,而不会在鼠标移动过程中显示鼠标所在的位置到起始点的总长度,也不会给出继续和如何结束测距的提示。

但是高德地图自己是有这个总长度与如何操作提示的,所以基于高德提供的距离测量插件,进行了一些小的改动实现这个总长度提示,本篇主要讲述如何获取总长度。

java 高德api根据地名计算距离 高德距离工具_覆盖物

测距实现思路

  1. 要基于高德提供的测距插件RangingTool进行实现,此插件可直接添加使用。
  2. 在开启测距后,如果起点打在了自己绘制的覆盖物上,那么会触发覆盖物的点击事件,所以在覆盖物的点击事件逻辑中要做规避处理。
  3. 由于绘制的覆盖物都是不冒泡的,即覆盖物的事件不会通过冒泡传到地图上。所以测距的点打在区域上后,点击事件不会冒泡到地图上,而测距插件主要是监听地图的点击事件,导致测距无法正常使用。这里的设计是地图在开启测距功能时,拿到所有的覆盖物实例,给覆盖物开启冒泡功能;在地图测距功能结束时,再把所有的覆盖物冒泡功能关闭掉。

使用测距插件

window.AMap.plugin(['AMap.RangingTool'], () => {
     this.ruler = new window.AMap.RangingTool(window.map);
  },
)

开启测距

主要是开启地图测距能力、更改鼠标测距样式、监听一些事件、开启覆盖物冒泡。

fn(val) {
  if (val) {
    this.ruler.turnOn(); // 开启测距
    window.map.setDefaultCursor(`xxx`); // 改变鼠标样式
    window.map.on('mousemove', this.mouseMove);
    window.map.on('rightclick', this.rangeRightClick);
    this.ruler.on('addnode', this.addnode);
    this.ruler.on('end', this.end);
    window.map.getAllOverlays().forEach((v) => {
          v.De.bubble = true;
          // if (v.CLASS_NAME === 'AMap.Marker') {
          //   v.De.bubble = true;
          // } else if (['AMap.Polyline', 'AMap.Polygon', 'AMap.Rectangle', 'AMap.Circle'].includes(v.CLASS_NAME)) {
          //   const temp = v.getOptions();
          //   v.setOptions({ ...temp, bubble: true });
          // }
    });
  }
}

测距时每新增一个节点,都要记录一下,同时记录起始点到这个最新节点间的距离,就是更新此时测距的总距离。

addnode(e) {
  this.rangeArr.push(e.position);
  if (this.rangeArr.length > 1) {
    const res = window.AMap.GeometryUtil.distance(this.rangeArr[this.rangeArr.length - 1], this.rangeArr[this.rangeArr.length - 2]);
    this.rangeSum += res;
  }
}

测距过程中,在鼠标移动时,也要实时更新鼠标所在的位置到起始点的总距离,这里的总距离可不是直线距离。

mouseMove(e) {
  if (this.rangeArr.length) {
    const res = window.AMap.GeometryUtil.distance(this.rangeArr[this.rangeArr.length - 1], e.lnglat);
    this.showRangeTotal = this.rangeSum + res;
  }
}

关闭测距

关闭测距的逻辑和开启测距的逻辑反着来就行了。关闭地图测距能力、恢复鼠标样式、去除监听事件、关闭覆盖物冒泡。

fn(val) {
  if (val) {
    ......
  } else {
    this.ruler.turnOff();
   ......
  }
}