Calculate distance between two GeoLocation

1.6k views Asked by At

I am trying to calculate the distance between two Geo Locations. The problem I have is the following: I tried with libraries like :Geocalc and Haversine formulas, like this:

public static final double RKilometers = 6371;

public static double calculationByDistance(double lat1, double lon1, double lat2, double lon2) {
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);

    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    double c = 2 * Math.asin(Math.sqrt(a));
    return RKilometers * c;
}

But I get the same wrong values with all those options. For short distances it works perfectly, but for long distances it doesn´t.

This is the test I did:

//distance between Barrow Island(Australia) and Tavatave(Madagascar)
assertEquals(calculationByDistance(20.82, 115.4, 18.15, 49.4), 6885, 20);
//get 6875.965169284442

//here is the problem
//distance between Rio Grande and Glasgow
assertEquals(calculationByDistance(32.05, 52.11, 55.83, 4.25), 10744, 20);
//get 4522.502442756569

Does someone know where is my error? Thank you!

4

There are 4 answers

0
IrApp On BEST ANSWER

I found the error. The problem was the values for latitud and longitud were wrong. I took the data from Wolframalpha and they don´t show the signs for the values. The rights values for my test are:

assertEquals(calculationByDistance(-32.05, 52.11, 55.83, -4.25), 10744, 20); 

Thank you for your time!!!And sorry for the stupid error :)

2
nafas On

I had this code from a long ago, I don't even remember if I wrote it myself or got it off someone. as far as I remember it gives a pretty good estimate, you can try it out and see if it works for you. (edits are welcomed)

public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
        double earthRadius = 3958.75;  //this is in miles I believe
        double dLat = Math.toRadians(lat2-lat1);
        double dLng = Math.toRadians(lng2-lng1);
        double sindLat = Math.sin(dLat / 2);
        double sindLng = Math.sin(dLng / 2);
        double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
                * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        double dist = earthRadius * c;

        return dist;
}
0
flaz14 On

It is hard to propose you any code snippet or existing tools and services. Just because calculating distance depends on the certain task. There are many kinds of map projections and corresponding formulas.

For example, if you are using Google maps you probably can do more precise calculation taking into account height differences. OpenStreetMap, for instance, doesn't provide (at least a couple years ago) any height info, so your precision can vary (compare precision achieved using OpenStreetMap for 'flat' city in Eastern Europe and San Francisco, for example).

I've got satisfied with https://code.google.com/p/simplelatlng/. It is really simple and saves you from writing boilerplate code.

For long distances specific web services can do good job (especially when service aggregates data from the several other services).

0
user6031720 On
public static float distFrom(float lat1, float lng1, float lat2, float lng2) 
{
    // Earth Radius in meters

    double earthRadius = 6371000; 
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) *
               Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    float dist = (float) (earthRadius * c);

    System.out.println("Distance is : " + dist);
    return dist; // distance in meters
}