IOS CLLocationManager和中国地图偏移(China Shift)

CLLocationManager类的作用是监听GPS的位置消息,当用户坐标发生变化时,会调用下面的方法进行通知:

-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;

问题来了,当我们把newLocation中的坐标映射到MKMapView控件上时,会发现这个点跟本不是我们所在的位置,而是离我们百米左右的某个地方。
至于原因,。

那么,我们需要将原始的(真实的)位置坐标,转换为有中国特色的坐标。
对于这个问题,本文总结了两个处理办法:

1. 使用IOS的私有类MKLocationManager来计算。
  这个做法是有风险的,苹果不允许私有模块被直接调用。换句话说,你的软件可能会被Deny。

  因为是私有模块,我们需要声明这个类和我们要用到的函数,代码如下

[cpp]   view plain copy
  1. @interface MKLocationManager     
  2.     + (id)sharedLocationManager;       // 创建并获取MKLocationManager实例  
  3.     - (BOOL)chinaShiftEnabled;        // 判断IOS系统是否支持计算偏移  
  4.     - (CLLocation*)_applyChinaLocationShift:(CLLocation*)arg;   // 传入原始位置,计算偏移后的位置  
  5. @end  

在CLLocationManager的位置监听函数中,我们把newLocation(原始位置),转换为中国位置

[cpp]   view plain copy
  1. -(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation  
  2. {  
  3.     if ([[MKLocationManager sharedLocationManager] chinaShiftEnabled]) {  
  4.         newLocation = [[MKLocationManager sharedLocationManager] _applyChinaLocationShift:newLocation];  
  5.         if (newLocation == nil) {  // 很重要,计算location好像是要联网的,软件刚启动时前几次计算会返回nil。  
  6.             return;  
  7.         }  
  8.     }  
  9.     ...  
  10. }  

这样,经转换后的newLocation,已经是中国的位置了。现在在映射到MKMapView上时,会显示正确的所在位置。

 

2. 打开MKMapView的showsUserLocation功能。

  初始化MKMapView时,将属性showsUserLocation设置为YES,MKMapView会启动内置的位置监听服务,当用户位置变化时,调用delegate的回调函数:

[cpp]   view plain copy
  1. - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation  
  2. {  
  3.     // 这里得到的userLocation,已经是偏移后的位置了  
  4. }  

这个方法不会用到IOS的私有类和函数,不会有被绝的风险。缺点可能是不能像CLLocationManager那样进行丰富的配置,至少目前我还没找到。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值