最近项目需要使用离线地图 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>