http://www.aiuxian.com/article/p-2767848.html

#define toDeg(X) (X*180.0/M_PI)

/**
 * @method 根据两点经纬度,计算与真北方夹角
 *
 * @param longitude1
 * @param latitude1
 * @param longitude2
 * @param latitude2 // 目标点
 */
- (void)getAngle:(double)longitude1 latitude1:(double)latitude1 longitude2:(double)longitude2 latitude2:(double)latitude2 {
    double cos_c = cos(90 - latitude2)*cos(90 - latitude1) + sin(90 - latitude2)*sin(90 - latitude1)*cos(longitude2-longitude1);
    
    double sin_c = sqrt(1 - pow(cos_c, 2));
    
    double z = asin(sin(90 - latitude2)*sin(longitude2 - longitude1)/sin_c);
    z = toDeg(z);
    
    
// A(起始点)为原点B目标点
    if(longitude1 < longitude2 && latitude1 < latitude2) { // 第一象限
        
    } else if (longitude1 < longitude2 && latitude1 > latitude2){ // 第二象限
        z += 360;
    } else { // 三四象限
        z = 180 - z;
    }
    cityHeading = z;
    
    NSLog(@"城市夹角:%f",z);
}

此处设定求B相对于A的方位角,即A为当前位置,B为目标位置

Aj:A点经度

Aw:A点纬度

Bj:B点经度

Bw:B点纬度

北纬为正,南纬为负;东经为正,西经为负

经纬度使用度,DDD.DDDDDD°,非度分或度分秒。

度数未加说明均采用角度制

R:地球平均半径

Azimuth:方位角,以真北为0度起点,由东向南向西顺时针旋转360度

这里需要注意一点,我们一开始的假设便是求B点相对于A点的方位角,因此这里是Bj-Aj,不要写反,否则得不到正确结果。

算到这里,还没有完,得到的结果并不总符合我们对方位角的定义,因此要根据B相对于A的位置在四个象限两个轴上进行讨论,依据不同情况对计算结果进行不同处理。假设A点固定于原点,则:

B点在第一象限,Azimuth=A;

B在第二象限,Azimuth=360+A;

B在第三四象限,Azimuth=180-A。

这里只说了象限的讨论结果,因为轴上的讨论更复杂些,要结合程序运行环境一起考虑,考虑的主要因素是系统的计算精度。譬如,在三面角余弦公式中,当AB点纬度值相同时,对公式的值起决定作用的就是cos(Bj-Aj)这一项,当Bj-Aj的值比较小时,例如0.0001(这在赤道地区对应的长度为11米左右),用一般的计算器计算时值为1,这样,后面的计算便不可能完成。但是,如果用计算机计算则为0.999999999998476913…………。所以,基于以上原因,需要对轴的“范围进项扩充”,要用单片机、手机运算的尤其要注意。

经过一系列计算,最后,就得到了最终结果。

似乎有人注意到了,以上的计算都是把地球看成标准的球体,而事实是地球是个椭圆,其实,地球的偏心率极低,各位可以将此法得到的计算结果与谷歌地球(WGS84坐标系统,我说的不是谷歌地图)上的结果进行对比,偏差是非常小的(我测的几个值,最大偏差0.5度)。

二、距离的求算

其实,“眼尖”的或许已经注意到了,第一步的余弦值结果就可以直接用来求算AB两点间的球面距离,用反余弦函数求得c的度数,再将度数转换为弧度,乘以地球半径就得到了两点间的球面距离。

公式为



这里要注意,L的单位与R的单位一致,单位不同的不要忘记换算

短距离(例如100米,30米)使用这个公式,计算出的结果与谷歌地球给出的距离偏差在0.5%以下,长距离计算时,偏差则可以降至0.01%以下。求算的距离越大,偏差越小,就是这个公式的特点,原因不说自明。

PS:对于一些GPS接收机,其数据格式为NMEA-0183,经纬度数据为DDDMM.MMMM,需要将它转换为度,公式为:

经纬度(度)=DDD+MM.MMMM/60

第二种方法:

 #import <Foundation/Foundation.h>

 @interface MyLatLng : NSObject {
double m_LoDeg,m_LoMin,m_LoSec;
double m_LaDeg,m_LaMin,m_LaSec;
double m_Longitude,m_Latitude;
double m_RadLo,m_RadLa;
double Ec;
double Ed;
}
- (id)init:(double)longitude latitude:(double)latitude; @property (assign, nonatomic) double m_LoDeg;
@property (assign, nonatomic) double m_LoMin;
@property (assign, nonatomic) double m_LoSec;
@property (assign, nonatomic) double m_LaDeg;
@property (assign, nonatomic) double m_LaMin;
@property (assign, nonatomic) double m_LaSec;
@property (assign, nonatomic) double m_Longitude;
@property (assign, nonatomic) double m_Latitude;
@property (assign, nonatomic) double m_RadLo;
@property (assign, nonatomic) double m_RadLa;
@property (assign, nonatomic) double Ec;
@property (assign, nonatomic) double Ed;
@end
 #import "MyLatLng.h"
#define RC 6378137
#define RJ 6356725 @implementation MyLatLng
@synthesize m_LoDeg;
@synthesize m_LoMin;
@synthesize m_LoSec;
@synthesize m_LaDeg;
@synthesize m_LaMin;
@synthesize m_LaSec;
@synthesize m_Longitude;
@synthesize m_Latitude;
@synthesize m_RadLa;
@synthesize m_RadLo;
@synthesize Ec;
@synthesize Ed; - (id)init:(double)longitude latitude:(double)latitude{
self = [super init]; if (self) {
m_LoDeg=(int)longitude;
m_LoMin=(int)((longitude-m_LoDeg)*);
m_LoSec=(longitude-m_LoDeg-m_LoMin/.)*; m_LaDeg=(int)latitude;
m_LaMin=(int)((latitude-m_LaDeg)*);
m_LaSec=(latitude-m_LaDeg-m_LaMin/.)*; m_Longitude=longitude;
m_Latitude=latitude;
m_RadLo=longitude*M_PI/.;
m_RadLa=latitude*M_PI/.;
Ec=RJ+(RC-RJ)*(.-m_Latitude)/.;
Ed=Ec*cos(m_RadLa);
} return self;
}
@end
 #import "ViewController.h"
#import "MyLatLng.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. MyLatLng *A = [[MyLatLng alloc]init:113.249648 latitude:23.401553];
MyLatLng *B = [[MyLatLng alloc]init:113.246033 latitude:23.403362]; [self getAngle:A B:B];
} - (double)getAngle:(MyLatLng *)A B:(MyLatLng *)B {
double dx=(B.m_RadLo-A.m_RadLo)*A.Ed;
double dy=(B.m_RadLa-A.m_RadLa)*A.Ec;
double angle=0.0;
angle = atan(fabs(dx/dy))*./M_PI;
double dLo=B.m_Longitude-A.m_Longitude;
double dLa=B.m_Latitude-A.m_Latitude;
if(dLo>&&dLa<=){
angle=(.-angle)+;
}
else if(dLo<=&&dLa<){
angle=angle+.;
}else if(dLo<&&dLa>=){
angle= (.-angle)+;
}
return angle;
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

iOS 根据经纬度计算与地理北极夹角的更多相关文章

  1. IOS根据两个经纬度计算相距距离

    //第一种苹果自带的 CLLocation *orig=[[[CLLocation alloc] initWithLatitude:[mainDelegate.latitude_self double ...

  2. iOS根据2个经纬度计算距离

    #pragma mark - calculate distance 根据2个经纬度计算距离 #define PI 3.14159265358979323 +(double) CalculationDi ...

  3. iOS开发拓展篇—CoreLocation地理编码

    iOS开发拓展篇—CoreLocation地理编码 一.简单说明 CLGeocoder:地理编码器,其中Geo是地理的英文单词Geography的简写. 1.使用CLGeocoder可以完成“地理编码 ...

  4. java工具类(六)根据经纬度计算距离

    Java实现根据经纬度计算距离 在项目开发过程中,需要根据两地经纬度坐标计算两地间距离,所用的工具类如下: Demo1: public static double getDistatce(double ...

  5. sql server2008根据经纬度计算两点之间的距离

    --通过经纬度计算两点之间的距离 create FUNCTION [dbo].[fnGetDistanceNew] --LatBegin 开始经度 --LngBegin 开始维度 --29.49029 ...

  6. 利用JS实现的根据经纬度计算地球上两点之间的距离

      最近用到了根据经纬度计算地球表面两点间距离的公式,然后就用JS实现了一下. 计算地球表面两点间的距离大概有两种办法. 第一种是默认地球是一个光滑的球面,然后计算任意两点间的距离,这个距离叫做大圆距 ...

  7. php根据经纬度计算距离和方向--摘录自http://haotushu.sinaapp.com/post-520.html

    define('EARTH_RADIUS', 6367000);//需定义的静态变量 function getRadian($d) { return $d * M_PI / 180; } functi ...

  8. TSQL 根据经纬度计算两点间的距离;返回米(m)

    -- ============================================= -- Author:Forrest -- Create date: 2013-07-16 -- Des ...

  9. cesium根据经纬度计算距离

    var startLatitude = 36;var startLongitude = 120; var endLatitude=34; var endLongitude=121; var start ...

随机推荐

  1. XMLHttpRequest对象的常用属性与方法

    方法 一, open(); 书上解释: 用于设置请求的目标url请求方法, 以及其他参数信息 个人理解: 发送请求的页面在不刷新的情况能将参数传给一个服务器进行处理, 这个方法就是将这些个参数传送过去 ...

  2. EasyUI项目中的自定义JS

    自定义方法: (function($) { $.extend($, { //获取下标,删除时使用 getArrayIndex :  function (array,value) { var index ...

  3. MySQL多表数据记录查询详解

    在实际应用中,经常需要实现在一个查询语句中显示多张表的数据,这就是所谓的多表数据记录连接查询,简称来年将诶查询. 在具体实现连接查询操作时,首先将两个或两个以上的表按照某个条件连接起来,然后再查询到所 ...

  4. 【转】nginx中proxy_set_header Host $host的作用

    nginx为了实现反向代理的需求而增加了一个ngx_http_proxy_module模块.其中proxy_set_header指令就是该模块需要读取的配置文件.在这里,所有设置的值的含义和http请 ...

  5. 德国Aptamil不同系列奶粉间差别

    以下内容均来源网络整理.汇总. 德国人做事严谨,而且对于有争议性的成分持保守态度,比如不添加麦芽糊精.所以我比较赞赏购买德国的奶粉,主要是aptamil和hipp喜宝,这两个牌子也基本没有负面新闻.但 ...

  6. 关于Cocos2d-x中物理世界的物体乱跳的问题的解决

    这是电脑短时间内帧率低,无法满足游戏配置的帧率引起的. 解决方法: 第一种: 1.打开AppDelegate.cpp文件 2.把director->setAnimationInterval(1. ...

  7. struts2中struts.xml和web.xml文件解析及工作原理

    web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp ...

  8. Spring bean的初始化及销毁

    Spring bean的几个属性:scope.init-method.destroy-method.depends-on等. Scope 在Spring容器中是指其创建的Bean对象相对于其他Bean ...

  9. VC内存溢出一例 –- 调用约定不一致

    这个是网查的跟我在做图像分割realse相反的情况: 最近在写一个程序,调用了多个DLL,每个DLL代码都支持多线程,Debug的模式下基本调通了,但是在Release模式下,程序因为内存溢出而崩溃, ...

  10. CentOS 6.5在grub界面下更改root密码

    想要更改CentOS 7 root的密码或者忘记了root的密码的时候可以在grub界面下更改root的密码. 百度了很多内容,更多方法都是适用于centos6及以前版本的,终于找到一个可以的. 1. ...