Calculate distance between two points in Leaflet
Asked Answered
I

4

23

How do you calculate the distance between two markers in Leaflet-ionic2?

Couldn't figure out, I hope there is an Algorithme to do as soon as i select a marker it show me the distance between my location and the marker.

Thanks..

Indemnify answered 2/4, 2017 at 10:47 Comment(0)
S
25

The Leaflet manual mentions the distanceTo function, which calculates the distance ~~in meters~~ (numeric distance, it's not metric). This distance is between NE and SW points of bounding, no driving/walking distance is calculated, just direct distance using a single line joining these 2 extremes.

Example plagiarized from Google Groups:

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';
}
Splotch answered 20/2, 2019 at 3:50 Comment(3)
Is this driving distance or shortest distance based on an algorithm such as Haversine or Vincenty's?Sac
@Sac How could it be driving distance? You should have read the manual. "Returns the distance (in meters) to the given LatLng calculated using the Spherical Law of Cosines."Dielle
It does not return driving distance, it returns numeric distance between the extremes of the bounding rectangle. It's just a simple pythagoras calculation.Renaud
A
20

You can use this function to find distance between 2 positions.

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])

We are using this function in our library time-aware-polyline to encode lat lng info with timestamp.

Antiphlogistic answered 4/4, 2017 at 13:7 Comment(3)
Should be [lat1, lng1], [lat2, lng2] instead of [lat1, lng2], [lat2, lng2]Turnsole
I love you. I do really. Lol Thanks dude. Not a chance in hell I could have came up with this.Invariable
github.com/hypertrack/time-aware-polyline-js is 404Entopic
F
0

Calculated distance, time for two address with geocoding and if the leflet map provide you two routes you can collect info for both of the routes consider the code below. you need to include following packages

<script src="https://unpkg.com/[email protected]/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>

Note: #item1 and #item2 are id for label on the html page.

Frontward answered 24/12, 2022 at 12:54 Comment(0)
G
0

There is a distance method on the map object that takes two [lat, long] parameters and returns a distance between them in meters.

For example:

const getDistanceInKm = (map, cordsFrom, cordsTo) =>
  map.distance(cordsFrom, cordsTo).toFixed(0);

docs

Gangboard answered 9/6 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.