Python 如何快速估计两个(纬度、经度)点之间的距离?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15736995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I quickly estimate the distance between two (latitude, longitude) points?
提问by fread2281
I want to be able to get a estimate of the distance between two (latitude, longitude) points. I want to undershoot, as this will be for A* graph search and I want it to be fast. The points will be at most 800 km apart.
我希望能够估计两个(纬度,经度)点之间的距离。我想低于,因为这将用于 A* 图形搜索,并且我希望它很快。这些点最多相距 800 公里。
采纳答案by Aaron D
The answers to Haversine Formula in Python (Bearing and Distance between two GPS points)provide Python implementations that answer your question.
Python 中Haversine 公式的答案(两个 GPS 点之间的方位角和距离)提供了 Python 实现来回答您的问题。
Using the implementation below I performed 100,000 iterations in less than 1 secondon an older laptop. I think for your purposes this should be sufficient. However, you should profile anything before you optimize for performance.
使用下面的实现,我在较旧的笔记本电脑上在不到 1 秒的时间内执行了 100,000 次迭代。我认为就您的目的而言,这应该足够了。但是,在优化性能之前,您应该分析任何内容。
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 kmTo underestimate haversine(lat1, long1, lat2, long2) * 0.90or whatever factor you want. I don't see how introducing error to your underestimation is useful.
低估haversine(lat1, long1, lat2, long2) * 0.90或任何你想要的因素。我不明白在你的低估中引入错误有什么用。
回答by Raymond Hettinger
One idea for speed is to transform the long/lat coordinated into 3D (x,y,z) coordinates. After preprocessing the points, use the Euclidean distance between the points as a quickly computed undershoot of the actual distance.
速度的一种想法是将经纬度坐标转换为 3D (x,y,z) 坐标。对点进行预处理后,使用点之间的欧几里得距离作为实际距离的快速计算下冲。
回答by Aaron D
For maximal speed, you could create something like a rainbow tablefor coordinate distances. It sounds like you already know the area that you are working with, so it seems like pre-computing them might be feasible. Then, you could load the nearest combination and just use that.
为了获得最大速度,您可以为坐标距离创建类似彩虹表的东西。听起来您已经知道您正在使用的领域,因此预先计算它们似乎是可行的。然后,您可以加载最接近的组合并使用它。
For example, in the continental United States, the longitude is a 55 degree span and latitude is 20, which would be 1100 whole number points. The distance between all the possible combinations is a handshake problemwhich is answered by (n-1)(n)/2 or about 600k combinations. That seems pretty feasible to store and retrieve. If you provide more information about your requirements, I could be more specific.
例如,在美国大陆,经度为 55 度跨度,纬度为 20,这将是 1100 个整数点。所有可能组合之间的距离是一个握手问题,由 (n-1)(n)/2 或大约 600k 组合回答。存储和检索这似乎非常可行。如果您提供有关您的要求的更多信息,我可以更具体。
回答by TreyA
Since the distance is relatively small, you can use the equirectangular distance approximation. This approximation is faster than using the Haversine formula. So, to get the distance from your reference point (lat1/lon1) to the point your are testing (lat2/lon2), use the formula below. Important Note: you need to convert all lat/lon points to radians:
由于距离相对较小,您可以使用等距柱状距离近似值。这种近似比使用Haversine 公式更快。因此,要获得从参考点 (lat1/lon1) 到您要测试的点 (lat2/lon2) 的距离,请使用以下公式。重要说明:您需要将所有经纬度点转换为弧度:
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 )
Since 'R' is in km, the distance 'd' will be in km.
由于“R”以公里为单位,因此距离“d”将以公里为单位。
Reference: http://www.movable-type.co.uk/scripts/latlong.html
回答by uher
Please use the following code.
请使用以下代码。
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
回答by Danylo Zherebetskyy
If the distance between points is relatively small (meters to few km range) then one of the fast approaches could be
如果点之间的距离相对较小(几米到几公里的范围),那么快速方法之一可能是
from math import cos, sqrt
def qick_distance(Lat1, Long1, Lat2, Long2):
x = Lat2 - Lat1
y = (Long2 - Long1) * cos((Lat2 + Lat1)*0.00872664626)
return 111.319 * sqrt(x*x + y*y)
Lat, Long are in radians, distance in km.
Lat, Long 以弧度为单位,距离以公里为单位。
Deviation from Haversine distance is in the order of 1%, while the speed gain is more than ~10x.
与 Haversine 距离的偏差约为 1%,而速度增益超过 ~10 倍。
0.00872664626 = 0.5 * pi/180,
0.00872664626 = 0.5 * pi/180,
111.319 - is the distance that corresponds to 1degree at Equator, you could replace it with your median value like here https://www.cartographyunchained.com/cgsta1/or replace it with a simple lookup table.
111.319 - 是对应于赤道 1 度的距离,你可以用你的中值替换它,就像这里 https://www.cartographyunchained.com/cgsta1/或用一个简单的查找表替换它。
回答by Chiefir
To calculate a haversine distance between 2 points u can simply use mpu.haversine_distance()library, like this:
要计算两点之间的半正弦距离,您可以简单地使用mpu.haversine_distance()库,如下所示:
>>> import mpu
>>> munich = (48.1372, 11.5756)
>>> berlin = (52.5186, 13.4083)
>>> round(mpu.haversine_distance(munich, berlin), 1)
>>> 504.2

