Obtenir la distance entre deux points géo
je veux faire une application qui vérifie ce qui est l'endroit le plus proche d'où l'utilisateur est. Je peux facilement obtenir l'emplacement de l'utilisateur et j'ai une liste d'endroits avec la latitude et la longitude.
quelle serait la meilleure façon de connaître l'endroit le plus proche de la liste par rapport à la position actuelle.
Je n'ai rien trouvé dans l'API google.
je suis inquiet je dois recourir à mon calcul et doivent faire des maths pour la calculer.
qu'en pensez-vous ?
Santé et merci de lire ou de répondre.
8 réponses
Location loc1 = new Location("");
loc1.setLatitude(lat1);
loc1.setLongitude(lon1);
Location loc2 = new Location("");
loc2.setLatitude(lat2);
loc2.setLongitude(lon2);
float distanceInMeters = loc1.distanceTo(loc2);
http://developer.android.com/reference/android/location/Location.html
regardez la distance entre les deux. Vous pouvez créer un objet de localisation à partir d'une latitude et longitude:
Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);
une solution approximative (basée sur une projection équirectangulaire), beaucoup plus rapide (il ne nécessite que 1 trig et 1 racine carrée).
cette approximation est pertinente si vos points ne sont pas trop éloignés. Il sera toujours sur-estimé par rapport à la distance réelle haversine. Par exemple, il ajoutera pas plus de 0,05382 % à la distance réelle si le delta latitude ou longitude entre votre deux points ne dépasse pas 4 degrés décimaux .
la formule standard (Haversine) est la exacte un (c'est-à-dire, il fonctionne pour tout couple de longitude/latitude sur la terre) mais est beaucoup plus lent comme il a besoin de 7 racines trigonométriques et 2 carrés. Si votre couple de points ne sont pas trop éloignés, et la précision absolue n'est pas primordiale, vous pouvez utiliser cette version approximative (Equirectangular), qui est beaucoup plus rapide car il utilise un seul trigonométriques et une racine carrée.
// Approximate Equirectangular -- works if (lat1,lon1) ~ (lat2,lon2)
int R = 6371; // km
double x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
double y = (lat2 - lat1);
double distance = Math.sqrt(x * x + y * y) * R;
vous pouvez optimiser ce plus par soit:
- suppression de la racine carrée si vous comparez simplement la distance à une autre (dans ce cas, comparez les deux distances au carré);
- prise en compte de l'cosinus si vous calculez la distance d'un maître point à beaucoup de d'autres (dans ce cas vous faites la projection équirectangulaire centrée sur le point maître, de sorte que vous pouvez calculer le cosinus une fois pour toutes les comparaisons).
pour plus d'informations voir: http://www.movable-type.co.uk/scripts/latlong.html
Il ya une belle mise en œuvre de référence de la formule Haversine en plusieurs langues à: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe
il y a quelques méthodes que vous pouvez utiliser, mais pour déterminer laquelle est la meilleure, nous devons d'abord savoir si vous êtes au courant de l'altitude de l'utilisateur, ainsi que l'altitude des autres points?
selon le niveau de précision que vous recherchez, vous pouvez examiner les formules Haversine ou Vincenty...
ces pages détaillent les formules, et, pour les moins mathématiquement inclinés fournir également une explication de la façon de les mettre en œuvre dans le script!
Haversine formule: http://www.movable-type.co.uk/scripts/latlong.html
formule de Vincenty: http://www.movable-type.co.uk/scripts/latlong-vincenty.html
si vous avez des problèmes avec l'un des sens dans les formules, il suffit de commenter et je ferai de mon mieux pour y répondre:)
il y a deux façons d'obtenir la distance entre les LatLng.
public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
et deuxième
public float distanceTo (Location dest)
comme répondu par praveen.
il suffit d'utiliser la méthode suivante, passer lat et long et obtenir la distance en mètre:
private static double distance_in_meter(final double lat1, final double lon1, final double lat2, final double lon2) {
double R = 6371000f; // Radius of the earth in m
double dLat = (lat1 - lat2) * Math.PI / 180f;
double dLon = (lon1 - lon2) * Math.PI / 180f;
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(latlong1.latitude * Math.PI / 180f) * Math.cos(latlong2.latitude * Math.PI / 180f) *
Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2f * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c;
return d;
}
private float getDistance(double lat1, double lon1, double lat2, double lon2) {
float[] distance = new float[2];
Location.distanceBetween(lat1, lon1, lat2, lon2, distance);
return distance[0];
}
vous pouvez obtenir la distance et le temps en utilisant L'API GoogleMap Google Map API
il suffit de passer téléchargé JSON à cette méthode, vous obtiendrez la Distance en temps réel et le temps entre deux latlong
void parseJSONForDurationAndKMS(String json) throws JSONException {
Log.d(TAG, "called parseJSONForDurationAndKMS");
JSONObject jsonObject = new JSONObject(json);
String distance;
String duration;
distance = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("distance").getString("text");
duration = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("duration").getString("text");
Log.d(TAG, "distance : " + distance);
Log.d(TAG, "duration : " + duration);
distanceBWLats.setText("Distance : " + distance + "\n" + "Duration : " + duration);
}