计算经纬度点之间的距离

article/2025/8/27 9:56:35

球面上任意两点之间的距离计算公式可以参考维基百科上的下述文章。

  • Great-circle distance

  • Haversine formula

值得一提的是,维基百科推荐使用Haversine公式,理由是Great-circle distance公式用到了大量余弦函数, 而两点间距离很短时(比如地球表面上相距几百米的两点),余弦函数会得出0.999...的结果, 会导致较大的舍入误差。而Haversine公式采用了正弦函数,即使距离很小,也能保持足够的有效数字。 以前采用三角函数表计算时的确会有这个问题,但经过实际验证,采用计算机来计算时,两个公式的区别不大。 稳妥起见,这里还是采用Haversine公式。

 

其中

 

  • R为地球半径,可取平均值 6371km;
  • φ1, φ2 表示两点的纬度;
  • Δλ 表示两点经度的差值。

根据2个经纬度坐标,距离计算函数

下面就是计算球面间两点(lat1, lon1) - (lat2, lon2)之间距离的函数。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace HarvenSin
{class Program{/// <summary>/// 根据经纬度,计算2个点之间的距离。/// </summary>/// <param name="args"></param>static void Main(string[] args){//39.94607,116.32793  31.24063,121.42575Console.WriteLine(Distance(39.94607, 116.32793, 31.24063, 121.42575));}public static double HaverSin(double theta){var v = Math.Sin(theta / 2);return v * v;}static double EARTH_RADIUS = 6371.0;//km 地球半径 平均值,千米/// <summary>/// 给定的经度1,纬度1;经度2,纬度2. 计算2个经纬度之间的距离。/// </summary>/// <param name="lat1">经度1</param>/// <param name="lon1">纬度1</param>/// <param name="lat2">经度2</param>/// <param name="lon2">纬度2</param>/// <returns>距离(公里、千米)</returns>public static double Distance(double lat1,double lon1, double lat2,double lon2){//用haversine公式计算球面两点间的距离。//经纬度转换成弧度lat1 = ConvertDegreesToRadians(lat1);lon1 = ConvertDegreesToRadians(lon1);lat2 = ConvertDegreesToRadians(lat2);lon2 = ConvertDegreesToRadians(lon2);//差值var vLon = Math.Abs(lon1 - lon2);var vLat = Math.Abs(lat1 - lat2);//h is the great circle distance in radians, great circle就是一个球体上的切面,它的圆心即是球心的一个周长最大的圆。var h = HaverSin(vLat) + Math.Cos(lat1) * Math.Cos(lat2) * HaverSin(vLon);var distance = 2 * EARTH_RADIUS * Math.Asin(Math.Sqrt(h));return distance;}/// <summary>/// 将角度换算为弧度。/// </summary>/// <param name="degrees">角度</param>/// <returns>弧度</returns>public static double ConvertDegreesToRadians(double degrees){return degrees * Math.PI / 180;}public static double ConvertRadiansToDegrees(double radian){return radian * 180.0 / Math.PI;}}
}

 

公式来历:

VERSINE(F)=1-cos(F)

 

 

Haversine名字来历是Ha-VERSINE,即Half-Versine ,表示sin的一半的意思。

 

hav(A) = (1-cos(A))/2 = sin(A/2)* sin(A/2)

 

推倒过程:

 

如下一个半径为1 的圆,O是圆心,A、B是弦(chord)。角度AOB=theta。则角度AOC=theta/2。OC是垂直于AB的垂线(perpendicular)。AC长度是sin(theta/2),AB长度是2*sin(theta/2)。

(图1)

如下地球图所示,假设半径R为1,O是球心,A (lat1,lon1) 和 B (lat2,lon2) 是我们感兴趣的2个点。2跟经度线 lon1,lon2相交于北极(north pole)N。EF所在的线是赤道(equator)。ACBD是平面上的等腰梯形的四个顶点(vertice)。AC和DB的弦(直线)在图上没有画出。CD的位置是:C (lat2,lon1) and D (lat1,lon2)。角度AOC是A点与C点的纬度差 dlat。角度EOF是经度E点和经度F点的差dlon。

 

 

(图2)

弦AC的长度,参照图1的方式,那么是AC=2*sin(dlat/2),弦BD也是一样的长度。

E、F 2个点是赤道上的2个点,它们的纬度是0。EF的距离是EF=2*sin(dlon/2)

A、D2个点所在的纬度是lat1。AD所在纬度的圆平面的半径是cos(lat1)。从A作一条垂线(perpendicular)到OE为AG,AO是球半径,则OG=cos(lat1),即A、D所在纬度圆圈的半径(AO`)。

这时候,AD的弦长AD= 2*sin(dlon/2)*cos(lat1),类似的可以推出CB的长度= CB=2*sin(dlon/2)*cos(lat2)

 

下面看一下如何求AB的长度,回到平面等腰梯形,如下图:

 

(图3)

AH是到CB的垂线(perpendicular),CH= (CB-AD)/2。

根据勾股定理(Pythagorean theorem): 【^2表示2的平方】

AH^2 = AC^2 - CH^2

       = AC^2 - (CB-AD)^2/4

 

HB 的长度是HB=AD+CH = AD+(CB-AD)/2 = (CB+AD)/2,根据勾股定理得到:

  AB^2 = AH^2 + HB^2

       = AC^2 - (CB-AD)^2/4 + (CB+AD)^2/4

       = AC^2 + CB*AD

根据前面球面上的求经纬距离的方式,我们已经得到 AC、AD和CB的长度,代入公式得到:

 

  AB^2 = 4*(sin^2(dlat/2) + 4*cos(lat1)*cos(lat2)*sin^2(dlon/2))

 

假设中间值h 是AB长度一半的平方,如下

 

  h = (AB/2)^2

    = (sin^2(dlat/2)) + cos(lat1) * cos(lat2) * sin^2(dlon/2)

  (请参看代码里的h)

最后一步,是求得代表AB长度的角度AOB。参照图1的方式,我们可以知道

(图4)

设AC=,根据勾股定理(Pythagorean theorem)得到:

OC= = sqrt(OA^2 - AC^2)

         = = sqrt(1-a)   // sqrt表示开根号

 

如果设c是角AOB的度数值。

sin(AOC) = AC/OA = sqrt(a)

则:

c = ∠AOB = asin(sqrt(a)) * 2

最后的AB真实距离,把地球半径带上就可以了。

distance = 2 * EARTH_RADIUS * c。

由于在最上面的求解中,

h = (AB/2)^2

    = (sin^2(dlat/2)) + cos(lat1) * cos(lat2) * sin^2(dlon/2)

sqrt(a)*2= AB && h = (AB/2)^2

=> a = h

var distance = 2 * EARTH_RADIUS * Math.Asin(Math.Sqrt(h));


http://chatgpt.dhexx.cn/article/BFH0NeiW.shtml

相关文章

计算两个经纬度的距离

一 点睛 计算两个经纬度的距离的方法这里提供两种。 1 基于 googleMap 中的算法得到两经纬度之间的距离&#xff0c;计算精度与谷歌地图的距离精度差不多。 2 计算中心经纬度与目标经纬度的距离(米) 二 代码 public class LongitudeLatitude {/*** 默认地球半径*/private …

根据两点经纬度计算距离

根据两点经纬度计算距离 这些经纬线是怎样定出来的呢&#xff1f;地球是在不停地绕地轴旋转&#xff08;地轴是一根通过地球南北两极和地球中心的 假想线&#xff09;&#xff0c;在地球中腰画一个与地轴垂直的大圆圈&#xff0c;使圈上的每一点都和南北两极的距离相等&#xf…

通过经纬度坐标计算距离的方法(经纬度距离计算)

通过经纬度坐标计算距离的方法&#xff08;经纬度距离计算&#xff09; 最近在网上搜索“通过经纬度坐标计算距离的方法”&#xff0c;发现网上大部分都是如下的代码&#xff1a; #define PI 3.14159265 static double Rc 6378137; // 赤道半径 static double Rj 635672…

根据经纬度计算两点之间的距离

前言 在我们平时使用美团&#xff0c;饿了么等app进行订餐&#xff0c;或者使用猫眼进行订电影票的时候&#xff0c;都有一个距离的排序&#xff0c;表明该家店距离我们当前的位置&#xff0c;这种基于地理位置的服务&#xff0c;统一被称为LBS&#xff08;Location Based Ser…

logistic模型原理与推导过程分析(1)

从线性分类器谈起 给定一些数据集合&#xff0c;他们分别属于两个不同的类别。例如对于广告数据来说&#xff0c;是典型的二分类问题&#xff0c;一般将被点击的数据称为正样本&#xff0c;没被点击的数据称为负样本。现在我们要找到一个线性分类器&#xff0c;将这些数据分为两…

阻滞增长模型--Logistic模型

文章目录 写在前面一、思路二、原始数据三、源代码四、结果 写在前面 做了一个作业&#xff0c;觉得挺有意思&#xff0c;有空就发上来了。 阻滞增长模型–Logistic模型的部分推导、思路&#xff0c;并给出参考代码。 参考书籍&#xff1a;《数学模型》第四版&#xff0c;姜启…

logistic模型原理与推导过程分析(2)

二项逻辑回归模型 既然logistic回归把结果压缩到连续的区间(0,1)&#xff0c;而不是离散的0或者1&#xff0c;然后我们可以取定一个阈值&#xff0c;通常以0.5为阈值&#xff0c;如果计算出来的概率大于0.5&#xff0c;则将结果归为一类&#xff08;1&#xff09;&#xff0c;…

从logit变换到logistic模型

从logit变换到logistic模型 logit变换几率logistic模型 前面我们知道对数函数和对数函数的一些基本性质&#xff0c;也许你会问&#xff0c;为什么要引入对数函数&#xff1f;而且还是一个基本初等函数&#xff1f;这就要从logit变换说起。 logit变换 我们在研究某一结果&…

Gompertz模型绘图 matlab,Logistic模型matlab求解

Logistic模型求解怎么用matlab求解啊&#xff1f; 悬赏分&#xff1a;100 - 解决时间&#xff1a;2008-11-17 23:09 已知 x0:1:12 y[43.65 109.86 187.21 312.67 496.58 707.65 960.25 1238.75 1560.00 1824.29 2199.00 2438.89 2737.71] yL/(1a*exp(-k*x)) 利用线性回归模型所…

数学建模-Logistic模型

文章目录 Malthus模型模型假设建模与求解模型评价 Logistic模型模型假设建模与求解模型检验 为了更好地理解Logistic模型&#xff0c;我们先看看Malthus模型 Malthus模型 这是英国神父Malthus通过对一百多年人口统计资料的分析之后提出的人口模型假设 模型假设 设x(t)表示t时…

数学建模-Logistic模型附Matlab代码

目录 一、Logistic模型介绍 二、Logistic模型实例 三、Logistic模型原理 3.1 Logistic 方程定义 3.2 Yule算法 3.2 Rhodes算法 3.3 Nair算法 4、Logistic模型Matlab部分代码 4.1 Yule算法 4.2 Rhodes算法 4.3 Nair算法 一、Logistic模型介绍 logistic回归又称logi…

logistic回归模型—基于R

logistic回归模型—基于R 数据理解和准备一. 对缺失值的处理二.虚拟变量的赋值三.箱线图四.相关性分析 训练集与测试集的划分模型构建与评价一.logistic回归模型二.检查模型在训练数据集和测试数据集上的表现使用交叉验证的logistic回归 logistic回归又称logistic回归分析&…

数学模型——Logistic回归模型(含Matlab代码)

写在前面 Logistic回归模型是一种非常常见的统计回归模型&#xff0c;在处理大量数据&#xff0c;揭示各自变量如何作用于因变量&#xff08;描述X与Y之间的关系&#xff09;时有着十分重要的作用。笔者在写Logit回归模型前参加了一次市场调研比赛&#xff0c;在这次比赛中学到…

菜鸟的数学建模之路(五):Logistic模型

matlab实现 Logistic回归跟多元线性回归差不多&#xff0c;但是有区别&#xff1a; &#xff08;1&#xff09; 线性回归&#xff1a;y是一个定量的变量&#xff0c;这时y对于不同的自变量来说有相应的值。 &#xff08;2&#xff09; Logistic回归&#xff1a;y是一个定性的变…

自学鸿蒙应用开发(25)- 基本的CommonDialog

动作演示 对话框是应用程序的主要输入手段之一&#xff0c;但是遗憾的是目前鸿蒙的开发网站上只有ToastDialog用法&#xff0c;其他类型的对话框则只能参考为数不多的英文文档。 以下是作者经过不断尝试&#xff0c;终于鼓捣出来的CommonDialog对话框。 CommonDialog1 代码实…

Builder设计模式构建通用型Dialog

目录 写在前面 一、什么是Builder模式 二、AlertDialog源码分析 2.1、源码阅读 2.2、Builder模式工作流程 三、代码实战——Builder模式构建通用型Dialog 3.1、基本框架搭建 3.2、完善Builder 3.3、完善真正的构建器 3.4、自定义参数配置 四、使用Dialog 写在前面 …

自学鸿蒙应用开发(26)- 自定义CommonDialog

执行效果 上一篇文章中说过&#xff0c;直接使用鸿蒙系统中的CommonDialog大致是下面的效果&#xff1a; 这个效果实在是无法用于实际的应用开发。本文介绍如何定制自己的CommonDialog。还是先看演示视频&#xff1a; CustomizeCommonDialog 准备布局 定制CommonDialog的第一…

Android炫酷翻转Dialog及高仿苹果IOS的Dialog

简单的Android弹出Dialog效果&#xff08;圆角&#xff09; 最近一段时间工作挺忙的&#xff0c;一直想写一篇博文&#xff0c;总是被各种事情打破计划&#xff0c;终于这次利用这个周末来开始自己第一次的技术文章的写作&#xff0c;提前说明&#xff0c;本人还是个菜鸟&#…

Android 全局Dialog

前沿 android 弹窗好几种&#xff0c;全局弹窗是什么&#xff1f;和普通Dialog&#xff08;必须依附activity上下文的弹窗&#xff09;有什么区别&#xff1f; 逛技术blog发现【全局dialog】这个名词&#xff0c;之前用FragmentDialog&#xff0c;自定义dialog。以及dialog的…

Android开发dialog内存泄露,Android中导致内存泄漏的竟然是它----Dialog

一. 内存泄漏的 Bug 猛增 最近在 App 进行 mokey 测试的时候检测到一些内存泄漏问题。在前天的测试中,楼主一瞬间收到了4个这样的 Bug 单,瞬间心理无比纠结,真有千万只羊驼向我奔来。 登录页面出现内存泄漏??!!楼主的代码是如此的***而无懈可击,这么可能出现这么多泄漏的…