How to Sort Geo-points according to the distance from current location in Android

前端 未结 4 1963
星月不相逢
星月不相逢 2020-12-04 20:44

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;
           


        
相关标签:
4条回答
  • 2020-12-04 20:58

    you can use the

    distanceInMeters = (loc1.distanceTo(loc2));
    

    from google maps API and then add the results to the Key in a TreeMap

    0 讨论(0)
  • 2020-12-04 20:59

    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());
        }
    });
    
    0 讨论(0)
  • 2020-12-04 20:59

    As you got your current location, You can sort by calculating the driving distance (which is most suitable for places like restaurants ) as follows,

    1. Calculate the distance to each object

      http://maps.googleapis.com/maps/api/directions/json?origin="+yourLat+","+yourLong+"&destination="+toLat+","+toLong+"&sensor=false&mode=DRIVING
      
    2. Once you calculate each distance , apply some simple sorting algorithm for those distances.

    0 讨论(0)
  • 2020-12-04 21:03

    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
    
    0 讨论(0)
提交回复
热议问题