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;
}