4. 计算点之间的距离
任务说明
本案例提供两组地理坐标点(经纬度),分别使用Haversine公式和GeoPandas的distance()方法计算点与点之间的球面距离,并对比两种方法的结果是否一致。输入数据为两个点坐标,输出为两种方法计算的距离值及差异。
实现代码
import math
import geopandas as gpd
from shapely.geometry import Point
# 输入:两个点的经纬度(经度, 纬度)
point_a = (116.4074, 39.9042) # 北京
point_b = (121.4737, 31.2304) # 上海
# ---------- 1. Haversine公式 ----------
def haversine(coord1, coord2):
"""计算两个经纬度坐标之间的球面距离(单位:米)"""
lon1, lat1 = coord1
lon2, lat2 = coord2
R = 6371000.0 # 地球平均半径(米)
phi1 = math.radians(lat1)
phi2 = math.radians(lat2)
dphi = math.radians(lat2 - lat1)
dlambda = math.radians(lon2 - lon1)
a = math.sin(dphi / 2) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(dlambda / 2) ** 2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
return R * c
dist_haversine = haversine(point_a, point_b)
print(f"Haversine距离: {dist_haversine:.2f} 米")
# ---------- 2. GeoPandas distance()方法 ----------
# 创建GeoDataFrame,坐标系为WGS84(EPSG:4326)
gdf = gpd.GeoDataFrame(
geometry=[Point(point_a), Point(point_b)],
crs="EPSG:4326"
)
# 将坐标系转换为适合测距的投影坐标系(Web Mercator,单位:米)
gdf_proj = gdf.to_crs("EPSG:3857")
# 计算两点之间的距离(投影后平面距离近似球面距离)
dist_geopandas = gdf_proj.geometry[0].distance(gdf_proj.geometry[1])
print(f"GeoPandas distance()距离: {dist_geopandas:.2f} 米")
# ---------- 3. 结果对比 ----------
diff = abs(dist_haversine - dist_geopandas)
print(f"两种方法差异: {diff:.2f} 米")
print(f"相对误差: {diff / dist_haversine * 100:.4f}%")
代码说明
代码首先定义了两个城市的经纬度坐标。Haversine函数直接根据球面三角公式计算大圆距离。GeoPandas部分先将坐标点构建为GeoDataFrame(EPSG:4326),再投影到EPSG:3857(Web Mercator)坐标系,使距离计算以米为单位,然后调用distance()方法获取两点间距离。最后输出两种结果并计算差值和相对误差。
运行方式与依赖
运行前需安装依赖:pip install geopandas shapely。将代码保存为point_distance.py,在命令行执行python point_distance.py即可。
验证方法与判定标准
程序输出应包含三行:Haversine距离、GeoPandas距离和差异值。判定通过的标准为:两种方法计算的距离均在1060~1080千米范围内(北京到上海的实际球面距离约1067千米),且相对误差小于1%。由于Web Mercator投影在纬度40°附近存在约0.3%的长度变形,两种方法结果存在小量差异属正常现象。