web-dev-qa-db-fra.com

Comment puis-je estimer rapidement la distance entre deux points (latitude, longitude)?

Je veux pouvoir obtenir une estimation de la distance entre deux points (latitude, longitude). Je veux effectuer un sous-dépouillement, car ce sera pour la recherche de graphes A * et je veux que ce soit rapide . Les points seront au maximum à 800 km l'un de l'autre.

49
fread2281

Les réponses à Formule Haversine en Python (Relèvement et distance entre deux points GPS) fournissent des implémentations Python qui répondent à votre question.

Utilisation de l'implémentation ci-dessous I effectué 100 000 itérations en moins d'une seconde sur un ordinateur portable plus ancien. Je pense que cela devrait suffire à vos fins. Cependant, vous devez profiler quoi que ce soit avant d’optimiser pour obtenir des performances optimales .

from math import radians, cos, sin, asin, sqrt
def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    # Radius of earth in kilometers is 6371
    km = 6371* c
    return km

Sous-estimer haversine(lat1, long1, lat2, long2) * 0.90 ou le facteur que vous voulez. Je ne vois pas en quoi l'introduction d'une erreur dans votre sous-estimation est utile.

101
Aaron D

Comme la distance est relativement petite, vous pouvez utiliser l'approximation de distance équirectangulaire. Cette approximation est plus rapide que l’utilisation de la formule de Haversine. Ainsi, pour obtenir la distance entre votre point de référence (lat1/lon1) et le point que vous testez (lat2/lon2), utilisez la formule ci-dessous. Remarque importante: vous devez convertir tous les points lat/lon en radians:

R = 6371  // radius of the earth in km
x = (lon2 - lon1) * cos( 0.5*(lat2+lat1) )
y = lat2 - lat1
d = R * sqrt( x*x + y*y )

Puisque 'R' est en km, la distance 'd' sera en km. 

Référence: http://www.movable-type.co.uk/scripts/latlong.html

35
TreyA

Une idée de vitesse est de transformer le long/lat coordonné en coordonnées 3D (x, y, z). Après le prétraitement des points, utilisez la distance euclidienne entre les points en tant que dépassement rapide calculé de la distance réelle.

7

Pour une vitesse maximale, vous pouvez créer quelque chose comme un tableau Rainbow pour les distances de coordonnées. Il semble que vous sachiez déjà le domaine dans lequel vous travaillez, il semble donc possible de les pré-calculer. Ensuite, vous pouvez charger la combinaison la plus proche et l'utiliser. 

Par exemple, dans la partie continentale des États-Unis, la longitude est de 55 degrés et la latitude est de 20, ce qui correspond à 1100 points entiers. La distance entre toutes les combinaisons possibles est un problème de poignée de main auquel on répond par (n-1) (n)/2 ou environ 600 combinaisons. Cela semble assez faisable pour stocker et récupérer. Si vous fournissez plus d'informations sur vos besoins, je pourrais être plus précis.

3
Aaron D

Si la distance entre les points est relativement petite (portée de quelques mètres à quelques km), une des approches rapides pourrait être:

def qick_distance(Lat1, Long1, Lat2, Long2):
    x = Lat2 - Lat1
    y = (Long2 - Long1)*cos((Lat2 + Lat1)*0.00872664626)  
    return 111.138*sqrt(x*x+y*y)

Lat, Long sont en radians, la distance en mètres . La déviation par rapport à la distance de Haversine est de l’ordre de 1%, le gain en vitesse est supérieur à ~ 10x . 0.00872664626 = 0.5 * pi/180 la distance qui correspond à 1 degré à la latitude 45N (environ le milieu de l’Europe), vous pouvez la remplacer par votre valeur médiane, comme ici https://www.cartographyunchained.com/cgsta1/ ou remplacez-le par une simple table de correspondance.

0
Danylo Zherebetskyy

Pour calculer une distance de haversine entre 2 points, vous pouvez simplement utiliser mpu.haversine_distance () library, comme ceci: 

>>> import mpu
>>> munich = (48.1372, 11.5756)
>>> berlin = (52.5186, 13.4083)
>>> round(mpu.haversine_distance(munich, berlin), 1)
>>> 504.2
0
Chiefir

Veuillez utiliser le code suivant.

def distance(lat1, lng1, lat2, lng2):
    #return distance as meter if you want km distance, remove "* 1000"
    radius = 6371 * 1000 

    dLat = (lat2-lat1) * math.pi / 180
    dLng = (lng2-lng1) * math.pi / 180

    lat1 = lat1 * math.pi / 180
    lat2 = lat2 * math.pi / 180

    val = sin(dLat/2) * sin(dLat/2) + sin(dLng/2) * sin(dLng/2) * cos(lat1) * cos(lat2)    
    ang = 2 * atan2(sqrt(val), sqrt(1-val))
    return radius * ang
0
uher