Haversine 距离算法是计算地球表面两点球面直线距离的经典算法,日常用的地图测距、打车软件预估里程,背后都有它的身影。
一、算法的核心用途
我们生活的地球是一个近似球体,如果要计算两个地点(比如北京到上海)的'直线距离',不能直接用平面几何的勾股定理(因为地球表面是曲面)。
Haversine 算法的作用,就是基于两点的经纬度坐标,计算它们在地球球面上的最短距离(这个最短距离也叫大圆距离,即穿过球心的平面切割球面形成的圆弧长度)。
二、必须掌握的前置知识
在理解公式前,先记住 3 个关键概念:
- 经纬度的定义
- 纬度 (latitude):衡量地点南北位置,范围是
[-90°, 90°],赤道是 0°,北极是 90°N,南极是 90°S。 - 经度 (longitude):衡量地点东西位置,范围是
[-180°, 180°],本初子午线是 0°,向东为东经,向西为西经。
- 纬度 (latitude):衡量地点南北位置,范围是
- 角度与弧度的转换数学中三角函数(sin、cos)的计算需要弧度值,而我们日常用的经纬度是角度值,因此必须先转换:
- 弧度 = 角度 × π / 180°
- 角度 = 弧度 × 180° / π
- 地球半径的取值地球不是完美球体,赤道半径约 6378km,极半径约 6357km。日常计算取平均半径 R = 6371km 即可满足精度需求。
三、Haversine 公式拆解
1. 公式的数学表达式
假设地球表面有两点:
- 点 A:纬度
lat1,经度lon1 - 点 B:纬度
lat2,经度lon2
Haversine 公式的最终形式为:
d = 2R · arcsin(√(sin²(Δφ/2) + cos(φ1)·cos(φ2)·sin²(Δλ/2)))
其中:
- Δφ = lat2 − lat1:两点的纬度差
- Δλ = lon2 − lon1:两点的经度差
- R:地球平均半径(6371km)
- d:两点的球面直线距离
2. 公式的通俗理解(分 4 步计算)
我们不用死记公式,而是把计算拆成 4 个简单步骤:
- 角度转弧度将
lat1, lon1, lat2, lon2全部转换成弧度值(记为φ1, λ1, φ2, λ2)。 - 计算差值计算纬度差 Δφ=φ2−φ1,经度差 Δλ=λ2−λ1。
- 计算核心根式代入公式计算根号内的部分:a=sin²(Δφ/2)+cos(φ1)·cos(φ2)·sin²(Δλ/2)
- 计算最终距离代入公式计算距离:d=2R·arcsin(√a)
四、零基础能看懂的 Python 代码实现
下面给出完整的 Python 代码,逐行添加中文注释,你可以直接复制运行。我们以北京(39.9042°N, 116.4074°E)到上海(31.2304°N, 121.4737°E)为例计算距离。
# 导入数学库,用于三角函数和弧度转换
import math
def haversine_distance(lat1, lon1, lat2, lon2):
"""
计算地球表面两点的球面直线距离
参数:
lat1: 点 1 的纬度(角度值)
lon1: 点 1 的经度(角度值)
lat2: 点 2 的纬度(角度值)
lon2: 点 2 的经度(角度值)
返回:
distance: 两点的球面距离,单位为千米 (km)
"""
R =
phi1 = math.radians(lat1)
lambda1 = math.radians(lon1)
phi2 = math.radians(lat2)
lambda2 = math.radians(lon2)
delta_phi = phi2 - phi1
delta_lambda = lambda2 - lambda1
a = math.sin(delta_phi / ) ** + \
math.cos(phi1) * math.cos(phi2) * \
math.sin(delta_lambda / ) **
c = * math.atan2(math.sqrt(a), math.sqrt( - a))
distance = R * c
distance
beijing_lat, beijing_lon = ,
shanghai_lat, shanghai_lon = ,
distance = haversine_distance(beijing_lat, beijing_lon, shanghai_lat, shanghai_lon)
()

