vue leaflet 测量尺功能

最近项目需要使用离线地图 leaflet是最好的选择,但是翻遍各大大佬文章找了很多量尺功能都不好用,要不是不兼容 索性自己写一个简单的测量功能 根据地图的经纬度来计算距离。给列为提供个思路,可以自己封装利用,兼容vue2,vue3

<template>
  <div>
    <div id="map"></div>
    <button @click="startMeasurement">开始测量</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      map: null,
      drawnItems: null,
      lastClickedLatLng: null,
      totalDistance: 0,
      measuring: false, // 用于跟踪测量是否在进行中
      polyline: null, // 用于保存绘制的线对象
    };
  },
  mounted() {
    this.map = L.map('map', {
      minZoom: 4,
      maxZoom: 13,
      maxBounds: [
        [35.606168, 123.01982],
        [38.126654,123.70392],
        [38.013431,115.635907],
        [34.356035,115.013999],
      ],
    }).setView([36.91695414, 118.58299255], 10);

    L.tileLayer('../../public/MAP_zxy/{z}/{x}/{y}.png', {}).addTo(this.map);

    this.drawnItems = L.layerGroup().addTo(this.map);

    // 添加监听 ESC 键的事件
    window.addEventListener('keydown', this.handleKeyDown);
  },
  beforeUnmount() {
    // 移除 ESC 键的事件监听
    window.removeEventListener('keydown', this.handleKeyDown);
  },
  methods: {
    startMeasurement() {
      this.measuring = true;
      this.map.on('click', this.onClickMeasurement);
    },
    onClickMeasurement(e) {
      if (!this.lastClickedLatLng) {
        this.lastClickedLatLng = e.latlng;
        var label = this.createLabelLayer('起点', e.latlng).addTo(this.map);
        this.drawnItems.addLayer(label);
      } else {
        var distance = this.lastClickedLatLng.distanceTo(e.latlng);
        this.totalDistance += distance;
        var labelText = (this.totalDistance / 1000).toFixed(2) + ' km';
        var label = this.createLabelLayer(labelText, e.latlng).addTo(this.map);
        this.drawnItems.addLayer(label);
        
        // 绘制线
        if (this.polyline) {
          this.polyline.addLatLng(e.latlng);
        } else {
          this.polyline = L.polyline([this.lastClickedLatLng, e.latlng], { color: 'red' }).addTo(this.map);
        }
        
        this.lastClickedLatLng = e.latlng;
      }
    },
    createLabelLayer(text, latlng) {
      return L.marker(latlng, {
        icon: L.divIcon({
          className: 'custom-label',
          html: '<div class="label-box">' + text + '</div>',
          iconSize: [100, 30] // 调整标签框大小
        })
      });
    },
    // 处理按下 ESC 键的事件
    handleKeyDown(event) {
      if (event.key === 'Escape') {
        this.cancelMeasurement();
      }
    },
    // 取消测量的方法
    cancelMeasurement() {
      this.measuring = false;
      this.map.off('click', this.onClickMeasurement);
      this.lastClickedLatLng = null;
      this.totalDistance = 0;
      if (this.polyline) {
        this.map.removeLayer(this.polyline);
        this.polyline = null;
      }
      this.drawnItems.clearLayers();
    }
  },
};
</script>

<style>
#map {
  position: absolute;
  width: 100%;
  height: 90%;
}
button {
  position:absolute ;
  bottom: 0;
  margin-left: 10px;
  z-index: 10;
}
.label-box {
  background-color: transparent !important;
  border: 1px solid #ccc;
  width: 60px !important;
  margin-bottom: 10px;
  font-weight: 600;
  white-space: nowrap !important;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值