IOS 计算两个经纬度之间的距离

一 丶

-(double)distanceBetweenOrderBy:(double) lat1 :(double) lat2 :(double) lng1 :(double) lng2{

           CLLocation *curLocation = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1];

           CLLocation *otherLocation = [[CLLocation alloc] initWithLatitude:lat2 longitude:lng2];

            double  distance  = [curLocation distanceFromLocation:otherLocation];

            return  distance;

}

二丶

//将角度转为弧度

+ (float)radians:(float)degrees{

return (degrees*3.14159265)/180.0;

}

//根据经纬度换算出直线距离

+ (float)getDistance:(float)lat1 lng1:(float)lng1 lat2:(float)lat2 lng2:(float)lng2

{

//地球半径

int R = 6378137;

//将角度转为弧度

float radLat1 = [self radians:lat1];

float radLat2 = [self radians:lat2];

float radLng1 = [self radians:lng1];

float radLng2 = [self radians:lng2];

//结果

float s = acos(cos(radLat1)*cos(radLat2)*cos(radLng1-radLng2)+sin(radLat1)*sin(radLat2))*R;

//精度

s = round(s* 10000)/10000;

return  round(s);

}

经纬度简介

这些经纬线是怎样定出来的呢?地球是在不停地绕地轴旋转(地轴是一根通过地球南北两极和地球中心的
假想线),在地球中腰画一个与地轴垂直的大圆圈,使圈上的每一点都和南北两极的距离相等,这个圆圈
就叫作“赤道”。在赤道的南北两边,画出许多和赤道平行的圆圈,就是“纬圈”;构成这些圆圈的线段,
叫做纬线。我们把赤道定为纬度零度,向南向北各为90度,在赤道以南的叫南纬,在赤道以北的叫北纬。
北极就是北纬90度,南极就是南纬90度。纬度的高低也标志着气候的冷热,如赤道和低纬度地地区无冬,
两极和高纬度地区无夏,中纬度地区四季分明。 
其次,从北极点到南极点,可以画出许多南北方向的与地球赤道垂直的大圆圈,这叫作“经圈”;构成这
些圆圈的线段,就叫经线。公元1884平面坐标图年,国际上规定以通过英国伦敦近郊的格林尼治天文台的
经线作为计算经度的起点,即经度零度零分零秒,也称“本初子午线”。在它东面的为东经,共180度;
在它西面的为西经,共180度。因为地球是圆的,所以东经180度和西经180度的经线是同一条经线。各国
公定180度经线为“国际日期变更线”。为了避免同一地区使用两个不同的日期,国际日期变线在遇陆地时
略有偏离。 
  每一经度和纬度还可以再细分为60分,每一分再分为60秒以及秒的小数。利用经纬线,我们就可以确定
地球上每一个地方的具体位置,并且把它在地图或地球仪上表示出来。例如问北京的经纬度是多少?我们
很容易从地图上查出来是东经116度24分,北纬39度54分。在大海中航行的船只,只要把所在地的经度测
出来,就可以确定船在海洋中的位置和前进方向。 纬度共有90度。赤道为0度,向两极排列,圈子越小,
度数越大。
横线是纬度,竖线是经度。 
当然可以计算,四元二次方程。 
经度和纬度都是一种角度。经度是个两面角,是两个经线平面的夹角。因所有经线都是一样长,为了度量
经度选取一个起点面,经1884年国际会议协商,决定以通过英国伦敦近郊、泰晤士河南岸的格林尼治皇家
天文台(旧址)的一台主要子午仪十字丝的那条经线为起始经线,称为本初子午线。本初子午线平面是起
点面,终点面是本地经线平面。某一点的经度,就是该点所在的经线平面与本初子午线平面间的夹角。在
赤道上度量,自本初子午线平面作为起点面,分别往东往西度量,往东量值称为东经度,往西量值称为西
经度。由此可见,一地的经度是该地对于本初子午线的方向和角距离。本初子午线是0°经度,东经度的最
大值为180°,西经度的最大值为180°,东、西经180°经线是同一根经线,因此不分东经或西经,而统称
180°经线。 
  纬度是个线面角。起点面是赤道平面,线是本地的地面法线。所谓法线,即垂直于参考扁球体表面的线。
某地的纬度就是该地的法线与赤道平面之间的夹角。纬度在本地经线上度量,由赤道向南、北度量,向北
量值称为北纬度,向南量值称为南纬度。由此可见,一地的纬度是该地对于赤道的方向和角距离。赤道是
0°纬线,北纬度的最大值为90°,即北极点;南纬度的最大值为90°,即南极点。
经纬度互换

度换算成度分秒

度(DDD):E 108.90593度    N 34.21630度
 如何将度(DDD):: 108.90593度换算成度分秒(DMS)东经E 108度54分22.2秒?转换方法是将108.90593整数位不变取108(度),用0.90593*60=54.3558,取整数位54(分),0.3558*60=21.348再取整数位21(秒),故转化为108度54分21秒.
同样将度分秒(DMS):东经E 108度54分22.2秒 换算成度(DDD)的方法如下:108度54分22.2秒=108+(54/60)+(22.2/3600)=108.90616度
因为计算时小数位保留的原因,导致正反计算存在一定误差,但误差影响不是很大。1秒的误差就是几米的样子。GPS车友可以用上述方法换算成自己需要的单位坐标。
 
 
关于经纬度十进制表示法
对于两个点,在纬度相等的情况下:
经度每隔0.00001度,距离相差约1米;每隔0.0001度,距离相差约10米;每隔0.001度,距离相差约100米;每隔0.01度,距离相差约1000米;每隔0.1度,距离相差约10000米。

对于两个点,在经度相等的情况下:
纬度每隔0.00001度,距离相差约1.1米;每隔0.0001度,距离相差约11米;每隔0.001度,距离相差约111米;每隔0.01度,距离相差约1113米;每隔0.1度,距离相差约11132米。

 
 
 
 
 
根据地球上任意两点的经纬度计算两点间的距离
 
方法1:由于地球是椭球体,这个太难算了,如果假设地球是球体,可以使用以下公式:设地球上某点的经度为A,纬度为B, 则这点的空间坐标是 x=cos(B)*cos(A) y=cos(B)*sin(A) z=sin(B) 设地球上两点的空间坐标分别为(x1,y1,z1),(x2,y2,z2) 则它们的夹角为 C=acos(x1*x2+y1*y2+z1*z2),C是角度 则两地距离为 C/180*pi*R,其中R为地球平均半径6371 误差不超过1% 
 
地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为 6356.755千米,平均半径6371.004千米。如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R。如果以0度经线为基 准,那么根据地球表面任意两点的经纬度就可以计算出这两点间的地表距离(这里忽略地球表面地形对计算带来的误差,仅仅是理论上的估算值)。设第一点A的经 纬度为(LonA, LatA),第二点B的经纬度为(LonB, LatB),按照0度经线的基准,东经取经度的正值(Longitude),西经取经度负值(-Longitude),北纬取90-纬度值(90- Latitude),南纬取90+纬度值(90+Latitude),则经过上述处理过后的两点被计为(MLonA, MLatA)和(MLonB, MLatB)。那么根据三角推导,可以得到计算两点距离的如下公式:

C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB)

Distance = R*Arccos(C)*Pi/180

 
这里,R和Distance单位是相同,如果是采用6371.004千米作为半径,那么Distance就是千米为单位,如果要使用其他单位,比如mile,还需要做单位换算,1千米=0.621371192mile
如果仅对经度作正负的处理,而不对纬度作90-Latitude(假设都是北半球,南半球只有澳洲具有应用意义)的处理,那么公式将是:
C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)*cos(MLonA-MLonB)
Distance = R*Arccos(C)*Pi/180
以上通过简单的三角变换就可以推出。
如果三角函数的输入和输出都采用弧度值,那么公式还可以写作:
 
C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)
Distance = R*Arccos(C)*Pi/180
也就是:
C = sin(LatA/57.2958)*sin(LatB/57.2958) + cos(LatA/57.2958)*cos(LatB/57.2958)*cos((MLonA-MLonB)/57.2958)
Distance = R*Arccos(C) = 6371.004*Arccos(C) kilometer = 0.621371192*6371.004*Arccos(C) mile = 3958.758349716768*Arccos(C) mile
  1. <span style="font-size:14px;font-weight: normal;">  private static final  double EARTH_RADIUS = 6378137;//赤道半径(单位m)
  2. /**
  3. * 转化为弧度(rad)
  4. * */
  5. private static double rad(double d)
  6. {
  7. return d * Math.PI / 180.0;
  8. }
  9. /**
  10. * 基于余弦定理求两经纬度距离
  11. * @param lon1 第一点的精度
  12. * @param lat1 第一点的纬度
  13. * @param lon2 第二点的精度
  14. * @param lat3 第二点的纬度
  15. * @return 返回的距离,单位km
  16. * */
  17. public static double LantitudeLongitudeDist(double lon1, double lat1,double lon2, double lat2) {
  18. double radLat1 = rad(lat1);
  19. double radLat2 = rad(lat2);
  20. double radLon1 = rad(lon1);
  21. double radLon2 = rad(lon2);
  22. if (radLat1 < 0)
  23. radLat1 = Math.PI / 2 + Math.abs(radLat1);// south
  24. if (radLat1 > 0)
  25. radLat1 = Math.PI / 2 - Math.abs(radLat1);// north
  26. if (radLon1 < 0)
  27. radLon1 = Math.PI * 2 - Math.abs(radLon1);// west
  28. if (radLat2 < 0)
  29. radLat2 = Math.PI / 2 + Math.abs(radLat2);// south
  30. if (radLat2 > 0)
  31. radLat2 = Math.PI / 2 - Math.abs(radLat2);// north
  32. if (radLon2 < 0)
  33. radLon2 = Math.PI * 2 - Math.abs(radLon2);// west
  34. double x1 = EARTH_RADIUS * Math.cos(radLon1) * Math.sin(radLat1);
  35. double y1 = EARTH_RADIUS * Math.sin(radLon1) * Math.sin(radLat1);
  36. double z1 = EARTH_RADIUS * Math.cos(radLat1);
  37. double x2 = EARTH_RADIUS * Math.cos(radLon2) * Math.sin(radLat2);
  38. double y2 = EARTH_RADIUS * Math.sin(radLon2) * Math.sin(radLat2);
  39. double z2 = EARTH_RADIUS * Math.cos(radLat2);
  40. double d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)+ (z1 - z2) * (z1 - z2));
  41. //余弦定理求夹角
  42. double theta = Math.acos((EARTH_RADIUS * EARTH_RADIUS + EARTH_RADIUS * EARTH_RADIUS - d * d) / (2 * EARTH_RADIUS * EARTH_RADIUS));
  43. double dist = theta * EARTH_RADIUS;
  44. return dist;
  45. }</span>
 
 
方法2:google地图提供的方法:

对上面的公式解释如下:
1.Lat1 Lung1 表示A点经纬度,Lat2 Lung2 表示B点经纬度;
2.a=Lat1 – Lat2 为两点纬度之差  b=Lung1 -Lung2 为两点经度之差;
3.6378.137为地球半径,单位为千米;
计算出来的结果单位为千米,若将半径改为米为单位则计算的结果单位为米。
计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下。

  1. <span style="font-size:14px;">  private static final  double EARTH_RADIUS = 6378137;//赤道半径(单位m)
  2. /**
  3. * 转化为弧度(rad)
  4. * */
  5. private static double rad(double d)
  6. {
  7. return d * Math.PI / 180.0;
  8. }
  9. /**
  10. * 基于googleMap中的算法得到两经纬度之间的距离,计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下
  11. * @param lon1 第一点的精度
  12. * @param lat1 第一点的纬度
  13. * @param lon2 第二点的精度
  14. * @param lat3 第二点的纬度
  15. * @return 返回的距离,单位km
  16. * */
  17. public static double GetDistance(double lon1,double lat1,double lon2, double lat2)
  18. {
  19. double radLat1 = rad(lat1);
  20. double radLat2 = rad(lat2);
  21. double a = radLat1 - radLat2;
  22. double b = rad(lon1) - rad(lon2);
  23. double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2)+Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
  24. s = s * EARTH_RADIUS;
  25. //s = Math.round(s * 10000) / 10000;
  26. return s;
  27. }</span>

IOS 计算两个经纬度之间的距离的更多相关文章

  1. 计算两个经纬度之间的距离(python算法)

    EARTH_REDIUS = 6378.137 def rad(d): return d * pi / 180.0 def getDistance(lat1, lng1, lat2, lng2): r ...

  2. reactjs中使用高德地图计算两个经纬度之间的距离

    第一步下载依赖 npm install --save react-amap 第二步,在组件中使用 import React, { Component } from 'react' import { L ...

  3. iOS 计算两个坐标之间的距离

    //第一个坐标 CLLocation *before=[[CLLocation alloc] initWithLatitude:29.553968 longitude:106.538872]; //第 ...

  4. java计算两个经纬度之间的距离

    /** * 计算点 是否在一个固定点的半径范围内 * @2016年10月20日 * @param a 经度1 已知 * @param b 纬度1 已知 * @param x 经度2 * @param ...

  5. java如何计算两个经纬度之间的距离?

    /*计算两个经纬度之间的距离 结果单位:米 */public static double getDistance(String lat1Str, String lng1Str, String lat2 ...

  6. 高德地图 API 计算两个城市之间的距离

    1. 目前在项目中,遇到一个需求不会做,就是要计算两个城市之间的距离,而这两个城市的输入是可变的,如果要使用数据库来先存储两地之间的距离,调用的时候再来调用,那么存数据的时候,要哭的,因为光是省级区域 ...

  7. Java计算两个经纬度间的距离最简单的方式

    开发中经常会遇到计算两个点(经纬度)之间的距离或者计算最近门店的场景,下面简单实现一下如何计算两个经纬度之间相隔的距离. 1.导入geodesy的maven依赖 或者到阿里云maven仓库下载jar包 ...

  8. PHP MYSQL 搜索周边坐标,并计算两个点之间的距离

    搜索附近地点,例如,坐标(39.91, 116.37)附近500米内的人,首先算出“给定坐标附近500米”这个范围的坐标范围. 虽然它是个圆,但我们可以先求出该圆的外接正方形,然后拿正方形的经纬度范围 ...

  9. iOS 计算两个日期之间的天数问题

    //获取当前时间若干年.月.日之后的时间 + (NSDate *)dateWithFromDate:(NSDate *)date years:(NSInteger)years months:(NSIn ...

随机推荐

  1. oracle11G在linux环境下的卸载操作

    1.使用SQL*PLUS停止数据库[oracle@OracleTest oracle]$ sqlplus logSQL> connect / as sysdbaSQL> shutdown ...

  2. Ubuntu 12.04 DNS服务器的配置方法

    Bind是一款开放源码的DNS服务器软件,由美国加州大学Berkeley分校开发和维护的,全名为Berkeley Internet Name Domain它是目前世界上使用最为广泛的DNS服务器软件, ...

  3. css中元素居中总结

    很多时候,我们需要让元素居中显示:1. 一段文本的水平居中,2. 一张图片的水平居中,3. 一个块级元素的水平居中:4. 单行文本的竖直居中,5. 不确定高度的一段文本竖直居中,6. 确定高度的块级元 ...

  4. 利用OpenCV检测图像中的长方形画布或纸张并提取图像内容

    基于知乎上的一个答案.问题如下: 也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢 ...

  5. Django数据库怎么给字段设置主键

    id = models.IntegerField(primary_key = True) 附: null :缺省设置为false.通常不将其用于字符型字段上,比如CharField,TextField ...

  6. [Editor]Unity Editor类常用方法

    Editor文档资料 Unity教程之-Unity Attribute的使用总结:http://www.unity.5helpyou.com/3550.html 利用unity3d属性来设置Inspe ...

  7. HTML5之应用缓存---manifest---缓存使用----HTML5的manifest缓存

    相信来查这一类问题的都是遇到问题或者是初学者吧! 没关系相信你认真看过之后就会知道明白的 这是HTML5新加的特性 HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连 ...

  8. Oracle 排序中使用nulls first 或者nulls last 语法

    -原理 Nulls first和nulls last是Oracle Order by支持的语法 如果Order by 中指定了表达式Nulls first则表示null值的记录将排在最前(不管是asc ...

  9. UMLUnified Modeling Language (UML)又称统一建模语言或标准建模语言

    1.用例图(use case diagram) 2.活动图(activity diagram) 3.静态结构图 4.顺序图(Sequence Diagram):时序图 5.交互纵览图(Interact ...

  10. GitHub入门之一:使用github下载项目

    git作为目前比较流行的版本控制系统,被各个互联网公司广泛使用着.目前国外的网站有GitHub,国内的有CSDN和OSCHINA的git. 使用git可以很方便地进行多人协作和版本控制.作为一个入门小 ...