0

I already found some examples how to measure straight line distance between my current GPS location and other locations, but all solutions shows about 100 meters less as real.

First I tried this solution:

private double meterDistanceBetweenPoints(double lat_a, double lng_a, double lat_b, double lng_b) {
    float pk = (float) (180.f/Math.PI);

    double a1 = lat_a / pk;
    double a2 = lng_a / pk;
    double b1 = lat_b / pk;
    double b2 = lng_b / pk;

    double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
    double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
    double t3 = Math.sin(a1) * Math.sin(b1);
    double tt = Math.acos(t1 + t2 + t3);

    return 6366000 * tt;
}

and then another one with DistanceTo:

     double distance;
        Location locationA = new Location("Point A");
        locationA.setLatitude(Lat[position]);
        locationA.setLongitude(Lng[position]);

        Location locationB = new Location("Point B");
        locationB.setLatitude(Act1c);
        locationB.setLongitude(Act2c);

distance = locationA.distanceTo(locationB); 

Everything works fine, but it shows always ca. 100 meters less as the real distance is. And the coordinates are ok.

If I check the same distance on Google map (not road of course, but straight line, with measure tool), it shows me for example 330 m and my android app shows 230m. I tried more locations, alway shows less (instead of Google's 880m android shows me 740m).

Also I checked the distance measure with some online tool http://boulter.com/gps/distance/ and it gives me the same result as android.

But I am measuring the distance in my city, and I know that it is ca. 300m, not 200m, so what can be wrong here? These are short distances, so any Earth elipse can't play role here.

I don't want to use Google Play services, as they need http connection.

I also tried the solution from the link in the answer below:

    double getDistanceFromLatLonInKm(double lat1, double lon1, double lat2, double lon2) {
    int R = 6371; // Radius of the earth in km
    double dLat = deg2rad(lat2-lat1);  // deg2rad below
    double dLon = deg2rad(lon2-lon1);
    double a =
            Math.sin(dLat/2) * Math.sin(dLat/2) +
                    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
                            Math.sin(dLon/2) * Math.sin(dLon/2)
            ;
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double d = R * c; // Distance in km
    return d;
}

private double deg2rad(double deg) {
    return deg * (Math.PI/180);
}

but the same result as all others.

And the last update - same result:

   static final double EARTH_RADIUS = 6371009;
public static double computeDistanceBetween(double lat_a, double lng_a, double lat_b, double lng_b) {
    return computeAngleBetween(lat_a, lng_a, lat_b,lng_b ) * EARTH_RADIUS;
}

static double computeAngleBetween(double lat_a, double lng_a, double lat_b, double lng_b) {
    return distanceRadians(toRadians(lat_a), toRadians(lng_a),
            toRadians(lat_b), toRadians(lng_b));
}

private static double distanceRadians(double lat1, double lng1, double lat2, double lng2) {
    return arcHav(havDistance(lat1, lat2, lng1 - lng2));
}

static double arcHav(double x) {
    return 2 * asin(sqrt(x));
}

static double havDistance(double lat1, double lat2, double dLng) {
    return hav(lat1 - lat2) + hav(dLng) * cos(lat1) * cos(lat2);
}

static double hav(double x) {
    double sinHalf = sin(x * 0.5);
    return sinHalf * sinHalf;
}
Darksymphony
  • 2,155
  • 30
  • 54
  • i dont see any problem if its always 100 meters less (compared to your measurements) – pskink Feb 25 '18 at 16:49
  • @pskink, that's what I thought too, until I saw that it's off by 140 as well. wotan, it might be your equation that's off, I think there are multiple ways to calculate it, check [this](https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula) – SQLiteNoob Feb 25 '18 at 16:52
  • That looks like the haversine formula, and in all the instances of it I've googled the constant for radius of the earth is given as either 6373km or 6371km. You have 6366km. Try one of these other values and see if that brings your results in line with google maps's answer. – Ben P. Feb 25 '18 at 17:10
  • well, see my updated question, the last solution uses 6371, but this didn't help. Now I started to be unsure, if the Google measure distance is correct, or these solutions – Darksymphony Feb 25 '18 at 17:13
  • try [SphericalUtil](https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/SphericalUtil.java), btw it says that: `static final double EARTH_RADIUS = 6371009;` – pskink Feb 25 '18 at 18:40
  • yeah, but that seems to require google services, I think I will stay by my used solutions now, I will do some testing also in terrain. If all these solutions gives the same result (also tried on other phone), then probably it is ok. At least untill I find some better solution. – Darksymphony Feb 25 '18 at 18:54
  • 1
    did you try `SphericalUti` i posted a link to? you dont know what method to use? – pskink Feb 25 '18 at 18:57
  • Leave the GPS out of it and get 2 coordinates from google maps and run them through your code. –  Feb 26 '18 at 01:20
  • if I am not wrong, that SphericalUtil requires google maps services to include, that I wanted to avoid. @Andy: I tried to compare fixed coordinates, and it gave me the same result, maybe 20m more, but that can be the GPS issue. So the distance calculating seems working as expected, but the issue is that it is different as google shows on the map. – Darksymphony Feb 26 '18 at 07:19
  • where in `computeDistanceBetween()` method maps services are required? – pskink Feb 26 '18 at 07:22
  • it is using LatLng from, LatLng to, and this requires to import this: import com.google.android.gms.maps.model.LatLng. And I am working on a offline app. – Darksymphony Feb 26 '18 at 07:23
  • cannot you simply replace it with `"whatever location object you are using"`? – pskink Feb 26 '18 at 07:24
  • well, was not sure if I can do this, sorry, I am kind of newbie in this locations area. In this case I will try it today, will see how it works – Darksymphony Feb 26 '18 at 07:27
  • seems, there are more issues that can't be resolved - in computeDistanceBetween is called computeAngleBetween, in computeAngleBetween is called distanceRadians and inside are arcHav(havDistance...also there is toRadians.. these are unknown and can't be resolved – Darksymphony Feb 26 '18 at 08:05
  • they all are taken from `com.google.maps.android.MathUtil` small utility class – pskink Feb 26 '18 at 08:08
  • I see, but then the external com.google.maps.android.MathUtil import is needed, which I suppose can't work if my app is going to be offline app. But for now I will try it, I am curious if it will change the result. – Darksymphony Feb 26 '18 at 08:19
  • yes, so now I imported static java.lang.Math.*; and added some required methods from google MathUtil, so not directly importing anything from google to my app - see my updated question. So I used the code from SphericalUtil. The result is the same as all other solutions gave me... – Darksymphony Feb 26 '18 at 08:29
  • 1
    take those two locations: 37.825534, -122.479400, and 37.814147, -122.478038, the distance between should be 1270-1280 (depending if measuring the centers of gates or just ends), what does the algorithm say? if you dont believe, check on the maps where those two locations are... – pskink Feb 26 '18 at 09:04
  • my result shows 1271,81.Seems correct! I think maybe I found the issue - when I right click on a place on Google map, What is here, it shows the correct coordinates at the bottom, but then if I click on them, in URL the coordinates are a little different - seems google jumps to the nearest place and I used those from URL. When I tried to use the exact ones, now in my case the app shows 323m and google measure 330m. So this solves the issue. Thanks all for your valuable advices, at least we have more possibilities on one place how to calculate the distance, maybe can be usefull for someone too. – Darksymphony Feb 26 '18 at 11:21

0 Answers0