0%

LBS 球面距离公式

维基百科推荐使用$Haversine$公式,理由是$Great-circle distance$公式用到了大量余弦函数, 而两点间距离很短时(比如地球表面上相距几百米的两点),余弦函数会得出0.999…的结果, 会导致较大的舍入误差。而$Haversine$公式采用了正弦函数,即使距离很小,也能保持足够的有效数字。 以前采用三角函数表计算时的确会有这个问题,但经过实际验证,采用计算机来计算时,两个公式的区别不大。 稳妥起见,这里还是采用$Haversine$公式。

Haversine公式

$$haversin(\frac{d}{R}) = haversin(φ2 - φ1) + cos(φ1) cos(φ2) haversin(⊿λ)$$
其中
$$haversin(θ) = sin(\frac{θ}{2})^2 = \frac{1- cos(θ)}{2}$$

$R$为地球半径,可取平均值$ 6371.137km$
$φ_1$, $φ_2$ 表示两点的纬度;
$Δλ$ 表示两点经度的差值。

距离计算函数

下面就是计算球面间两点$(lat0, lng)-(lat1, lng1)$之间距离的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from math import sin, asin, cos, radians, fabs, sqrt

EARTH_RADIUS=6371 # 地球平均半径,6371km

def hav(theta):
s = sin(theta / 2)
return s * s

def get_distance_hav(lat0, lng0, lat1, lng1):
"用haversine公式计算球面两点间的距离。"
# 经纬度转换成弧度
lat0 = radians(lat0)
lat1 = radians(lat1)
lng0 = radians(lng0)
lng1 = radians(lng1)

dlng = fabs(lng0 - lng1)
dlat = fabs(lat0 - lat1)
h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng)
distance = 2 * EARTH_RADIUS * asin(sqrt(h))

return distance

相关文献

LBS 球面距离公式

写文不易,感谢支持!
Writing is not easy. Thank you for your support.