根据经纬度计算地球上两点之间的距离——Haversine公式介绍及计算步骤
目录
摘要
1.半正矢公式(Haversine Formula)介绍
2.半正矢公式应用
3.半正矢公式计算
3.1 主要思路
3.2 计算步骤
3.2.1 平面向量计算方法
3.2.2 空间向量计算方法
摘要
写本文的出发点是需要在Qlik中根据经纬度计算地球上两点间的距离。我在社区上搜到了相关公式的分享,这个公式叫做“半正矢公式”。对于“半正矢”知之甚少的我,决定从头到尾将公式计算一遍,并通过这篇文章记录所有的步骤,希望它能对需要的人有所帮助。这也算是温习高中所学的三角函数了。
本文的部分图片源自其他网站,剩下的图都是通过GeoGebra制作的。这个工具非常方便,推荐大家使用。
(GeoGebra - the world’s favorite, free math tools used by over 100 million students and teachers)
1.半正矢公式(Haversine Formula)介绍
公式:
(i)
如图 (i), OAC是一个圆,O是其圆心,A和C是圆上的点,r 是⊙OAC的半径。
设:r = 1, 那么 OA = OC = r =1;
过点A做一条垂线,交线段OC于点B,∠OBA=90°。
设:∠AOB=θ;
因此,AB = sinθ, OB = cosθ, BC = 反正弦 = 1 – cosθ.
所谓的半正矢就是“一半的反正弦”(Haversine = “half reversed sin”),所以:
最后得出:
2.半正矢公式应用
回到应用场景,已知地球上的两个点A和B,现在我们想知道这两点之间的最短距离。地球可以近似看作为一个球体,那么AB间的最短距离就是过AB两点的大圆圆弧,这个大圆是地球的内切圆,半径和圆心点都于地球相同。
(ii)
设:A点坐标 = (Ø1, λ1); B点坐标 = (Ø2, λ2);
Ø = 纬度, λ = 经度
d = A 和 B 的最短距离
R = 地球半径 = 6371 km
把 替换为 Haversin(θ) 可得:
过去的水手们可以查余弦函数、半正矢函数和半正矢函数的逆函数的数值表,从而求出距离d。只要有数值表,还是挺方便的。[1]
[1]https://plus.maths.org/content/lost-lovely-haversine
3.半正矢公式计算
3.1 主要思路
(iii)
如图 (iii), ⊙OAB 是地球的内切圆,圆心为O。
距离计算步骤:
- 计算AB,即点A和B之间的直线距离;
- 通过AB和地球半径R,计算∠AOB 的角度;
- 通过∠AOB 和R计算 ,即⊙ OAB上AB的弧长,这个弧长就是最短距离。
3.2 计算步骤
3.2.1 平面向量计算方法
(iv)
与第2节相同,设:
A点坐标 = (Ø1, λ1); B点坐标 = (Ø2, λ2);
Ø = 纬度,λ = 经度;
d = AB间的最短距离;
R = 地球半径 = 6371 km;
O = 地球球心;
N = 北极点;
点C和E与点A在同一条经度线上;
点D和F与点B在同一条经度线上;
点D 与点A在同一条纬度线上;
点C 与点B在同一条纬度线上;
点E和F又是在赤道上,点A所在经度线与点B所在经度线相较于北极点。
可得:
C点坐标 = (Ø2, λ1); D点坐标 = (Ø1, λ2);
E点坐标 = (0, λ1); F点坐标 = (0, λ2);
引入 :
(v)
如图(v),OXY是一个圆,设r 为⊙OXY的半径,且r = 1;
OX = OY = r = 1, OZ是线段XY的垂线;
设∠XOY=θ,那么∠XOZ=∠YOZ=θ/2;
所以 XZ= , 且 XY=2XZ= 。
回到图 (iv), ∠AOC = Ø2 – Ø1;
因为 OA = OC =R,所以 AC = ;
同理,BD = AC;EF = ;
点O’ 是点A和点D所在圆的圆心,O’A 长度等于圆的半径。
过点A做一条垂线,相交OE于G,∠AOG = ∠AOE = Ø1;
所以 : ;
由于 ∠GOO’ = ∠AGO = 90°,OG = O’A,所以 O’A = ;
∠AO’D = λ2 – λ1, 可得 AD = ;
同理, BC = ;
知道AD和BC的长度后,我们在等腰梯形ADBC中就可以计算AB的长度了。
(vi)
在等腰梯形ADBC中,过点A做一条垂线相交BC于点E。
那么:
;
;
;
;
现在,AB线段的长度已经计算出来,接下来就是最后一步计算 的弧长。
(vii)
如图(vii),⊙OAB 是地球的内接圆,圆心为O,OA = R.
设:AC = √a, ∠AOB = b, ∠OCA = 90°;
那么 AC = AB/2;
;
;
;
;
;
把 替换为 Haversin(θ) :
与第二节的公式一致,计算完毕。
或者我们可以用正切函数tan:
这与Qlik 社区分享的计算公式一致[2]。
[2] https://community.qlik.com/t5/QlikView-App-Dev/Haversine-formula-to-find-distance-between-two-lat-long-points/m-p/234630
3.2.2 空间向量计算方法
如通过空间向量计算距离,我们需要把经纬度的坐标转换为三维空间坐标。
如图 (viii),我们建立了一个坐标系,Z轴就是地轴所在的轴,平面XOY是赤道所在的平面,平面XOZ是本初子午线所在的平面。A点是地球上任意一点。
设:A点坐标 = (Ø1, λ1),R是地球半径;
A 点的空间坐标 = (X1, Y1, Z1)
(viii)
过A点做一条垂线相交平面XOY于A’点,则:
;
X1 = OC, Y1 = CA’, Z1 = A’A
因此, ;
同理,我们有一点 B (Ø2, λ2),则 ;
那么:
设 ,那么我们可通过余弦定理计算θ 的值:
把cos(θ) 替换为 Haversin(θ),结果与上文等价。
参考文章
Haversine formula to find distance between two lat... - Qlik Community - 234630
Lost but lovely: The haversine | plus.maths.org
地理空间距离计算及优化(根据两个点经纬度计算距离)_ArthurKingYs的博客-CSDN博客_两个经纬度算距离公式及方法
半正矢公式(Haversine公式)
如何计算地球上两点的距离(附公式推导)_呆呆papa的博客-CSDN博客_地球两点距离
根据经纬度计算地球上两点之间的距离——Haversine公式介绍及计算步骤相关推荐
- php 计算两点时间距离,PHP计算地球上两点之间的距离(示例详解)
给定经度和纬度,求地球上两点之间的距离.首先我们需要了解该问题的解决思路,然后再用PHP代码来实现计算. 此问题可以用半正矢(haversine)公式求解: 大圆距离或正交距离是球面(或地球表面)上两 ...
- 给定经纬度计算距离_根据经纬度计算地球上两点之间的距离js实现代码
利用JS实现的根据经纬度计算地球上两点之间的距离 最近用到了根据经纬度计算地球表面两点间距离的公式,然后就用JS实现了一下. 计算地球表面两点间的距离大概有两种办法. 第一种是默认地球是一个光滑的球面 ...
- 计算地球上两点之间的俯仰角和方位角
源代码:https://gitee.com/gnoyuin/jiaodu https://github.com/niuyong/jiaodu
- php 地图两点距离计算,计算地图上两点间的距离PHP类
计算地图上两点间的距离,使用的是谷歌地图 class GeoHelper { /** * @param int $lat1 * @param int $lon1 * @param int $lat2 ...
- python 计算流形上两点之间的测地距离
在分析数据时,有时要计算流形上两点之间的测地距离.本着有现成轮子绝对不自己写的观点,发现可以通过以下方式计算流形上任意两点之间的测地距离. ISOMAP是一种保持测地距离不变的高维空间中低维流形的降维 ...
- 计算地球上两点距离(震中距)的Matlab函数(兼容度数和度分秒)及另外三种方法
目录 写在前面 方法1: taup 方法2: ObsPy 方法3: Mapping Toolbox的distance函数 方法4: 自己写的Matlab函数 参数 公式 函数 写在前面 最近要计算震中 ...
- 通过经纬度计算两点之间的距离的公式
通过经纬度计算两点之间距离的常用公式如下: 设点 A 的纬度为 $lat_A$,经度为 $lon_A$,点 B 的纬度为 $lat_B$,经度为 $lon_B$,则两点之间的距离 $d$ 为: $d ...
- 如何求地球上两点之间的最短距离_例谈平行线上两动点之间距离最短问题
初中几何中有一类关于距离最短的问题,这些问题最终都会转化为"垂线段最短"或"两点之间线段最短".本文就一类平行线上两动点之间距离最短问题,谈谈笔者对此的分析和见 ...
- 如何求地球上两点之间的最短距离_初中数学求线段之和最小的问题,知识点题型汇总...
我们经常在考试当中看到求线段之和最小的问题,首先来看下这几个数学模型: 模型1:两点之间线段最短 要在l找点P,使得PA+PB最短,这模型最简单,两点之间线段最短. 模型2:将军饮马问题 在l上找一点 ...
最新文章
- 在 Linux 下确认 NTP 是否同步的方法
- 使用logrotate做nginx日志分割
- docker image aarch64 x86_64_「docker」交叉编译适用于ARM平台的Docker源码
- Java中判断两个Date时间段是否有交集的方法
- tensorflow RNN循环神经网络 (分类例子)-【老鱼学tensorflow】
- FOSCommentBundle功能包:基于ACL安全添加角色
- 总结:第一章~第五章
- 一个简单的jQuery插件ajaxfileupload实现ajax上传文件例子
- composer安装laravel-u-editor及其使用
- pytorch根据特征图训练LSTM Stacked AutoEncoder
- 大数据支撑健康医疗服务落地
- Spark 任务参数配置
- 搜索c盘大文件_硬核干货,如何给c盘“减肥”?
- 向jre中添加安全证书
- 熊博士c语言,InstallShield2015制作安装包----------安装后实现电脑开机自启动
- excel计算加权和
- 尹语堂®公益20210906
- 基于NT98530的多目VR摄像机方案,多sensor同步,多sensor防抖,PTP校时,实景SLAM数字孪生的最佳搭档。
- html页分割线最简单的实现方式
- 同样是程序员 为什么薪资不同