在Leaflet中计算两点之间的距离

23

如何在Leaflet-ionic2中计算两个标记之间的距离?

我无法理解,希望有一个算法能够在我选择一个标记后立即显示我的位置和标记之间的距离。

谢谢..

3个回答

25

Leaflet手册中提到了distanceTo函数,它可以计算距离(数值距离,不是公制)。该距离是在边界的东北点和西南点之间测量的,没有计算驾车/步行距离,仅使用一条直线连接这两个极端来计算直接距离。

示例取自谷歌群组:

function createMarker()
{
     var markerFrom = L.circleMarker([28.6100,77.2300], { color: "#F00", radius: 10 });
     var markerTo =  L.circleMarker([18.9750,72.8258], { color: "#4AFF00", radius: 10 });
     var from = markerFrom.getLatLng();
     var to = markerTo.getLatLng();
     markerFrom.bindPopup('Delhi ' + (from).toString());
     markerTo.bindPopup('Mumbai ' + (to).toString());
     map.addLayer(markerTo);
     map.addLayer(markerFrom);
     getDistance(from, to);
}

function getDistance(from, to)
{
    var container = document.getElementById('distance');
    container.innerHTML = ("New Delhi to Mumbai - " + (from.distanceTo(to)).toFixed(0)/1000) + ' km';
}

1
这是基于Haversine或Vincenty算法的驾驶距离还是最短距离? - coder101
4
怎么可能是驾车距离?你应该看一下手册。“使用余弦定理计算给定经纬度之间的距离(以米为单位)。” - Lee Goddard
它不返回驾驶距离,而是返回边框矩形的极端之间的数值距离。这仅仅是一个简单的勾股定理计算。 - dresende

18
您可以使用此函数来查找两个位置之间的距离。
function getDistance(origin, destination) {
    // return distance in meters
    var lon1 = toRadian(origin[1]),
        lat1 = toRadian(origin[0]),
        lon2 = toRadian(destination[1]),
        lat2 = toRadian(destination[0]);

    var deltaLat = lat2 - lat1;
    var deltaLon = lon2 - lon1;

    var a = Math.pow(Math.sin(deltaLat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(deltaLon/2), 2);
    var c = 2 * Math.asin(Math.sqrt(a));
    var EARTH_RADIUS = 6371;
    return c * EARTH_RADIUS * 1000;
}
function toRadian(degree) {
    return degree*Math.PI/180;
}
var distance = getDistance([lat1, lng1], [lat2, lng2])

我们在我们的库time-aware-polyline中使用这个函数来编码带有时间戳的lat lng信息。


4
应该是[lat1,lng1],[lat2,lng2],而不是[lat1,lng2],[lat2,lng2]。 - Dave Driesmans
我真的很喜欢你。哈哈,谢谢老兄。我绝对不可能想出这个。 - Robert Ruby II
1
https://github.com/hypertrack/time-aware-polyline-js 是 404。 - Max Base

0

使用地理编码计算两个地址之间的距离和时间,如果leaflet地图提供了两条路线,您可以收集两条路线的信息,请考虑以下代码。 您需要包括以下软件包

<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
crossorigin=""></script>
<script src="jquery.min.js"></script>
<script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
<script src="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.js"></script>
<script type="text/javascript">


 geocoder = new L.Control.Geocoder.Nominatim();
    function geocode(location, func) {
    geocoder.geocode(location, function(loc1result){
        latLng1 = new L.LatLng(loc1result[0].center.lat, loc1result[0].center.lng);
        func({coordinates: {latLng1}});
      });
    }
    function geocode2(loc2, func) {
    geocoder.geocode(loc2, function(loc2result){
        latLng2 = new L.LatLng(loc2result[0].center.lat, loc2result[0].center.lng);
        func({coordinates: {latLng2}});
      });
    }
    
function fetchGeocodeLocation(location) {
  return new Promise((resolve, reject) => {   
    geocode(location, function(results) {   
      resolve(results.coordinates);
    });
  });
}
function fetchGeocodeLocation2(loc2) {
  return new Promise((resolve, reject) => {    
    geocode2(loc2, function(results) { 
      resolve(results.coordinates);
    });
  });
}

async function loc() {
    var loc1 = ("mardan khyber pakhtunkhwa"); 
    var loc2 = ("peshawar Khyber Pakhtunkhwa");
    var geoCodeLocation1 = await fetchGeocodeLocation(loc1);
    var geoCodeLocation2 = await fetchGeocodeLocation2(loc2);
    console.log(geoCodeLocation1.latLng1.lat);
    console.log(geoCodeLocation1.latLng1.lng);
    var map = L.map('map').setView([geoCodeLocation1.latLng1.lat,  geoCodeLocation1.latLng1.lng], 5);

    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: 'OSM'
    }).addTo(map);
    //alert(geoCodeLocation.latLng1.lat);
    // L.marker([geoCodeLocation1.latLng1.lat, geoCodeLocation1.latLng1.lng]).addTo(map)
    //    .bindPopup(loc1)
    //    .openPopup();
    // L.marker([geoCodeLocation2.latLng2.lat, geoCodeLocation2.latLng2.lng]).addTo(map)
    //    .bindPopup(loc2)
    //    .openPopup();

       L.Routing.control({
        show: false,
        waypoints: [
            L.latLng(geoCodeLocation1.latLng1.lat, geoCodeLocation1.latLng1.lng),
            L.latLng(geoCodeLocation2.latLng2.lat, geoCodeLocation2.latLng2.lng)
        ]
    }).on('routesfound', function(e){
      if(e.routes[0] != null){
        //console.log(e.routes[0]);
        //console.log(e.routes[0].summary.totalDistance/1000 + "Km");
        //console.log(e.routes[0].summary.totalTime/60 + "Hrs");
        var totalHrs = e.routes[0].summary.totalTime/60;
        var totalMnts = (totalHrs/60).toFixed(1);
          console.log(totalMnts);
        var splitMnt = totalMnts.toString().split('.');
        var onlyHrs = splitMnt[0];
        var onlyMinutes = (parseFloat(splitMnt[1]) * 60);
        $('#distance1').text((e.routes[0].summary.totalDistance/1000).toFixed(1) + " Km, ");
        $('#time1').text(onlyHrs + "h " + Math.floor(onlyMinutes/10) +" Minutes");
        console.log(onlyHrs + "--" + Math.round(onlyMinutes) );
      }
      if(e.routes[1] != null){
        //console.log(e.routes[1]);
        //console.log(e.routes[1].summary.totalDistance/1000 + "Km");
        var totalHrs1 = e.routes[1].summary.totalTime/60;
        var totalMnts1 = (totalHrs1/60).toFixed(1);
        var splitMnt1 = totalMnts1.toString().split('.');
        var onlyHrs1 = splitMnt1[0];
        var onlyMinutes1 = (parseFloat(splitMnt1[1]) * 60);
        $('#distance2').text((e.routes[1].summary.totalDistance/1000).toFixed(1) + " Km, ");
        $('#time2').text(onlyHrs1 + "h " + Math.floor(onlyMinutes1/10) +" Minutes");
        //console.log(onlyHrs + "--" + onlyMinutes );
      }
        
    })
    .addTo(map);
}

loc()
</script>

注意:#item1和#item2是HTML页面上标签的ID。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接