Cómo ordenar puntos geográficos según la distancia desde la ubicación actual en Android
Tengo un objeto "Lugar" con una coordenada LatLng para cada uno:
import com.google.android.gms.maps.model.LatLng; public class Place{ public String name; public LatLng latlng; public Restaurant(String name, LatLng latlng) { this.name = name; this.latlng = latlng; } }
y tengo un ArrayList de estos lugares, algo como esto:
- mapa androide de google que encuentra la distancia
- Cómo obtener la ubicación actual de mi dispositivo
- Pasar cadenas entre actividades en android
- ¿Cómo obtener la latitud y longitud actuales sin utilizar el método getLastKnownLocation en Android?
- Ubicación por dirección IP en interiores
ArrayList<Place> places = new ArrayList<Place>(); places.add("Place 1", LatLng(90.0,90.0)); places.add("Place 2", LatLng(93.0,93.0)); places.add("Place 3", LatLng(83.0,92.0)); places.add("Place 4", LatLng(93.0,91.0));
y tengo "mi" LatLng:
LatLng myLocation = new LatLng(10.0,10.0);
¿Cómo puedo clasificar estos objetos de acuerdo a lo más cercano a mí? Gracias por la ayuda
- LocationManager.getLastKnownLocation () return null
- Obtener coordenadas de pantalla por ubicación específica y longitud (android)
- android obtener el nombre de ubicación actual
- ¿Cómo encontrar si un punto GPS se encuentra en un conjunto determinado de inicio y fin ubicación GPS?
- ¿Cómo encontrar distancia (por carretera) entre 2 puntos geográficos en la aplicación de Android?
- Aplicación de Android que muestra lat largo en textViews
- Conversión de valores de latitud / longitud (DMS + Formato de dirección de compás) a valores de punto decimal correspondientes en Android
- Compruebe si la latitud y la longitud están dentro de un círculo
Tomando el algoritmo de esta respuesta de la pregunta publicada por @shieldstroy, que utiliza la Gran Distancia Círculo , tengo este ejemplo trabajando.
Aquí está el 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; } }
Aquí está el código de alto nivel, acabo de poner esto en 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); }
Aquí está la salida del registro:
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
Para calcular la distancia hay diferentes métodos disponibles. Una muy simple es la fórmula de Haversine ( http://rosettacode.org/wiki/Haversine_formula#Java ). Un cálculo más exacto sería la fórmula de Vincenty. Si los dos lugares no están muy lejos, la solución de Haversine es suficiente.
Después de calcular la distancia, sólo tiene que ordenar su matriz con un comparador, como:
Collections.sort(places, new Comparator<Place>() { public int compare(Place p1, Place p2) { return Double.compare(p1.getDistance(), p2.getDistance()); } });
A medida que tiene su ubicación actual, puede ordenar mediante el cálculo de la distancia de conducción (que es más adecuado para lugares como restaurantes) de la siguiente manera,
-
Calcular la distancia a cada objeto
http://maps.googleapis.com/maps/api/directions/json?origin="+yourLat+","+yourLong+"&destination="+toLat+","+toLong+"&sensor=false&mode=DRIVING
-
Una vez que usted calcula cada distancia, aplique un algoritmo de clasificación simple para esas distancias.
- UIautomator cómo obtener el hijo por índice o instancia
- ¿La API de Android 20 permite que los dispositivos compatibles con Bluetooth LE actúen como un dispositivo periférico?