Search code examples
javascriptjsonsortingreact-nativereact-native-listview

How to get the distance between two locations based on their latitude and longitude?


I am trying to display a list based on user distance to each location. The locations are received from Firebase as a JSON.

To get user location, I'm using:

    navigator.geolocation.getCurrentPosition(function(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;

Do you know a way to sort this JSON by distance and list it (having multiple child nodes)?

Thanks.


Solution

  • You have two ways to get the distance between a latitude/longitude to some other latitude/longitude:

    - Using Google API

        function getDistanceOneToOne(lat1, lng1, lat2, lng2)
        {
           const Location1Str = lat1 + "," + lng1;
           const Location2Str = lat2 + "," + lng2;
    
           let ApiURL = "https://maps.googleapis.com/maps/api/distancematrix/json?";
    
           let params = `origins=${Location1Str}&destinations=${Location2Str}&key=${GOOGLE_API_KEY}`; // you need to get a key
           let finalApiURL = `${ApiURL}${encodeURI(params)}`;
    
           let fetchResult =  await fetch(finalApiURL); // call API
           let Result =  await fetchResult.json(); // extract json
    
           return Result.rows[0].elements[0].distance;
        }
    

    This requires network connection on the mobile, but it provide the driving distance(exactly as the driving navigator) PLUS more information (ex, duration to arrive), unlike the second approach which provides the straight distance.

    For the above you need to get a Google Api Key. More info here: Google Maps Api

    - Using Pure Math

    This happens locally on the devices, and it provides the straight distance between two latitudes/longitudes.

    function distance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var theta = lon1-lon2
        var radtheta = Math.PI * theta/180
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist)
        dist = dist * 180/Math.PI
        dist = dist * 60 * 1.1515
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="M") { dist = dist * 0.8684 }
        return dist
    }
    

    Run one of the above for each item and you will get the distance for each. Hope that helps.