如何用geopy计算两点间直线上任意位置的经纬度?
问题
我正在使用geopy模拟物体在两个地理点间移动时的位置映射,需要计算该物体在理论行程中任意阶段的经纬度:例如从巴黎到纽约,0%对应巴黎,100%对应纽约,50%对应行程过半时的中点(仅考虑两点间直线,不考虑实际航线或真实物体轨迹)。
我的代码如下:
from geopy.distance import geodesic as GD start = (48.8567, 2.3508) # Paris end = (40.7128, 74.0060) # New York distance_between = GD(start, end).km print(f"{distance_between} km between Paris and New York") pct_travelled = 50 new_lat = start[0] + (end[0] - start[0]) * (int(pct_travelled) / 100) new_lon = start[1] + (end[1] - start[1]) * (int(pct_travelled) / 100) print(f"Your current location is {new_lat}, {new_lon}") distance_travelled_so_far = GD(start, (new_lat, new_lon)).km distance_still_to_travel = GD((new_lat, new_lon), end).km print(f"You have travelled {distance_travelled_so_far} km") print(f"You have {distance_still_to_travel} km left to travel")
运行后得到错误结果:
5529.689905151459 km between Paris and New York Your current location is 44.78475, 38.178399999999996 You have travelled 2744.973813842307 km You have 2943.5970959509054 km left to travel
错误原因是地球是椭球体,经纬度的每一度对应的实际距离并不均匀,直接线性插值经纬度得到的点并不是球面上两点间大圆弧的中点,因此50%行程时已行驶距离和剩余距离不相等。请问如何用geopy或其他Python库正确实现该功能?
解决方案
方法一:使用geopy内置的destination方法
geopy的geodesic对象提供了destination方法,可以直接计算从起点出发,沿指定方位角移动指定距离后的位置,完全符合球面大圆弧的计算逻辑:
from geopy.distance import geodesic as GD start = (48.8567, 2.3508) # Paris end = (40.7128, 74.0060) # New York # 计算起点到终点的总距离和初始方位角 total_distance = GD(start, end) bearing = GD(start, end).bearing pct_travelled = 50 travel_distance = total_distance.km * (pct_travelled / 100) # 获取移动后的位置 current_loc = GD(start).destination(bearing=bearing, kilometers=travel_distance) new_lat, new_lon = current_loc.latitude, current_loc.longitude print(f"{total_distance.km} km between Paris and New York") print(f"Your current location is {new_lat}, {new_lon}") travelled = GD(start, (new_lat, new_lon)).km remaining = GD((new_lat, new_lon), end).km print(f"You have travelled {travelled} km") print(f"You have {remaining} km left to travel")
运行后,50%行程时的已行驶距离和剩余距离会基本相等(仅存在极小的浮点精度误差)。
方法二:使用pyproj库(更底层的椭球体计算)
如果需要更灵活的地理计算,可以用pyproj的Geod类,基于WGS84椭球体进行精确的球面计算:
from pyproj import Geod from geopy.distance import geodesic as GD start = (48.8567, 2.3508) # Paris (纬度, 经度) end = (40.7128, 74.0060) # New York (纬度, 经度) # 初始化WGS84椭球体的Geod对象 geod = Geod(ellps='WGS84') # 计算起点到终点的正向方位角、反向方位角和总距离(单位:米) forward_az, _, total_dist_m = geod.inv(start[1], start[0], end[1], end[0]) total_dist_km = total_dist_m / 1000 pct_travelled = 50 travel_dist_m = total_dist_m * (pct_travelled / 100) # 计算移动后的位置(返回值为:经度, 纬度, 最终方位角) new_lon, new_lat, _ = geod.fwd(start[1], start[0], forward_az, travel_dist_m) print(f"{total_dist_km} km between Paris and New York") print(f"Your current location is {new_lat}, {new_lon}") travelled = GD(start, (new_lat, new_lon)).km remaining = GD((new_lat, new_lon), end).km print(f"You have travelled {travelled} km") print(f"You have {remaining} km left to travel")
这个方法的计算逻辑和geopy一致,但提供了更多自定义椭球体的选项,适合复杂地理场景。
内容的提问来源于stack exchange,提问作者Super
相关产品推荐
相关产品推荐

