在地图应用中有时候需要计算两点之间的距离,在Leaflet中我们可以使用Leaflet提供的distance方法来实现。
下面看一个例子在地图上用鼠标选择两个点,然后画一条直线,并计算距离。
首先我们声明一些变量,除了map之外,还声明了两个点的坐标 latlngA 和 latlngB,已经两个标记 markerA 和 markerB,另外还包括一条直线 polyline。
map!: leaflet.Map;
latlngA: leaflet.LatLng | null = null;
latlngB: leaflet.LatLng | null = null;
markerA: leaflet.Marker | null = null;
markerB: leaflet.Marker | null = null;
polyline: leaflet.Polyline | null = null;
然后初始化地图,可以设置坐标 this.map = leaflet.map("map").setView([51.5, -0.09], 16);
,这里使用定位到当前位置 leaflet.map("map").locate({ setView: true, maxZoom: 16 });
private initMap(): void {
this.map = leaflet.map("map");
const tiles = leaflet.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
},
);
tiles.addTo(this.map);
this.map.locate({ setView: true, maxZoom: 15 });
}
下面来处理距离计算,主要是通过 map
上的 click
事件来处理
this.map.on("click", (e) => {
if (!this.latlngA) {
this.latlngA = e.latlng;
this.markerA = leaflet.marker(this.latlngA).addTo(this.map);
} else if (!this.latlngB) {
this.latlngB = e.latlng;
this.markerB = leaflet.marker(this.latlngB).addTo(this.map);
this.polyline = leaflet
.polyline([this.latlngA, this.latlngB], {
color: "red",
})
.addTo(this.map);
console.log("markerA: ", this.latlngA);
console.log("markerB: ", this.latlngB);
console.log(
"distance: ",
this.map.distance(this.latlngA, this.latlngB),
);
} else {
if (this.polyline) {
this.map.removeLayer(this.polyline);
this.polyline = null;
}
if (this.markerA) this.map.removeLayer(this.markerA);
if (this.markerB) this.map.removeLayer(this.markerB);
this.latlngA = e.latlng;
this.markerA = leaflet.marker(this.latlngA).addTo(this.map);
this.latlngB = null;
this.markerB = null;
}
});
最后看一下完整代码:
import { Component, OnInit, AfterViewInit } from "@angular/core";
import * as leaflet from "leaflet";
@Component({
selector: "app-map-calculate-distance",
template: `
<div class="map-container">
<div class="map-frame">
<div id="map"></div>
</div>
</div>
`,
styles: `
.map-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 30px;
}
.map-frame {
border: 2px solid black;
height: 500px;
width: 800px;
}
#map {
height: 100%;
}
`,
})
export class MapCalculateDistanceComponent implements OnInit, AfterViewInit {
map!: leaflet.Map;
latlngA: leaflet.LatLng | null = null;
latlngB: leaflet.LatLng | null = null;
markerA: leaflet.Marker | null = null;
markerB: leaflet.Marker | null = null;
polyline: leaflet.Polyline | null = null;
constructor() {}
ngOnInit(): void {}
ngAfterViewInit(): void {
this.initMap();
}
private initMap(): void {
this.map = leaflet.map("map");
const tiles = leaflet.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{
maxZoom: 19,
attribution:
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
},
);
tiles.addTo(this.map);
this.map.locate({ setView: true, maxZoom: 15 });
this.map.on("click", (e) => {
if (!this.latlngA) {
this.latlngA = e.latlng;
this.markerA = leaflet.marker(this.latlngA).addTo(this.map);
} else if (!this.latlngB) {
this.latlngB = e.latlng;
this.markerB = leaflet.marker(this.latlngB).addTo(this.map);
this.polyline = leaflet
.polyline([this.latlngA, this.latlngB], {
color: "red",
})
.addTo(this.map);
console.log("markerA: ", this.latlngA);
console.log("markerB: ", this.latlngB);
console.log(
"distance: ",
this.map.distance(this.latlngA, this.latlngB),
);
} else {
if (this.polyline) {
this.map.removeLayer(this.polyline);
this.polyline = null;
}
if (this.markerA) this.map.removeLayer(this.markerA);
if (this.markerB) this.map.removeLayer(this.markerB);
this.latlngA = e.latlng;
this.markerA = leaflet.marker(this.latlngA).addTo(this.map);
this.latlngB = null;
this.markerB = null;
}
});
}
}