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. R语言数据的导入与导出

    1.R数据的保存与加载 可通过save()函数保存为.Rdata文件,通过load()函数将数据加载到R中. > a <- 1:10 > save(a,file='d://data/ ...

  2. php 删除目录

    <?php /* 自定义的删除函数,可以删除文件和递归删除文件夹 */ function my_del($path)//自定义my_del函数,函数有一个参数($path).当调用my_del( ...

  3. Mastering the game of Go with deep neural networks and tree search浅析

    Silver, David, et al. "Mastering the game of Go with deep neural networks and tree search." ...

  4. numpy得到数组的index

    itemindex = numpy.where(array==item)

  5. Android isUserAMonkey()

    Monkey是Android上的一个自动化测试工具.产生随机事件由于压力测试等. ActivityManager.isUserAMonkey()判断当前是否有运行的Monkey测试.有就返回true. ...

  6. nodejs基础 -- 模块系统

    为了让nodejs的文件可以相互调用,nodejs提供了一个简单的模块系统. 模块:是nodejs应用程序的基本组成部分,文件和模块一一对应.即,一个nodejs文件就是一个模块,这个文件可能是jav ...

  7. jquery -- onchange

    触发onchange 首先页面有一个input标签,并且已绑定onchange事件,如: 1 <input type="text" onchange="consol ...

  8. 最短路径问题-Floyd算法

    概念 最短路径也是图的一个应用,即寻找图中某两个顶点的最短路径长度. 实际应用:例如确定某两个城市间的坐火车最短行车路线长度等. Floyd algorithm 中文名就是弗洛伊德算法. 算法思路:用 ...

  9. 【Java面试题】23 java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?

    java5 以前, 有如下两种:第一种:new Thread(){}.start();这表示调用 Thread 子类对象的 run 方法, new Thread(){}表示一个Thread 的匿名子类 ...

  10. Navicat for Mysql 如何备份数据库

    Navicat for Mysql 如何备份数据库 打开界面如下 打开自己的的数据库 点击需要备份的数据库名 未完!!! 文章来自:http://jingyan.baidu.com/article/f ...