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..

4 Answers 4

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';
}
3
  • 1
    Is this driving distance or shortest distance based on an algorithm such as Haversine or Vincenty's?
    – coder101
    Commented Jan 31, 2020 at 14:15
  • 4
    @coder101 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." Commented Feb 10, 2020 at 9:31
  • 1
    It does not return driving distance, it returns numeric distance between the extremes of the bounding rectangle. It's just a simple pythagoras calculation.
    – dresende
    Commented Apr 24, 2023 at 15:20
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.

3
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.

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.