Selon Wikipedia, la formule de Vincenty est plus lente mais plus précise :
Les formules de Vincenty sont deux méthodes itératives connexes utilisées en géodésie pour calculer la distance entre deux points à la surface d'un sphéroïde, développées par Thaddeus Vincenty (1975a) .Elles sont basées sur l'hypothèse que la figure de la Terre est un sphéroïde oblat, et donc sont plus précises que des méthodes telles que la distance du grand cercle qui supposent une Terre sphérique.
La différence de précision se situe ~0.17%
à une distance de 428 mètres en Israël. J'ai fait un test de vitesse rapide et sale:
<class 'geopy.distance.vincenty'> : Total 0:00:04.125913, (0:00:00.000041 per calculation)
<class 'geopy.distance.great_circle'> : Total 0:00:02.467479, (0:00:00.000024 per calculation)
Code:
import datetime
from geopy.distance import great_circle
from geopy.distance import vincenty
p1 = (31.8300167,35.0662833)
p2 = (31.83,35.0708167)
NUM_TESTS = 100000
for strategy in vincenty, great_circle:
before = datetime.datetime.now()
for i in range(NUM_TESTS):
d=strategy(p1, p2).meters
after = datetime.datetime.now()
duration = after-before
print "%-40s: Total %s, (%s per calculation)" % (strategy, duration, duration/NUM_TESTS)
Pour conclure: la formule de Vincenty double le temps de calcul par rapport au grand cercle, et son gain de précision au point testé est de ~ 0,17%.
Le temps de calcul étant négligeable, la formule de Vincenty est préférée pour chaque besoin pratique.
Mise à jour : Suite aux commentaires perspicaces de whuber et de la réponse de cffk et de cffk , je suis d'accord que le gain de précision doit être comparé à l'erreur, pas à la mesure. Par conséquent, la formule de Vincenty est de quelques ordres de grandeur plus précise, et non de ~ 0,17%.
Si vous utilisez geopy, les distances great_circle et vincenty sont également pratiques à obtenir. Dans ce cas, vous devez presque toujours utiliser celui qui vous donne le résultat le plus précis, c'est-à-dire vincenty. Les deux considérations (comme vous le signalez) sont la vitesse et la précision.
Vincenty est deux fois plus lent. Mais probablement dans une application réelle, la durée de fonctionnement accrue est négligeable. Même si votre application demandait un million de calculs de distance, nous ne parlons que d'une différence de temps de quelques secondes.
Pour les points que vous utilisez, l'erreur dans vincenty est de 6 μm et l'erreur dans la distance du grand cercle est de 0,75 m. Je dirais alors que vincenty est 120000 fois plus précis (plutôt que 0,17% plus précis). Pour les points généraux, l'erreur dans la distance du grand cercle peut atteindre 0,5%. Pouvez-vous donc vivre avec une erreur de 0,5% dans les distances? Pour une utilisation occasionnelle (quelle est la distance du Cap au Caire?), Vous pouvez probablement le faire. Cependant, de nombreuses applications SIG ont des exigences de précision beaucoup plus strictes. (0,5% représente 5 m sur 1 km. Cela fait vraiment une différence.)
Presque tous les travaux de cartographie sérieux sont effectués sur l'ellipsoïde de référence et il est donc logique que les distances soient également mesurées sur l'ellipsoïde. Peut-être que vous pouvez vous en sortir avec des distances de grands cercles aujourd'hui. Mais pour chaque nouvelle demande, vous devrez vérifier si cela est toujours acceptable. Il vaut mieux utiliser la distance ellipsoïdale dès le départ. Vous dormirez mieux la nuit.
ADDENDA (mai 2017)
En réponse à la réponse donnée par @ craig-hicks. La méthode vincenty () dans geopy a un défaut potentiellement fatal: elle renvoie une erreur pour les points presque antipodaux. La documentation du code suggère d'augmenter le nombre d'itérations. Mais ce n'est pas une solution générale car la méthode itérative utilisée par vincenty () est instable pour de tels points (chaque itération vous éloigne de la bonne solution).
Pourquoi est-ce que je caractérise le problème comme "potentiellement mortel"? Parce que toute utilisation de la fonction de distance dans une autre bibliothèque de logiciels doit pouvoir gérer l'exception. Le manipuler en renvoyant un NaN ou la distance du grand cercle peut ne pas être satisfaisant, car la fonction de distance résultante n'obéira pas à l'inégalité du triangle qui empêche son utilisation, par exemple, dans les arbres à points d'observation.
La situation n'est pas complètement sombre. Mon package python Geographiclib calcule la distance géodésique avec précision sans aucune défaillance. La requête d'extraction de géopie # 144 modifie la fonction de distance du géopy pour utiliser le paquet GeographicLib s'il est disponible. Malheureusement, cette demande de traction est dans les limbes depuis août 2016.
ADDENDA (mai 2018)
geopy 1.13.0 utilise désormais le paquet Geographiclib pour calculer les distances. Voici un exemple d'appel (basé sur l'exemple de la question d'origine):
la source
Je m'excuse d'avoir posté une deuxième réponse ici, mais j'en profite pour répondre à la demande de @ craig-hicks de fournir des comparaisons de précision et de synchronisation pour différents algorithmes de calcul de la distance géodésique. Cela paraphrase un commentaire que je fais à ma demande de tirage # 144 pour geopy qui permet l'utilisation de l'une des deux implémentations de mon algorithme pour les géodésiques à utiliser dans geopy, l'une est une implémentation native de python, la géodésique (Geographiclib) et les autres utilisations une implémentation en C, géodésique (pyproj) .
Voici quelques données de synchronisation. Les temps sont en microsecs par appel
Voici la précision des calculs géodésiques basés sur mon ensemble de test géodésique . Les erreurs sont données en unités de microns (1e-6 m)
J'ai inclus la requête pull n ° 194 de hannosche qui corrige un mauvais bug dans la fonction de destination. Sans ce correctif, l'erreur dans le calcul de la destination pour vincenty est de 8,98 mètres.
19,2% des cas de tests ont échoué avec vincenty.distance (itérations = 20). Cependant, l'ensemble de test est biaisé vers les cas qui pourraient provoquer cet échec.
Avec des points aléatoires sur l'ellipsoïde WGS84, l'algorithme Vincenty est garanti d'échouer 16,6 fois sur 1000000 (la bonne solution est un point fixe instable de la méthode Vincenty).
Avec l'implémentation geopy de Vincenty et des itérations = 20, le taux d'échec est de 82,8 pour 1000000. Avec des itérations = 200, le taux d'échec est de 21,2 pour 1000000.
Même si ces taux sont faibles, les échecs peuvent être assez courants. Par exemple, dans un ensemble de données de 1000 points aléatoires (pensez aux aéroports du monde, peut-être), le calcul de la matrice de distance complète échouerait en moyenne 16 fois (avec des itérations = 20).
la source
Il semble que le paquet geopy.distance offre une fonction "distance ()" qui est par défaut vincenty (). Je recommanderais d'utiliser distance () en principe, car c'est la recommandation du package, au cas où il s'écarterait de vincenty () à l'avenir (peu probable que ce soit). Continuer la lecture:
Cette note de documentation est incluse dans le code source de la fonction vincenty () que vous avez spécifiée:
Le code source avec le commentaire / note ci-dessus peut être trouvé à https://github.com/geopy/geopy/blob/master/geopy/distance.py Faites défiler jusqu'à la définition de vincenty ()
Néanmoins, la fonction de distance par défaut utilisée par ce package lorsque caliing distance () est la fonction vincenty (), ce qui implique que l'échec de la convergence n'est pas catastrophique et qu'une réponse raisonnable est renvoyée - le plus important est qu'aucune exception n'est générée.
Mise à jour: Comme indiqué par "cffk", la fonction vincenty () lève explicitement une exception ValueError lorsque l'algorithme ne converge pas - bien qu'elle ne soit pas documentée dans la description de la fonction. Par conséquent, la documentation est boguée.
la source
Que vous utilisiez vincenty ou haversine ou la loi sphérique des cosinus, il est judicieux de prendre conscience des problèmes potentiels avec le code que vous prévoyez d'utiliser, des choses à surveiller et à atténuer, et de la façon dont on traite les problèmes vincenty vs haversine vs sloc différera à mesure que l'on se rend compte des problèmes / casse cachés de chacun, qui peuvent ou non être connus du grand public. Le programmeur chevronné le sait. Les débutants ne le peuvent pas. J'espère épargner à certains d'entre eux la frustration lorsqu'un extrait d'un forum fait quelque chose d'inattendu, dans certains cas. Si l'on va sérieusement utiliser une version de l'un d'entre eux, vincenty, haversine, sloc, alors SE, SO, Reddit, Quora, etc., peuvent avoir fourni une aide limitée dans le codage initial d'une solution, mais cela ne signifie pas que leur solution ou «réponse» acceptée est exempte de problèmes. Si un projet est suffisamment important, il mérite une quantité raisonnable de recherche appropriée. Lisez le manuel, lisez les documents, et s'il existe une révision du code de ce code, lisez-le. Copier et coller un extrait ou un résumé qui a été voté une centaine de fois ou plus ne signifie pas que sa sécurité est complète et assurée.
La réponse intrigante publiée par cffk soulève le point d'être conscient des cas cachés, dans les solutions packagées, qui peuvent produire des exceptions ou d'autres difficultés . Les allégations spécifiques formulées dans ce poste dépassent mon budget-temps pour le moment, mais j'en retiens qu'il y a effectivement des problèmes cachés dans certains paquets, y compris au moins une mise en œuvre de Vincent, au sujet desquels au moins une personne a proposé d'améliorer d'une manière ou d'une autre, afin de minimiser ou d'éliminer le risque de rencontrer ces difficultés. Je n'apporterai rien de plus à ce sujet concernant Vincent (en l'ignorant beaucoup trop), mais je me tournerai plutôt vers l'héversine, au moins en partie sur le sujet avec le PO.
La formule haversine publiquement publiée, que ce soit en python ou dans un autre langage, car elle utilisera très probablement la spécification en virgule flottante IEEE 754 sur la plupart des systèmes Intel et similaires aujourd'hui, et les processeurs ARM, PowerPC, etc. être également sensible à des erreurs d'exception rares mais réelles et répétables très proches ou à une distance d'arc de 180 degrés, des points antipodaux, en raison d'approximations de virgule flottante et d'arrondi. Certains débutants n'ont peut-être pas encore été mordus par cette situation. Parce que cette spécification fp se rapproche et arrondit, cela ne signifie pas que tout code qui appelle fp64 peut provoquer des erreurs d'exception, non. Mais du code, certaines formules peuvent ne pas avoir des contours si évidents où les approximations et les arrondis de IEEE 754 fp64 peuvent faire en sorte qu'une valeur s'écarte légèrement du domaine d'une méthode mathématique qui devrait évaluer sans faille une telle valeur. Un exemple ... sqrt (). Si une valeur négative trouve son chemin dans un sqrt (), tel que sqrt (-0.00000000000000000122739), il y aura une erreur d'exception. Dans la formule haversine, la manière dont elle progresse vers une solution, il y a deux méthodes sqrt () dans atan2 (). leun qui est calculé puis utilisé dans le sqrt (), peut, aux points antipodes du globe, légèrement s'égarer en dessous de 0,0 ou au-dessus de 1,0, très légèrement à cause des approximations fp64 et de l'arrondi, rarement, mais de façon répétable. Dans ce contexte, une répétabilité fiable et constante en fait un risque d'exception, un casse-tête à protéger, à atténuer, plutôt qu'un hasard aléatoire isolé. Voici un exemple d'un court extrait python3 de haversine, sans la protection nécessaire:
Très près ou aux points antipodes, un calculé dans la première ligne de la formule peut s'égarer négativement, rarement, mais de façon répétée avec ces mêmes coordonnées lat lon. Pour protéger / corriger ces rares cas, on peut simplement ajouter, après un calcul, comme on le voit ci - dessous:
Bien sûr, je n'ai pas montré l'intégralité de la fonction ici, mais un court extrait comme il est si souvent affiché. Mais celui-ci montre la protection de sqrt (), en testant le a et en le normalisant si nécessaire, ce qui évite également de mettre le tout dans un essai, sauf. La note = '' en haut sert à empêcher la phase de bytecode de protester contre l'utilisation de la note avant de lui affecter une valeur, si elle est renvoyée avec le résultat de la fonction.
Avec ce simple changement, d'ajouter les deux un essais, les fonctions sqrt () seront heureux, et le code a maintenant une somme supplémentaire de note qui peut être retourné au code d' appel, à l' alerte qu'un résultat a été légèrement normalisé, et pourquoi. Certains peuvent s'en soucier, d'autres non, mais c'est là, empêchant une erreur d'exception, qui «peut» autrement se produire. Un bloc try except peut intercepter l'exception, mais pas la corriger, sauf si cela est explicitement écrit pour le faire. Il semble plus facile à coder la ligne de correction (s) immédiatement après la une ligne de calcul. Une entrée soigneusement nettoyée ne devrait alors pas du tout nécessiter d'essayer sauf bloquer ici.
Résumé, si vous utilisez haversine, codé explicitement plutôt que d'utiliser un package ou une bibliothèque, peu importe la langue de votre choix, ce serait une bonne idée de tester et de normaliser un retour dans la plage nécessaire de 0,0 <= a <= 1,0 afin pour protéger la ligne suivante avec ses calculs c . Mais la majorité des extraits de code haversine ne le montrent pas et ne mentionnent pas le risque.
Expérience: lors de tests approfondis dans le monde entier, par incréments de 0,001 degré, j'ai rempli un disque dur avec des combinaisons lat lon qui ont provoqué une exception, une exception fiable et répétable cohérente, pendant un mois de test collatéral de la fiabilité du refroidissement du CPU fan, et ma patience. Oui, j'ai depuis supprimé la plupart de ces journaux, car leur but était principalement de prouver le point (si le jeu de mots est autorisé). Mais j'ai quelques journaux plus courts de «valeurs lat lon de problème», conservés à des fins de test.
Précision: est-ce que a et l'ensemble du résultat haversine perdront une certaine précision en le normalisant un peu dans le domaine? Pas grand-chose, peut-être pas plus que les approximations et arrondis fp64 déjà introduits, qui ont causé cette légère dérive hors du domaine. Si vous avez déjà trouvé haversine acceptable par rapport à vincenty - plus simple, plus rapide, plus facile à personnaliser, à dépanner et à entretenir, alors haversine peut être une bonne solution pour votre projet.
J'ai utilisé haversine sur une skysphère projetée au-dessus pour mesurer les distances angulaires entre les objets dans le ciel, vu depuis une position sur la terre, cartographier l'azimut et alt en coordonnées équivalentes lat lons à la skysphère, aucun élipsoïde à considérer du tout, puisque le la skysphère théorique projetée est une sphère parfaite, lorsqu'il s'agit de mesurer des angles de vue de distance angulaire entre deux objets à partir d'une position à la surface de la terre. Cela correspond parfaitement à mes besoins. Donc, haversine est toujours très utile et très précis dans certaines applications (bien dans mes buts) ... mais si vous l'utilisez, que ce soit sur terre pour le SIG ou la navigation, ou dans les observations et les mesures d'objets célestes, protégez dans le cas de points antipodes ou très proches de points antipodes, en testant unet le repoussant dans son domaine nécessaire en cas de besoin.
Le haversine non protégé est partout sur Internet, et je n'ai vu qu'un seul ancien poste Usenet qui a montré une certaine protection, je pense de la part d'un membre du JPL, et qui pourrait avoir été avant 1985, avant la spécification en virgule flottante IEEE 754. Deux autres pages ont mentionné des problèmes possibles près des points antipodaux, mais n'ont pas décrit ces problèmes, ni comment on pourrait les atténuer. Il y a donc lieu de s'inquiéter pour les débutants (comme moi) qui ne comprennent pas toujours assez bien les bonnes pratiques pour approfondir la recherche et tester les cas de certains codes qu'ils ont copiés et collés dans un projet en toute confiance. Le post intrigant de cffk était rafraîchissant en ce qu'il était public avec ces types de problèmes, qui ne sont pas souvent mentionnés, rarement codés publiquement pour la protection dans des extraits, et rarement discutés de cette manière, par rapport à la quantité de versions non protégées et non discutées qui sont publiées.
Depuis 20190923, la page wiki pour la formule haversine mentionne en effet le problème possible aux points antipodaux, en raison de problèmes de virgule flottante dans les appareils informatiques ... encourageant ...
https://en.wikipedia.org/wiki/Haversine_formula
(parce que cette page wiki n'a pas, pour le moment, d'ancrage html pour la section à laquelle je lierais directement, donc, après le chargement de la page, faites une recherche sur cette page du navigateur pour 'Quand utiliser ces formules' et vous voir plus officiellement le problème de l'haversine avec les points antipodes.)
Et cet autre site en a également une très brève mention:
https://www.movable-type.co.uk/scripts/latlong.html
Si l'on fait une recherche sur cette page pour «y compris la protection contre les erreurs d'arrondi», il y a ceci ...
Maintenant, il existe un cas rare où des erreurs d'arrondi sont mentionnées et la protection affichée pour la version asin (), mais non mentionnée ou affichée pour la version atan2 (). Mais au moins, le risque d'erreurs d'arrondi est mentionné.
imho, toute application 24/7/365 utilisant haversine, a besoin de cette protection près des points antipodes comme un détail important et simple.
Je ne sais pas quels packages haversine incluent ou n'incluent pas cette protection, mais si vous êtes nouveau dans tout cela et que vous allez utiliser la ou les versions d'extraits publiées, vous savez maintenant qu'il a besoin de protection, et cette protection est très simple à mettre en œuvre, c'est-à-dire si vous n'utilisez pas vincenty, et n'utilisez pas un haversine packagé sans accès facile pour modifier le code du package.
IOW, que vous utilisiez vincenty ou haversine ou sloc, vous devez être conscient de tout problème avec le code, des choses à surveiller et à atténuer, et comment les problèmes vincenty vs haversine vs sloc différeront à mesure que l'on se rend compte de chacun problèmes cachés / edgecases, qui peuvent être connus ou non.
la source