Leaflet计算两点之间距离

发布于:2025-05-30 ⋅ 阅读:(19) ⋅ 点赞:(0)

在地图应用中有时候需要计算两点之间的距离,在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:
                '&copy; <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:
                    '&copy; <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;
            }
        });
    }
}