iOS 根据两个经纬度计算与地理北极夹角

滴滴打车车辆转弯的,历史轨迹运动可能都需要这个功能吧.

头几天偶然看见了这个https://www.douban.com/group/topic/38478506/?author=1&start=0,作为程序员都身同感受吧,但是可惜没找到下文,所以今天我们来完成这个功能

让我指向像你

这是他的图片

不想看我墨迹一些没营养的下面有地址demo~~

实现思路

  • 1 不管手机怎么移动,我的红心手将指向你,所以这应该是一个指南针
  • 2 但是我不想指向北方,所以我们之间和北极应该有个角度,找到这个角度,我就找到你了
  • 3 应该还有个距离. 这个百度代码很多~~~

好的,我们首先先做个指南针.

1.导入头文件 #import <CoreLocation/CoreLocation.h>这个框架
签好协议<CLLocationManagerDelegate>和私有属性@property (nonatomic, strong) CLLocationManager *locationM;
2.然后懒加载

#pragma mark - 懒加载
- (CLLocationManager *)mgr
{
    if (!_mgr) {
        _mgr = [[CLLocationManager alloc] init];
    }
    return _mgr;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.mgr startUpdatingHeading];
}

3.实现协议

// 当获取到用户方向时就会调用
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    /*
     magneticHeading 设备与磁北的相对角度
     trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
     真北始终指向地理北极点
     */
    // 1.将获取到的角度转为弧度 = (角度 * π) / 180;
    CGFloat angle = newHeading.magneticHeading * M_PI / 180;
    // 2.旋转图片
    /*
     顺时针 正
     逆时针 负数
     */
    // 因为如果没有动画的话旋转的时候回出现卡顿的现象,为了更流畅,我们给它加个动画
    [UIView animateWithDuration:0.1 animations:^{
        // 旋转图片
        self.compasspointer.transform = CGAffineTransformMakeRotation(-a);
    }];
    
    
}

这个协议方法是一直调用的,不信你打印一下试试,所以最好不要在这里写任何耗时的事,self.compasspointer是一个图片,这里为了减少资源损耗就不画圆了,用图片是一样的.

  1. 这样就是一个正经八经的指南针了.下面只要求出来我们之间的角度,就完成了.

好的,我们找角度

1.根据百度的坐标提取系统我们可以知道任意两个点之间的坐标
    //我在大连的
    float lat1 = 38.927431;
    float lng1 = 121.650592;
   // 这是北京(假设就是北京)往下一点 116.650592,38.927431
    float lat2 = 38.927431;
    float lng2 = 116.650592;
2. 求出两个经纬度之间的角度
//两个经纬度之间的角度
-(double)getBearingWithLat1:(double)lat1 whitLng1:(double)lng1 whitLat2:(double)lat2 whitLng2:(double)lng2{
    
    double d = 0;
    double radLat1 =  [self radian:lat1];
    double radLat2 =  [self radian:lat2];
    double radLng1 = [self radian:lng1];
    double radLng2 =  [self radian:lng2];
    d = sin(radLat1)*sin(radLat2)+cos(radLat1)*cos(radLat2)*cos(radLng2-radLng1);
    d = sqrt(1-d*d);
    d = cos(radLat2)*sin(radLng2-radLng1)/d;
    d = [self angle:asin(d)];
    return d;
}
//根据角度计算弧度
-(double)radian:(double)d{
    
    return d * M_PI/180.0;
}
//根据弧度计算角度
-(double)angle:(double)r{
    
    return r * 180/M_PI;
}

我们纬度是一样的,根据上面的公式求出 北京 大连 北极之间的角度

角度
3 why? 口算都算出来了,应该是九十度啊?这怎么事八十八度?还是负数?后来我百度了一下真北,磁北,坐标北 ,我就不管这点误差了,当然这是可以处理的.

负数的问题,取个绝对值就好了,先不管这多为啥是负数
5231524215272_.pic.jpg

好了,变正数了,正数也可以一个人一个做法,不要吐槽我~

4 接下来为了验证正确性,我们把坐标改成山东东营,
 //  获取地理位置坐标的代码就不贴了,我在大连中山广场, 这是我的坐标 121.650592,38.927431
    float lat1 = 38.927431;
    float lng1 = 121.650592;
   // 山东 东营
    float lat2 = 37.588364;
    float lng2 = 118.593547;

按地图上来看角度应该是一百多度吧,但是打印出来的结果是
2018-04-20 17:14:06.029517+0800 angle[3667:1273780] -61.798896
2018-04-20 17:14:06.029610+0800 angle[3667:1273780] 61.798896
所以我又写了两行代码

if(lat2 < lat1){
        s = 180-s;
   }

这回打印结果
2018-04-20 17:14:06.029637+0800 angle[3667:1273780] 118.201104

好像对上
但是旋转图片的

        self.compasspointer.transform = CGAffineTransformMakeRotation(-a);

-a 是根据弧度计算的,值是0 到 2*π, 这个"我指向你的角度"就是 a弧度减去我求出来的角度

//宏定义
#define DEGREES_TO_RADIANS(angle) ( M_PI / 180 * (angle))

self.f =  DEGREES_TO_RADIANS(s);
    if (lng2 < lng1) {
        _f = (M_PI*2 - _f);
    }

打印出来2018-04-20 17:14:06.029687+0800 angle[3667:1273780] 4.220187

最后

// 当获取到用户方向时就会调用
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    /*
     magneticHeading 设备与磁北的相对角度
     trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
     真北始终指向地理北极点
     */
    // 1.将获取到的角度转为弧度 = (角度 * π) / 180;
    CGFloat angle = newHeading.magneticHeading * M_PI / 180;
    // 2.旋转图片
    /*
     顺时针 正
     逆时针 负数
     */
    CGFloat a = 0;
    a = angle - _f;
    // 因为如果没有动画的话旋转的时候回出现卡顿的现象,为了更流畅,我们给它加个动画
    [UIView animateWithDuration:0.1 animations:^{
        // 旋转图片
        self.compasspointer.transform = CGAffineTransformMakeRotation(-a);
    }];
    
    
}
效果图
正北
北京

墨迹完了,我也不知道我做的对不对,有问题一起探讨
下面是项目地址

demo (记得用真机)

Xcode9.3 以下打开会有问题???

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容