434 votes

Calculer la distance entre 2 coordonnées GPS

Comment calculer la distance entre deux coordonnées GPS (en utilisant la latitude et la longitude) ?

3 votes

Cet algorithme est connu sous le nom de Distance du Grand Cercle .

498voto

cletus Points 276888

Calculer la distance entre deux coordonnées par la latitude et la longitude y compris une implémentation Javascript.

Ouest y Sud les emplacements sont négatifs. Rappelez-vous que les minutes et les secondes sont en dehors de 60, donc S31 30' est -31,50 degrés.

N'oubliez pas de convertir des degrés en radians . De nombreuses langues disposent de cette fonction. Ou bien il s'agit d'un simple calcul : radians = degrees * PI / 180 .

function degreesToRadians(degrees) {
  return degrees * Math.PI / 180;
}

function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
  var earthRadiusKm = 6371;

  var dLat = degreesToRadians(lat2-lat1);
  var dLon = degreesToRadians(lon2-lon1);

  lat1 = degreesToRadians(lat1);
  lat2 = degreesToRadians(lat2);

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  return earthRadiusKm * c;
}

Voici quelques exemples d'utilisation :

distanceInKmBetweenEarthCoordinates(0,0,0,0)  // Distance between same 
                                              // points should be 0
0

distanceInKmBetweenEarthCoordinates(51.5, 0, 38.8, -77.1) // From London
                                                          // to Arlington
5918.185064088764

17 votes

Au cas où cela ne serait pas évident, la méthode toRad() est une personnalisation de la fonction Numéro prototype tel que : Number.prototype.toRad = function() { return this * (Math.PI / 180); }; . Ou, comme indiqué ci-dessous, vous pouvez remplacer (Math.PI/2) avec 0.0174532925199433 (...toute précision que vous jugerez nécessaire) pour une performance accrue.

54 votes

Si quelqu'un, en particulier ceux d'entre vous qui ne regardent pas les commentaires de fin de ligne, regarde cette formule et cherche une unité de distance, l'unité est le km :)

0 votes

Pourquoi calcule-t-on le cosinus de lat1 et lat2 et non celui de lon1 et lon2 ?

63voto

Peter Greis Points 381

Cherchez haversine avec Google ; voici ma solution :

#include <math.h>
#include "haversine.h"

#define d2r (M_PI / 180.0)

//calculate haversine distance for linear distance
double haversine_km(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 6367 * c;

    return d;
}

double haversine_mi(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 3956 * c; 

    return d;
}

0 votes

J'ai aussi utilisé l'haversine dans mes projets.

4 votes

Vous pouvez remplacer (M_PI / 180.0) par 0.0174532925199433 pour de meilleures performances.

3 votes

En termes de performances : on pourrait calculer sin(dlat/2.0) une seule fois, le stocker dans la variable a1, et au lieu de pow(,2), il est BEAUCOUP mieux d'utiliser a1*a1. De même pour l'autre pow(,2).

47voto

Roman Makarov Points 151

Version C# de Haversine

double _eQuatorialEarthRadius = 6378.1370D;
double _d2r = (Math.PI / 180D);

private int HaversineInM(double lat1, double long1, double lat2, double long2)
{
    return (int)(1000D * HaversineInKM(lat1, long1, lat2, long2));
}

private double HaversineInKM(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * _d2r;
    double dlat = (lat2 - lat1) * _d2r;
    double a = Math.Pow(Math.Sin(dlat / 2D), 2D) + Math.Cos(lat1 * _d2r) * Math.Cos(lat2 * _d2r) * Math.Pow(Math.Sin(dlong / 2D), 2D);
    double c = 2D * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1D - a));
    double d = _eQuatorialEarthRadius * c;

    return d;
}

Voici une démonstration de cette méthode en .NET. afin que vous puissiez le tester avec vos propres latitudes et longitudes.

1 votes

J'ai également ajouté un fiddle checky .NET pour que les gens puissent facilement le tester.

7 votes

Le .Net Framework comporte une méthode GeoCoordinate.GetDistanceTo intégrée. L'assemblage System.Device doit être référencé. Article MSDN msdn.microsoft.com/fr/us/library/

28voto

Greg Hewgill Points 356191

Cet algorithme est connu sous le nom de Distance du Grand Cercle .

26voto

Marko Tintor Points 209

Ceci est très facile à faire avec le type de géographie dans SQL Server 2008.

SELECT geography::Point(lat1, lon1, 4326).STDistance(geography::Point(lat2, lon2, 4326))
-- computes distance in meters using eliptical model, accurate to the mm

4326 est le SRID pour le modèle de Terre elipsoïdal WGS84

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X