I'm working on an Android app that uses Geopoints and I want to determinate a Geopoint from another Geopoint, a distance (in any format) and a polar angle. For example, I want to get coordinates of a place 100 meters in the North-North-East (22,5 degres) of my location got by the GPS in my phone.
The only method I've found is Location.distanceBetween(...).
Implementation for Android. This code is great for Unit Testing in your aplication:
public double radiansFromDegrees(double degrees)
{
return degrees * (Math.PI/180.0);
}
public double degreesFromRadians(double radians)
{
return radians * (180.0/Math.PI);
}
public Location locationFromLocation(Location fromLocation, double distance, double bearingDegrees)
{
double distanceKm = distance / 1000.0;
double distanceRadians = distanceKm / 6371.0;
//6,371 = Earth's radius in km
double bearingRadians = this.radiansFromDegrees(bearingDegrees);
double fromLatRadians = this.radiansFromDegrees(fromLocation.getLatitude());
double fromLonRadians = this.radiansFromDegrees(fromLocation.getLongitude());
double toLatRadians = Math.asin( Math.sin(fromLatRadians) * Math.cos(distanceRadians)
+ Math.cos(fromLatRadians) * Math.sin(distanceRadians) * Math.cos(bearingRadians) );
double toLonRadians = fromLonRadians + Math.atan2(Math.sin(bearingRadians)
* Math.sin(distanceRadians) * Math.cos(fromLatRadians), Math.cos(distanceRadians)
- Math.sin(fromLatRadians) * Math.sin(toLatRadians));
// adjust toLonRadians to be in the range -180 to +180...
toLonRadians = ((toLonRadians + 3*Math.PI) % (2*Math.PI) ) - Math.PI;
Location result = new Location(LocationManager.GPS_PROVIDER);
result.setLatitude(this.degreesFromRadians(toLatRadians));
result.setLongitude(this.degreesFromRadians(toLonRadians));
return result;
}
Take a look at great-circle formulas: http://en.wikipedia.org/wiki/Great-circle_distance
This should give You some hints on how to calculate the distances.
For a point in a given distance and heading, check http://williams.best.vwh.net/avform.htm#LL
Those formulas look quite complicated, but are easy to implement ;)
Related
I'm writing an Android app and integrating GoogleMapsV2 API. I have a series of markers on the map at various locations around an anchor.
I want those markers to converge on the anchor's position incrementally.
I've got a loop running that will call each marker B and from B's position calculate the bearing to the anchor A. I then calculate the destination coordinate for a fixed distance along that bearing and update.
Here are the two functions (taken from an amalgamation of stack posts and a GeoMapping site, for full disclosure) I'm using:
public double calcBearing(double lat1, double lon1, double lat2, double lon2){
double longitude1 = lon1;
double longitude2 = lon2;
double latitude1 = Math.toRadians(lat1);
double latitude2 = Math.toRadians(lat2);
double longDiff= Math.toRadians(longitude2-longitude1);
double y= Math.sin(longDiff)*Math.cos(latitude2);
double x=Math.cos(latitude1)*Math.sin(latitude2)-Math.sin(latitude1)*Math.cos(latitude2)*Math.cos(longDiff);
double calcBearing = (Math.toDegrees(Math.atan2(y, x))+360)%360;
return calcBearing;
}
public Coordinate calcCoordFromPointBearing(double lat1, double lon1, double bearing, double distance){
double rEarth = 6371.01; // Earth's average radius in km
double epsilon = 0.000001; // threshold for floating-point equality
double rLat1 = deg2rad(lat1);
double rLon1 = deg2rad(lon1);
double rbearing = deg2rad(bearing);
double rdistance = distance / rEarth;
double rlat = Math.asin( Math.sin(rLat1) * Math.cos(rdistance) + Math.cos(rLat1) * Math.sin(rdistance) * Math.cos(rbearing) );
double rlon;
if (Math.cos(rlat) == 0 || Math.abs(Math.cos(rlat)) < epsilon) // Endpoint a pole
rlon=rLon1;
else
rlon = ( (rLon1 - Math.asin( Math.sin(rbearing)* Math.sin(rdistance) / Math.cos(rlat) ) + Math.PI ) % (2*Math.PI) ) - Math.PI;
double lat = rad2deg(rlat);
double lon = rad2deg(rlon);
return new Coordinate(lat,lon);
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
private double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
In short, I've screwed up the above calculations I believe. The behavior I'm seeing is the markers moving erratically and with a high frequency ending up heading towards two bearings: 90 and 270. As a result, they tend to move away from my anchor instead of towards it.
Can someone help me spot the mistake? I am passing in degrees to both the bearing function and the coordinate calculation function, but I'm converting them immediately to radians for the algorithm and back to degrees for usage elsewhere.
[UPDATE:
Most of the code came from this example:
Calculating coordinates given a bearing and a distance
It looks to me that the output longitude is being normalized to -180 to 180, which I'm plotting on a 360 degree space causing the outputs to head to the bearings 90 and 270. Any suggestions on the trig math change required to fix this?]
probably needs 360.0
double calcBearing = (Math.toDegrees(Math.atan2(y, x))+360.0)%360.0;
This was kindof answered here
You still have another issue. Your not considering any tilt in the map. Why not just animate with the pixels. There won't be too much distortion of curvature. What you have to do is get the pixel position of the marker. You'll have to save the latlon when adding the marker or you have to add the markers with .setAnchor which gives you an offset in pixels. If you have the latlon of the marker placement then you get the point by.
LatLon ll;
Point p = mMap.getProjection().toScreenLocation(ll);
Then you can use code like this to animate the markers. I'm making a marker bounce below by interpolating the y axis. You'll have to interpolate both axi.
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long duration = 2500;
final Interpolator interpolator = new BounceInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = Math.max(
1 - interpolator.getInterpolation((float) elapsed
/ duration), 0);
marker.setAnchor(0.5f, 1.0f + 6 * t);
if (t > 0.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
The above code is from this question. I apologize for any performance issues you have when you use the above method. But you could still use the pixel positions for a more traditional animation approach.
I've got almost the same formulas as you working in another program where I animate a map to move to the expected location based on a location bearing and speed. The formula is slightly different at the end than yours. I lifted it from here and changed to longer names.
// Define the callback method that receives location updates
#Override
public void onLocationChanged(Location location) {
// Given the bearing, speed, and current location
// calculate what the expected location is traveling for an
// interval that is slightly larger than two times fastest interval of
// the location provider and animate the map movement to the
// expected location over the same slightly larger interval.
// In Theory by using an interval that is slightly larger
// than two times fastest interval of the location provider for the
// animation length a new animation will start before the
// currently running animation finishes. This should ensure a
// smooth animation of the map while traveling under most
// circumstances.
// Negative acceleration (braking)
// should have acceptable map animation because the map
// animation in theory never finishes.
// Note longer intervals, large negative accelerations, just
// braking at the start of an interval may result in the map moving
// backwards. But it will still be animated.
// Some handhelds might not be able to keep up
// TODO CHECK THE age of the location
// location.getSpeed() =meters/second
// interval 1/1000 seconds
// distance in radians km/6371
// changed.
// (location.getSpeed()m/s)(1/1000 interval seconds)( 1/1000 km/m)
// (1/6371 radians/km) = radians/6371000000.0
double expectedDistance = location.getSpeed() * expectedDistMultiplier;
// latitude in Radians
double currentLatitude = Math.toRadians(location.getLatitude());
// longitude in Radians
double longitude1 = Math.toRadians(location.getLongitude());
double bearing;
bearing = (location.hasBearing()) ? Math.toRadians(location
.getBearing()) : 0;
// calculate the expected latitude and longitude based on staring
// location
// , bearing, and distance
double expectedLatitude = Math.asin(Math.sin(currentLatitude)
* Math.cos(expectedDistance) + Math.cos(currentLatitude)
* Math.sin(expectedDistance) * Math.cos(bearing));
double a = Math.atan2(
Math.sin(bearing) * Math.sin(expectedDistance)
* Math.cos(currentLatitude),
Math.cos(expectedDistance) - Math.sin(currentLatitude)
* Math.sin(expectedLatitude));
double expectedLongitude = longitude1 + a;
expectedLongitude = (expectedLongitude + 3 * Math.PI) % (2 * Math.PI)
- Math.PI;
// convert to degrees for the expected destination
double expectedLongitudeDestination = Math.toDegrees(expectedLongitude);
double expectedLatitudeDestination = Math.toDegrees(expectedLatitude);
// log everything for testing.
Log.d("Location", "Bearing in radians" + bearing);
Log.d("Location", "distance in km" + expectedDistance);
Log.d("Location", "Current Latitude = " + location.getLatitude()
+ " Current Longitude = " + location.getLongitude());
Log.d("Location", "New Latitude = " + expectedLatitudeDestination
+ " New Longitude = " + expectedLongitudeDestination);
// build a camera update to animate positioning map to the expected
// destination
LatLng ll = new LatLng(expectedLatitudeDestination,
expectedLongitudeDestination);
CameraPosition.Builder cb = CameraPosition.builder()
.zoom(mMap.getCameraPosition().zoom)
.bearing(mMap.getCameraPosition().bearing)
.tilt(mMap.getCameraPosition().tilt).target(ll);
if (location.hasBearing()) {
cb.bearing(location.getBearing());
}
CameraPosition camera = cb.build();
CameraUpdate update = CameraUpdateFactory.newCameraPosition(camera);
mMap.animateCamera(update, interval, this);
}
I'm also try to draw arc (I'm referencing on this and this questions). I'll get from web service following:
Lat and Lng
Radius (in meters)
Start angle (end angle is startA + 60 degrees)
Now I encounter on following problem because I do not have two LatLng, just one, and in new map api v2 there is no radius = Projection.metersToEquatorPixels method for providing to RectF.set(point.x - radius,...)
Do you have code example, links, etc?
Also what about performances of App, because I'll have up to 500 arcs on map?
Starting from a LatLng point you can calculate another LatLng point in a given distance (radius) and a given angle as follows:
private static final double EARTHRADIUS = 6366198;
/**
* Move a LatLng-Point into a given distance and a given angle (0-360,
* 0=North).
*/
public static LatLng moveByDistance(LatLng startGp, double distance,
double angle) {
/*
* Calculate the part going to north and the part going to east.
*/
double arc = Math.toRadians(angle);
double toNorth = distance * Math.cos(arc);
double toEast = distance * Math.sin(arc);
double lonDiff = meterToLongitude(toEast, startGp.latitude);
double latDiff = meterToLatitude(toNorth);
return new LatLng(startGp.latitude + latDiff, startGp.longitude
+ lonDiff);
}
private static double meterToLongitude(double meterToEast, double latitude) {
double latArc = Math.toRadians(latitude);
double radius = Math.cos(latArc) * EARTHRADIUS;
double rad = meterToEast / radius;
double degrees = Math.toDegrees(rad);
return degrees;
}
private static double meterToLatitude(double meterToNorth) {
double rad = meterToNorth / EARTHRADIUS;
double degrees = Math.toDegrees(rad);
return degrees;
}
I have a little project I've been playing with (Android, GPS, mapping APIs), and I need to figure how to find a longitude/latitude/GeoPoint from a given longitude/latitude/GeoPoint with only knowing the meters/km longitude and latitude. e.g. I want to figure out where a point is from me, that I know is +1000 meters along the longitude and +1000 along the latitude.
It's a little different than the usual GeoPoint/distance questions you'll see, and it's not quite geo fencing radius related as the distance is X,Y meters/kms, and I don't have a bearing. (I could work out a bearing, but I don't have a suitable direct distance)
Basically, if I could reverse GeoPoint.distanceTo() it would do the job for me.
Update
Just a little more background. I'm basically applying a node triangulation idea I had, but the algorithm requires that my inputs be in a map normalized form that's not the same as longitude and latitude. I create a map/grid where 0,0 (the bottom/left) is the left/west and bottom/south most longitude/latitude values from the nodes I'm working with. All the other node X/Y on the map are determined by finding their meters from the 0,0 node's longitude/latitude using GeoPoint.distanceTo(). (note that I find their X/Y by performing distanceTo twice for each node so I have the X and Y meters from 0,0, not a direct line to the node) That distance in meters is fed into the algorithm and new X/Y map points are produced.
And so I need to figure out how to convert distance from a longitude/latitude into another, previously unknown, longitude/latitude.
double startPointLongitude = 23.459821;
double startPointLatitude = 76.998200;
double distanceLongitude = 100; // 100 meters along the longitude
double distanceLatitude = 75; // 75 meters along the latitude
Basically i took the Answer from AlexWien, corrected two things and made it into a java method
private static final double WGS84_RADIUS = 6370997.0;
private static double EarthCircumFence = 2* WGS84_RADIUS * Math.PI;
private static Position getPosition(Position sourcePosition, double mEastWest, double mNorthSouth){
double degreesPerMeterForLat = EarthCircumFence/360.0;
double shrinkFactor = Math.cos((sourcePosition.getLat()*Math.PI/180));
double degreesPerMeterForLon = degreesPerMeterForLat * shrinkFactor;
double newLat = sourcePosition.getLat() + mNorthSouth * (1/degreesPerMeterForLat);
double newLng = sourcePosition.getLng() + mEastWest * (1/degreesPerMeterForLon);
return new Position(newLat, newLng);
}
The distance between two degrees of latitude never change, it is always aprox. 111 km
(The exact value you should caculate by using the WGS84 Earth radius:
EarthCircumFence = 2* WGS84_RADIUS * Math.Pi;
metersPerDegree = (Earth Cirumfence / 360)
With this info you easily can calculate the latitude offset,
just reverse the factor and have:
degreesPerMeterForLat = EarthCircumfenceMeter / 360.0
with longitude its a bit different, the distance between two degrees of longitude shrink
the more you move away from aequator.
shrinkFactor = cos(toRadians(locationLatitude));
compensate now:
degreesPerMeterForLon = degreesPerMeterForLat / shrinkFactor;
Finally
newLatPos = latOld + numMeters * degreesPerMeterForLat;
newLonPos = lonOld + numMeters * degreesPerMeterForLon;
This works for distance offset < 10 - 50 km
Sigh, I posted this like 6 hours ago but it does not appear to have gone through.
Ok, worked it out in spite of most geographical formulas and facts occasionally going over my head. Working with geography is like working with the Gregorian calendar, it makes sense if you program for it all the time, but otherwise it's easy to get confused by an incorrect assumption.
The following except from my app will take a starting GeoPoint's long/lat
/**
* the length of one degree of latitude (and one degree of longitude at equator) in meters.
*/
private static final double DEGREE_DISTANCE_AT_EQUATOR = 111329;
/**
* calculates the x,y in meters from a given starting point's long0, lat0 to a target destination point's long1, lat1.
* #param long0 start point longitude
* #param lat0 start point latitude
* #param long1 end point longitude
* #param lat1 end point latitude
* #return
*/
public static Pair<Double, Double> xyFromLongLat(int long0, int lat0, int long1, int lat1) {
double x = (long1 / 1E6 - long0 / 1E6) * longitudeDistanceAtLatitude(lat0 / 1E6);
double y = (lat1 / 1E6 - lat0 / 1E6) * DEGREE_DISTANCE_AT_EQUATOR;
return new Pair<Double, Double>(x, y);
}
/**
* calculates longitude and latitude from a given starting point, with only the X/Y meters
* #param long0
* #param lat0
* #param x
* #param y
* #return
*/
public static Pair<Double, Double> longLatFromXY(int long0, int lat0, double x, double y) {
double lat1 = (y / DEGREE_DISTANCE_AT_EQUATOR) + (lat0 / 1E6);
double long1 = x / longitudeDistanceAtLatitude(lat0) + (long0 / 1E6);
return new Pair<Double, Double>(lat1, long1);
}
please shed some light on this situation
Right now i have two array having latitude and longitude of nearby places and also have the user location latiude and longiude now i want to calculate the distance between user location and nearby places and want to show them in listview.
I know that there is a method for calculating distance as
public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results);
Now what is the problem is how to pass these two array having nearby latitude and longitue in this method and get the array of distances.
http://developer.android.com/reference/android/location/Location.html
Look into distanceTo
Returns the approximate distance in meters between this location and
the given location. Distance is defined using the WGS84 ellipsoid.
or distanceBetween
Computes the approximate distance in meters between two locations, and
optionally the initial and final bearings of the shortest path between
them. Distance and bearing are defined using the WGS84 ellipsoid.
You can create a Location object from a latitude and longitude:
Location locationA = new Location("point A");
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB);
locationB.setLongitude(lngB);
float distance = locationA.distanceTo(locationB);
or
private double meterDistanceBetweenPoints(float lat_a, float lng_a, float lat_b, float lng_b) {
float pk = (float) (180.f/Math.PI);
float a1 = lat_a / pk;
float a2 = lng_a / pk;
float b1 = lat_b / pk;
float 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;
}
Try This Code. here we have two longitude and latitude values and selected_location.distanceTo(near_locations) function returns the distance between those places in meters.
Location selected_location = new Location("locationA");
selected_location.setLatitude(17.372102);
selected_location.setLongitude(78.484196);
Location near_locations = new Location("locationB");
near_locations.setLatitude(17.375775);
near_locations.setLongitude(78.469218);
double distance = selected_location.distanceTo(near_locations);
here "distance" is distance between locationA & locationB (in Meters)
There is only one user Location, so you can iterate List of nearby places can call the distanceTo() function to get the distance, you can store in an array if you like.
From what I understand, distanceBetween() is for far away places, it's output is a WGS84 ellipsoid.
private static Double _MilesToKilometers = 1.609344;
private static Double _MilesToNautical = 0.8684;
/// <summary>
/// Calculates the distance between two points of latitude and longitude.
/// Great Link - http://www.movable-type.co.uk/scripts/latlong.html
/// </summary>
/// <param name="coordinate1">First coordinate.</param>
/// <param name="coordinate2">Second coordinate.</param>
/// <param name="unitsOfLength">Sets the return value unit of length.</param>
public static Double Distance(Coordinate coordinate1, Coordinate coordinate2, UnitsOfLength unitsOfLength)
{
double theta = coordinate1.getLongitude() - coordinate2.getLongitude();
double distance = Math.sin(ToRadian(coordinate1.getLatitude())) * Math.sin(ToRadian(coordinate2.getLatitude())) +
Math.cos(ToRadian(coordinate1.getLatitude())) * Math.cos(ToRadian(coordinate2.getLatitude())) *
Math.cos(ToRadian(theta));
distance = Math.acos(distance);
distance = ToDegree(distance);
distance = distance * 60 * 1.1515;
if (unitsOfLength == UnitsOfLength.Kilometer)
distance = distance * _MilesToKilometers;
else if (unitsOfLength == UnitsOfLength.NauticalMiles)
distance = distance * _MilesToNautical;
return (distance);
}
distanceTo will give you the distance in meters between the two given location ej target.distanceTo(destination).
distanceBetween give you the distance also but it will store the distance in a array of float( results[0]). the doc says If results has length 2 or greater, the initial bearing is stored in results[1]. If results has length 3 or greater, the final bearing is stored in results[2]
hope that this helps
i've used distanceTo to get the distance from point A to B i think that is the way to go.
public double distance(Double latitude, Double longitude, double e, double f) {
double d2r = Math.PI / 180;
double dlong = (longitude - f) * d2r;
double dlat = (latitude - e) * d2r;
double a = Math.pow(Math.sin(dlat / 2.0), 2) + Math.cos(e * d2r)
* Math.cos(latitude * d2r) * Math.pow(Math.sin(dlong / 2.0), 2)
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = 6367 * c;
return d;
}
I wanted to implement myself this, i ended up reading the Wikipedia page on Great-circle distance formula, because no code was readable enough for me to use as basis.
C# example
/// <summary>
/// Calculates the distance between two locations using the Great Circle Distance algorithm
/// <see cref="https://en.wikipedia.org/wiki/Great-circle_distance"/>
/// </summary>
/// <param name="first"></param>
/// <param name="second"></param>
/// <returns></returns>
private static double DistanceBetween(GeoLocation first, GeoLocation second)
{
double longitudeDifferenceInRadians = Math.Abs(ToRadians(first.Longitude) - ToRadians(second.Longitude));
double centralAngleBetweenLocationsInRadians = Math.Acos(
Math.Sin(ToRadians(first.Latitude)) * Math.Sin(ToRadians(second.Latitude)) +
Math.Cos(ToRadians(first.Latitude)) * Math.Cos(ToRadians(second.Latitude)) *
Math.Cos(longitudeDifferenceInRadians));
const double earthRadiusInMeters = 6357 * 1000;
return earthRadiusInMeters * centralAngleBetweenLocationsInRadians;
}
private static double ToRadians(double degrees)
{
return degrees * Math.PI / 180;
}
I have location from GPS (lon_base, lat_base).
I have a list of locations (lon1, lat1|lon2, lat2|lon3, lat3...)
This list is very long and is around the world.
My questions are:
1. How do I get from that list only the lon\lat that are 1 mile from my lon_base\lat_base?
2. How do I sort them from closest to farthest?
Thanks in advance!
public static List<Location> sortLocations(List<Location> locations, final double myLatitude,final double myLongitude) {
Comparator comp = new Comparator<Location>() {
#Override
public int compare(Location o, Location o2) {
float[] result1 = new float[3];
android.location.Location.distanceBetween(myLatitude, myLongitude, o.Lat, o.Long, result1);
Float distance1 = result1[0];
float[] result2 = new float[3];
android.location.Location.distanceBetween(myLatitude, myLongitude, o2.Lat, o2.Long, result2);
Float distance2 = result2[0];
return distance1.compareTo(distance2);
}
};
Collections.sort(locations, comp);
return locations;
}
Where the List of Locations is a list containing your own Location class, not the android.location.Location.
You may use the great circle distance to calculate the distance between two points whose you know the latitude-longitude coordinates. The formulae are quite easy to code:
static double distance(double fromLat, double fromLon, double toLat, double toLon) {
double radius = 6378137; // approximate Earth radius, *in meters*
double deltaLat = toLat - fromLat;
double deltaLon = toLon - fromLon;
double angle = 2 * Math.asin( Math.sqrt(
Math.pow(Math.sin(deltaLat/2), 2) +
Math.cos(fromLat) * Math.cos(toLat) *
Math.pow(Math.sin(deltaLon/2), 2) ) );
return radius * angle;
}
You want to define your own Comparator that, in general, looks something like this:
LonLat myHouse = /* whatever */ ;
Comparable comp = new Comparable () {
LonLat a;
int compareTo (Object b) {
int aDist = calcDistance(a, myHouse) ;
int bDist = calcDistance(b, myHouse) ;
return aDist - bDist;
}
};
myLonLatList.sort(lonLatList, comp);
where calcDistance() simply calculates the distance between the two points. If you're on Android, I think Google Maps has a function somewhere in their API that will do this for you.
EDIT : You'll want your calcDistance() function to look like ChrisJ's distance function.
-tjw
You can use followig approximation (since 1 mile is much smaller than the radius of the earth) to calculate the distances from your base:
dx = cos(phi_base) * (theta - theta_base)
dy = phi - phi_base
dist = sqrt(dx*dx+dy*dy)
with: phi = latitude and theta = longitude
The result is in units of 60 nautical miles if theta and phi are given in degrees.
The results will be quite wrong for points that have a latitude that is much different from your base latitude, but this doesn't matter if you just want to know wich points are about 1 mile from your base.
For most programming languages you have to convert phi_base to radians (multiply by pi/180) in order to use it for cos().
(Attention: You have to take special care if your base longitude is very close to 180° or -180°, but probably that is not the case :-)
Use the calculated distances as sorting key to sort your points.
If you have to be more exact (e.g. if you want to know all points that are about 2000 miles from your home), than you must use the formula for Great Circle Distance to calculate the exact distance of two points on a sphere.
According to this link
i made working method. The answer above was wrong, because it doesn't convert lat/lng degrees to radians.
private double getDistance(double fromLat, double fromLon, double toLat, double toLon){
double radius = 6371; // Earth radius in km
double deltaLat = Math.toRadians(toLat - fromLat);
double deltaLon = Math.toRadians(toLon - fromLon);
double lat1 = Math.toRadians(fromLat);
double lat2 = Math.toRadians(toLat);
double aVal = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
Math.sin(deltaLon/2) * Math.sin(deltaLon/2) * Math.cos(lat1) * Math.cos(lat2);
double cVal = 2*Math.atan2(Math.sqrt(aVal), Math.sqrt(1-aVal));
double distance = radius*cVal;
Log.d("distance","radius * angle = " +distance);
return distance;
}