vue+leaflet地图测距工具实现(纯手工代码)

134 阅读1分钟

话不多说,先上效果图

微信图片_20241010154006.png

相关代码如下,部分代码可能写的不优雅,欢迎掘友们讨论!

data() {
  distance: 0, // 测距总长度km
  distanceLineLength: 0, // 测距每一段线段的长度km
  distanceLayer: null, // 测距的图层
  distanceLayerList: [], // 多条测距的图层组数组集合
  disCircleList: [], // 测距的点集合
  isMeasureDistance: false, // 是否地图测距
},
methods: {
  // ...省略leaflet初始化地图
  // 测距
    getDistanceHandler() {
      if (this.isMeasureDistance == true) {
        if (this.distanceLayer != null) {
          this.map.removeLayer(this.distanceLayer)
        }
        if (this.distanceLayerList.length != 0) {
          this.distanceLayerList.forEach(item => {
            let lay = item.layers
            this.map.removeLayer(lay)
          })
        }
        this.map.off('click');
        this.map.off('dblclick');
        this.map.off('mousemove');
        this.disCircleList = []
        this.distanceLayerList = []
        this.isMeasureDistance = false
        return
      } else {
        this.isMeasureDistance = true
        this.disCircleList = []
        this.distance = 0
      }

      // 计算两点之间的距离
      const dkLineLength = (a, b) => {
        return this.map.distance(a, b)
      }
      // if (this.distanceLayer != null) {
      //   this.map.removeLayer(this.distanceLayer)
      // }
      this.distanceLayer = L.layerGroup()
      this.map.addLayer(this.distanceLayer)

      var timeStamp = Date.now()  // 移除图层的唯一标记
      // 单击事件
      const onClick = (e) => {
        console.log('测距---单击事件', e)
        var lat = e.latlng.lat //纬度
        var lng = e.latlng.lng //经度
        // 测距单击事件两个点位置相同
        if (this.disCircleList.length != 0 && this.disCircleList.slice(-1)[0][0] == lat && this.disCircleList.slice(-1)[0][1] == lng) {
          return;
        }

        this.disCircleList.push([lat, lng])
        let cirHtml = ``
        if (this.disCircleList.length <= 1) {
          cirHtml = `<div style='background: #465996; width: max-content; height: 23px; line-height: 25px; padding: 0 5px; color: #fff''>起点</div>`
        } else {
          this.distanceLineLength = Number((dkLineLength(this.disCircleList.at(-2), this.disCircleList.at(-1)) / 1000).toFixed(3))
          this.distance = Number(this.distance) + this.distanceLineLength
          cirHtml = `<div style='background: #465996; width: max-content; height: 23px; line-height: 25px; padding-left: 5px; color: #fff'>` + this.distanceLineLength + `(公里)</div>`
          L.polyline([this.disCircleList.at(-2), this.disCircleList.at(-1)], { color: 'red', weight: 1 }).addTo(this.distanceLayer)
        }
        var texticon = L.divIcon({
          html: cirHtml,
          iconAnchor: [-5, 12] //设置标签偏移避免遮盖
        });
        L.marker([lat, lng], {
          icon: texticon
        }).addTo(this.distanceLayer)
        //初次打点
        L.circle([lat, lng], {
          color: "red",
          fillColor: "red",
          fillOpacity: "1",
          radius: 2000,
        }).addTo(this.distanceLayer)
      }
      this.map.on('click', onClick)

      let that = this
      this.map.on('dblclick', function (ev) {
        var lat = ev.latlng.lat //纬度
        var lng = ev.latlng.lng //经度
        let distanceLineLength = Number((dkLineLength(that.disCircleList.at(-2), that.disCircleList.at(-1)) / 1000).toFixed(3))

        const cirHtml = document.createElement("div");
        cirHtml.className = "measure-marker-distance";
        cirHtml.innerText = distanceLineLength + '(公里)总长度:' + that.distance.toFixed(3) + '(公里)'

        let closeSpan = document.createElement("span");
        closeSpan.style.color = "rgb(0, 255, 64)";
        closeSpan.innerText = "【关闭】"

        closeSpan.addEventListener("click", () => {
          let dpk = that.distanceLayerList.filter(item => item.id == timeStamp)[0].layers
          that.map.removeLayer(dpk)
        });
        cirHtml.appendChild(closeSpan)

        //双击最后一次打点
        var texticon = L.divIcon({
          html: cirHtml,
          iconAnchor: [-5, 12] //设置标签偏移避免遮盖
        });
        L.marker([lat, lng], {
          icon: texticon,
          zIndex: 5,
        }).addTo(that.distanceLayer)

        that.distanceLayerList.push({
          id: timeStamp,
          layers: that.distanceLayer
        })
        that.isMeasureDistance = false

        that.map.off('click');
        that.map.off('dblclick');
        that.map.off('mousemove');
      });
    },
}

.measure-marker-distance {
  background: #465996; 
  width: max-content; 
  height: 23px; 
  line-height: 23px; 
  padding-left: 5px; 
  color: #fff;
}