文章目录
1 原理公式
在地球上,计算两点之间的直线距离通常使用地理坐标系(例如WGS84)。计算两地直线距离的公式是根据经纬度之间的大圆距离(Great Circle Distance)来计算的。该公式基于球面三角学,常用的公式是
H
a
v
e
r
s
i
n
e
Haversine
Haversine 公式。
形式一:
d
l
o
n
=
l
o
n
2
−
l
o
n
1
d_{lon} = lon_2 - lon_1
dlon=lon2−lon1
d
l
a
t
=
l
a
t
2
−
l
a
t
1
d_{lat} = lat_2 - lat_1
dlat=lat2−lat1
a
=
s
i
n
2
(
d
l
a
t
/
2
)
+
c
o
s
(
l
a
t
1
)
∗
c
o
s
(
l
a
t
2
)
∗
s
i
n
2
(
d
l
o
n
/
2
)
a = sin²(d_{lat}/2) + cos(lat_1) * cos(lat_2) * sin²(d_{lon}/2)
a=sin2(dlat/2)+cos(lat1)∗cos(lat2)∗sin2(dlon/2)
c
=
2
∗
a
t
a
n
2
(
a
,
(
1
−
a
)
)
c = 2 * atan^2(\sqrt{a}, \sqrt{(1-a)})
c=2∗atan2(a,(1−a))
d
=
R
∗
c
d = R * c
d=R∗c
形式二:
d
=
R
∗
a
c
o
s
(
s
i
n
(
l
o
n
1
)
∗
s
i
n
(
l
o
n
2
)
+
c
o
s
(
l
o
n
1
)
∗
c
o
s
(
l
o
n
2
)
∗
c
o
s
(
l
a
t
2
−
l
a
t
1
)
)
d = R*acos(sin(lon_1)*sin(lon_2) + cos(lon_1)*cos(lon_2)*cos(lat_2-lat_1))
d=R∗acos(sin(lon1)∗sin(lon2)+cos(lon1)∗cos(lon2)∗cos(lat2−lat1))
其中:
R R R 是地球的半径,约为6371千米。
请注意,这个公式假设地球是一个完美的球形。实际上,地球的形状更像一个椭球,因此使用更精确的地理信息系统(GIS)软件或库(如proj.4或GeographicLib)可能会得到更准确的结果。
此外,经纬度通常以度为单位,但上述公式中的角度应被视为弧度。如果经纬度是以度数形式给出的,需要将其转换为弧度。可以通过将度数乘以π/180并取整数部分得到弧度值。例如,
30
°
30°
30°转换为弧度为
π
/
180
∗
30
π/180*30
π/180∗30。
2 代码实现
2.1 JavaScript
functioncalculateDistance(lat1, lon1, lat2, lon2){constR=6371;// 地球半径,单位为千米constrad=(angle)=> angle * Math.PI/180;// 将角度转换为弧度const lat1Rad =rad(lat1);const lon1Rad =rad(lon1);const lat2Rad =rad(lat2);const lon2Rad =rad(lon2);const dLat = lat2Rad - lat1Rad;const dLon = lon2Rad - lon1Rad;const a = Math.sin(dLat /2)* Math.sin(dLat /2)+
Math.cos(lat1Rad)* Math.cos(lat2Rad)*
Math.sin(dLon /2)* Math.sin(dLon /2);const c =2* Math.atan2(Math.sqrt(a), Math.sqrt(1- a));const distance =R* c;// 返回单位为千米的距离return distance;}// 示例用法const lat1 =39.9087;// 北京的经纬度const lon1 =116.4074;const lat2 =31.2304;// 上海的经纬度const lon2 =121.4737;const distance =calculateDistance(lat1, lon1, lat2, lon2);
console.log(distance);// 输出直线距离(单位:千米)
2.2 C++
#include<cmath>#include<iostream>// 计算两个经纬度之间的距离(单位:千米)doublecalculateDistance(double lat1,double lon1,double lat2,double lon2){constdouble R =6371;// 地球半径,单位为千米// 将经纬度转换为弧度double lat1Rad = std::atan(std::tan(lat1 *(M_PI /180))* std::cos(lon1 *(M_PI /180)));double lon1Rad = lon1 *(M_PI /180);double lat2Rad = std::atan(std::tan(lat2 *(M_PI /180))* std::cos(lon2 *(M_PI /180)));double lon2Rad = lon2 *(M_PI /180);// 计算两个经纬度之间的弧度差double dLat = lat2Rad - lat1Rad;double dLon = lon2Rad - lon1Rad;// 根据球面三角法公式计算距离double a = std::sin(dLat /2)* std::sin(dLat /2)+
std::cos(lat1Rad)* std::cos(lat2Rad)*
std::sin(dLon /2)* std::sin(dLon /2);double c =2* std::atan2(std::sqrt(a), std::sqrt(1- a));// 返回距离return R * c;}// 示例用法intmain(){double lat1 =39.9087;// 北京的经纬度double lon1 =116.4074;double lat2 =31.2304;// 上海的经纬度double lon2 =121.4737;double distance =calculateDistance(lat1, lon1, lat2, lon2);
std::cout <<"距离:"<< distance <<" 千米"<< std::endl;return0;}
请注意,此代码使用了C++标准库中的数学函数和常量。此外,将经纬度转换为弧度的方法需要使用std::atan和std::tan函数。
2.3 Python
import math
defcalculate_distance(lat1, lon1, lat2, lon2):
R =6371# 地球半径,单位为千米
rad =lambda angle: angle * math.pi /180# 将角度转换为弧度
lat1_rad = rad(lat1)
lon1_rad = rad(lon1)
lat2_rad = rad(lat2)
lon2_rad = rad(lon2)
dLat = lat2_rad - lat1_rad
dLon = lon2_rad - lon1_rad
a = math.sin(dLat /2)**2+ math.cos(lat1_rad)* math.cos(lat2_rad)* math.sin(dLon /2)**2
c =2* math.atan2(math.sqrt(a), math.sqrt(1- a))
distance = R * c # 返回单位为千米的距离return distance
# 示例用法
lat1 =39.9087# 北京的经纬度
lon1 =116.4074
lat2 =31.2304# 上海的经纬度
lon2 =121.4737
distance = calculate_distance(lat1, lon1, lat2, lon2)print(distance)# 输出直线距离(单位:千米)
请注意,由于Python和JavaScript之间的一些语法差异,需要使用math模块来进行数学计算。另外,由于Python中没有lambda函数的功能,因此需要使用普通的函数定义来代替。
2.4 MATLAB
function distance =calculateDistance(lat1, lon1, lat2, lon2)
const R =6371;% 地球半径,单位为千米
lat1Rad =rad(lat1);
lon1Rad =rad(lon1);
lat2Rad =rad(lat2);
lon2Rad =rad(lon2);
dLat = lat2Rad - lat1Rad;
dLon = lon2Rad - lon1Rad;
a =sin(dLat /2).^2+cos(lat1Rad).*cos(lat2Rad).*sin(dLon /2).^2;
c =2*atan2(sqrt(a),sqrt(1- a));
distance = R * c;% 返回单位为千米的距离end% 示例用法
lat1 =39.9087;% 北京的经纬度
lon1 =116.4074;
lat2 =31.2304;% 上海的经纬度
lon2 =121.4737;
distance =calculateDistance(lat1, lon1, lat2, lon2);disp(distance);% 输出直线距离(单位:千米)
请注意,MATLAB中的函数定义以function开头,输入参数以逗号分隔,输出结果使用变量名返回。此外,MATLAB中用.*表示元素之间的相乘,而^表示乘方。最后,使用disp函数输出结果。
版权归原作者 孙 悟 空 所有, 如有侵权,请联系我们删除。