Python中经纬度坐标转换为距离以及角度的实现可以通过使用Haversine公式来实现。
Haversine公式
Haversine公式是一种通过经纬度计算球面距离的算法,它的计算方式基于圆心角,其公式如下:
$d = 2r\arcsin\sqrt{\sin^2\frac{\phi_2-\phi_2}{2}+\cos\phi_1\cos\phi_2\sin^2\frac{\lambda_2-\lambda_1}{2}}$
其中,$d$表示两点间的距离,$r$为球体的半径,$\phi_1,\phi_2,\lambda_1,\lambda_2$分别表示两点的纬度和经度。
下面是Python中利用Haversine公式实现经纬度坐标转换为距离及角度的代码:
from math import radians, cos, sin, sqrt, atan2
def haversine(lat1, lon1, lat2, lon2):
R = 6371 # 地球半径,单位为千米
lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
a = sin((lat2-lat1)/2)**2 + cos(lat1)*cos(lat2)*sin((lon2-lon1)/2)**2
distance = 2 * R * atan2(sqrt(a), sqrt(1-a))
bearing = atan2(sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1))
bearing = (bearing + 360) % 360
return distance, bearing
该函数需要输入四个参数:原点的纬度($lat_1$)和经度($lon_1$),目标点的纬度($lat_2$)和经度($lon_2$),输出为一个包含距离和角度的元组。其中,距离以千米为单位,角度以度数表示,以北为0度,东为90度,南为180度,西为270度。
例如,我们希望计算北京市和上海市两个城市的距离和角度,其经纬度坐标分别为。
北京市 (39.9042° N, 116.4074° E)
上海市 (31.2304° N, 121.4737° E)
那么我们可以运行以下代码进行计算:
distance, bearing = haversine(39.9042, 116.4074, 31.2304, 121.4737)
print(f"Distance between Beijing and Shanghai is {distance:.2f} km, bearing {bearing:.2f} degrees")
输出结果为:
Distance between Beijing and Shanghai is 1061.44 km, bearing 117.61 degrees
这说明北京到上海的距离约为1061.44公里,方位角为117.61度。
Vincenty公式
除了Haversine公式,还可以使用Vincenty公式来计算两个经纬度之间的距离,Vincenty公式可以更准确地计算球面距离。下面是Python中利用Vincenty公式实现经纬度坐标转换为距离及角度的代码:
from math import radians, atan2, tan, sin, cos
from numpy import arctan2, sqrt, deg2rad
def vincenty(lat1, lon1, lat2, lon2, a=6378137.0, b=6356752.314245, f=1/298.257223563):
lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
L = lon2 - lon1
U1 = atan2((1 - f) * tan(lat1), cos(L))
U2 = atan2((1 - f) * tan(lat2), cos(L))
sinU1, cosU1 = sin(U1), cos(U1)
sinU2, cosU2 = sin(U2), cos(U2)
lambda_old = L
for i in range(1000):
sinLambda, cosLambda = sin(lambda_old), cos(lambda_old)
sinSigma = sqrt((cosU2*sinLambda)**2 + (cosU1*sinU2 - sinU1*cosU2*cosLambda)**2)
cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda
sigma = atan2(sinSigma, cosSigma)
sinAlpha = (cosU1*cosU2*sinLambda) / sinSigma
cosSqAlpha = 1 - sinAlpha**2
if cosSqAlpha == 0:
cos2SigmaM = 0
else:
cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha
C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))
lambda_new = L + (1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM**2)))
if abs(lambda_new - lambda_old) < 1e-12:
break
lambda_old = lambda_new
uSq = cosSqAlpha*(a**2 - b**2)/b**2
A = 1 + uSq/16384*(4096 + uSq*(-768 + uSq*(320 - 175*uSq)))
B = uSq/1024*(256 + uSq*(-128 + uSq*(74 - 47*uSq)))
deltaSigma = B*sinSigma*(cos2SigmaM + 1/4*B*(cosSigma*(-1+2*cos2SigmaM**2) - 1/6*B*cos2SigmaM*(-3+4*sinSigma**2)*(-3+4*cos2SigmaM**2)))
distance = b*A*(sigma-deltaSigma)
bearing = arctan2(cosU2*sin(L), cosU1*sinU2 - sinU1*cosU2*cos(L))
bearing = (bearing + 360) % 360
return distance, bearing
同样的,输入为原点的纬度($lat_1$)和经度($lon_1$),目标点的纬度($lat_2$)和经度($lon_2$),输出结果仍为一个包含距离和角度的元组。距离以米为单位,角度以度数表示,以北为0度,东为90度,南为180度,西为270度。
例如,我们想要计算纽约到旧金山的距离和角度。
纽约市 (40.7128° N, 74.0059° W)
旧金山 (37.7749° N, 122.4194° W)
现在,我们可以使用以下代码计算距离和角度:
distance, bearing = vincenty(40.7128, -74.0059, 37.7749, -122.4194)
print(f"Distance between New York and San Francisco is {distance/1000:.2f} km, bearing {bearing:.2f} degrees")
输出结果为:
Distance between New York and San Francisco is 4152.37 km, bearing 295.27 degrees
这说明纽约到旧金山的距离约为4152.37公里,方位角为295.27度。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python经纬度坐标转换为距离及角度的实现 - Python技术站