根据2个经纬度点,计算这2个经纬度点之间的距离(通过经度纬度得到距离)

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

  • 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的度数值。

tan(<AOC) = tan(c)= AC/OC = sqrt(a)/sqrt(1-a)

则:

c = 2 * arctan(sqrt(a)/sqrt(1-a)),

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

distance = 2 * EARTH_RADIUS * c。

2)另外一种方法:

SQL Server本身是支持空间数据索引的(Spatial Indexing),具有空间数据计算能力。

他是通过一个扩展DLL Microsoft.SqlServer.Types.dll 来实现这些功能的。这是一个托管DLL,那意味着.NET C# asp.net 也可以使用些功能。

例如通过 reference 引用: Microsoft.SqlServer.Types.dll 这个dll。

var a = SqlGeography.Point(22.54587746 , 114.12873077, 4326); //上海的某个点
var b = SqlGeography.Point(23, 115, 4326); //上海的某个点,4236代表WGS84这种坐标参照系统。
Console.WriteLine(a.STDistance(b)); //距离

这个算出来的距离,与上面使用haversine公式算出的距离,误差在几米之内。

结束。

参考资料:

http://mathforum.org/library/drmath/view/51879.html

http://blog.charlee.li/location-search/

转载于:https://www.cnblogs.com/softfair/p/distance_of_two_latitude_and_longitude_points.html

根据2个经纬度点,计算这2个经纬度点之间的距离(通过经度纬度得到距离)相关推荐

  1. java根据2个经纬度点,计算这2个经纬度点之间的距离(通过经度纬度得到距离)

    最近做一个项目:需要查询一个站点(已知该站点经纬度)500米范围内的其它站点.所以,我首先想到的是,对每条记录,去进行遍历,跟数据库中的每一个点进行距离计算,当距离小于500米时,认为匹配.这样做确实 ...

  2. 已知两个点的经纬度,计算两个点之间的距离(两种办法)

    网上淘来了两种办法,一种是haversine公式,这个公式的算法在ubuntu下测试距离长测两个点,非常不准.(在我需要使用这个算法的芯片平台测试也不准,类似ubuntu平台的误差.在visual s ...

  3. 给定经纬度计算距离_通过经纬度坐标计算距离的方法(经纬度距离计算)ZZ

    通过经纬度坐标计算距离的方法(经纬度距离计算) 最近在网上搜索"通过经纬度坐标计算距离的方法",发现网上大部分都是如下的代码: #define PI 3.14159265 stat ...

  4. 通过经纬度坐标计算距离的方法(实为通过一个经纬度和距离角度求另一个经纬度)

    转自:https://www.cnblogs.com/softfair/p/lat_lon_distance_bearing_new_lat_lon.html 通过经纬度坐标计算距离的方法(经纬度距离 ...

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

    通过经纬度坐标计算距离的方法(经纬度距离计算) 最近在网上搜索"通过经纬度坐标计算距离的方法",发现网上大部分都是如下的代码: #define PI 3.14159265 stat ...

  6. 给你两个经纬度,计算他们之间的距离

    这些经纬线是怎样定出来的呢?地球是在不停地绕地轴旋转(地轴是一根通过地球南北两极和地球中心的假想线),在地球中腰画一个与地轴垂直的大圆圈,使圈上的每一点都和南北两极的距离相等,这个圆圈就叫作" ...

  7. 依据地图上的经纬度坐标计算某个点到多边形各边的距离

    http://www.th2w.com/article/85 依据地图上的经纬度坐标计算某个点到多边形各边的距离 最近公司有一个需求:依据地图上的经纬度坐标计算某个点到多边形各边的距离. 主要原理: ...

  8. matlab如何测两点的角度_根据2点经纬度,计算方位角,以及计算2条线的夹角

    以真北为0度起点,由东向南向西顺时针旋转360度,主要是用于控制象限. 根据2点经纬度,计算方位角 [csharp] /// /// 给定2点,获得经纬度 /// /// 起点经纬度,都是以度为单位 ...

  9. android地图方位角_Android获取经纬度、计算距离、方位角

    最近在Android上做GPS的东西,获取经纬度.计算距离.方位角,感觉在搞GIS样.当然,玩笑了,玩玩而已,稍微总结一下. 经度指示南北方向,纵向. 纬度指示东西方向,横向. 获取经纬度 使用GPS ...

最新文章

  1. java旅游网站毕业论文,基于JAVA技术的旅游网站的开发.doc
  2. 超高性能管线式HTTP请求(实践·原理·实现)
  3. Python学习心得第一周-03练习1
  4. Hibernate提高性能的几点建议
  5. Spring上传时报Invalid CSRF Token错误解决方案
  6. html为何转换为json,将HTML元素的“样式”属性转换为JSON
  7. 清爽娱乐网系统源码 v5.69
  8. 5行Python代码实现刷爆全网的动态条形图!
  9. 关于查询界面渲染问题
  10. AssertionError: Override list has odd length: [‘\r‘]; it must be a list of pairs
  11. 曙光服务器如何重新设置u盘启动_u盘装曙光服务器 曙光服务器进bios设置u盘启动...
  12. xmlDocument是什么?(转)
  13. 我的世界服务器卡无限刷物品,我的世界怎么刷物品 我的世界无限刷物品教程...
  14. python stdin.write_python – 将大量数据写入stdin
  15. Google Sanitizers
  16. 语音合成(TTS)论文优选:过平滑问题分析及优化Revisiting Over-Smoothness in Text to Speech
  17. 通过C#和Arduino实现软件示波器
  18. cadence 通孔焊盘_allegro通孔类焊盘的制作方法
  19. Flask框架(一)flak视图和URL
  20. 计算机突然需要管理者密码,为什么windows7旗舰版开启管理员帐号登录需要密码...

热门文章

  1. IE和FireFox中JS兼容之event .
  2. 类中的常成员函数的使用和定义
  3. 适合苹果平板的思维导图软件有哪些
  4. 学UI设计能从事哪些工作 如何学好UI设计
  5. Spring项目实践(三)--- Spring配置文件详解
  6. 这家的“鸭”流弊又性感!一般人我不告诉他
  7. 极速入门ILRuntime热更新
  8. npm WARN ajv-keywords@3.2.0 requires a peer of ajv@^6.0.0 but none is installed
  9. Python 递归函数 详解
  10. Nginx 配置数据库服务代理