I have a \"Place\" object with a LatLng coordinate for each:
import com.google.android.gms.maps.model.LatLng;
public class Place{
public String name;
you can use the
distanceInMeters = (loc1.distanceTo(loc2));
from google maps API and then add the results to the Key in a TreeMap
For calculating the distance there are different methods available. A quite simple one is the Haversine Formula (http://rosettacode.org/wiki/Haversine_formula#Java). A more accurate calculation would be the Vincenty Formula. If the two locations are not far away, the Haversine solution is quite sufficient.
After calculating the distance, you just sort your array using a comparator, like:
Collections.sort(places, new Comparator<Place>() {
public int compare(Place p1, Place p2) {
return Double.compare(p1.getDistance(), p2.getDistance());
}
});
As you got your current location, You can sort by calculating the driving distance (which is most suitable for places like restaurants ) as follows,
Calculate the distance to each object
http://maps.googleapis.com/maps/api/directions/json?origin="+yourLat+","+yourLong+"&destination="+toLat+","+toLong+"&sensor=false&mode=DRIVING
Once you calculate each distance , apply some simple sorting algorithm for those distances.
Taking the algorithm from this answer from the question posted by @shieldstroy, that uses the Great Circle Distance, I got this example working.
Here is the Comparator
:
public class SortPlaces implements Comparator<Place> {
LatLng currentLoc;
public SortPlaces(LatLng current){
currentLoc = current;
}
@Override
public int compare(final Place place1, final Place place2) {
double lat1 = place1.latlng.latitude;
double lon1 = place1.latlng.longitude;
double lat2 = place2.latlng.latitude;
double lon2 = place2.latlng.longitude;
double distanceToPlace1 = distance(currentLoc.latitude, currentLoc.longitude, lat1, lon1);
double distanceToPlace2 = distance(currentLoc.latitude, currentLoc.longitude, lat2, lon2);
return (int) (distanceToPlace1 - distanceToPlace2);
}
public 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;
}
}
Here is the high level code, I just put this in onCreate()
:
//My location, San Francisco
double lat = 37.77657;
double lng = -122.417506;
LatLng latLng = new LatLng(lat, lng);
//set up list
ArrayList<Place> places = new ArrayList<Place>();
places.add(new Place("New York", new LatLng(40.571256,73.98369)));
places.add(new Place("Colorado", new LatLng(39.260658,-105.101615)));
places.add(new Place("Los Angeles", new LatLng(33.986816,118.473819)));
for (Place p: places){
Log.i("Places before sorting", "Place: " + p.name);
}
//sort the list, give the Comparator the current location
Collections.sort(places, new SortPlaces(latLng));
for (Place p: places){
Log.i("Places after sorting", "Place: " + p.name);
}
Here is the log output:
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: New York
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: Colorado
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places before sorting﹕ Place: Los Angeles
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: Los Angeles
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: Colorado
04-17 23:04:16.074 12963-12963/com.maptest.daniel.maptest I/Places after sorting﹕ Place: New York