校正IOS的GPS坐标方法

ios系统库中有两种定位方式:

1.CLLocationManager

  这种方式得到的坐标是有偏移的。

2.MKMapView

  这种方式得到的坐标是经过偏移的。


引用:http://www.keakon.net/2011/07/02/WGS84坐标转火星坐标(iOS篇)


   最近才知道,上面这两种方式为什么一个是准的,一个是不准的。原来中国为了保护地理信息安全,都有规定各个GIS厂商在绘制地图的时候进行曲线偏移,而且这个算法还几年一换。。。具体说明请看上面引用网址。
  CLLocationManager获得的坐标是WGS84坐标系
  MKMapView获得的用户点是火星坐标系

偏移校正方法:
1. 使用IOS的私有类MKLocationManager来计算,这种方法只在 IOS5 以前的系统上可以使用
  这个做法是有风险的,苹果不允许私有模块被直接调用。换句话说,你的软件可能会被Deny。

  因为是私有模块,我们需要声明这个类和我们要用到的函数,代码如下(需引入framework:MapKit、CoreLocation):

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

在CLLocationManager的位置监听函数中,我们把newLocation(原始位置),转换为中国位置
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation  
{  
    if ([[MKLocationManager sharedLocationManager] chinaShiftEnabled]) {  
        newLocation = [[MKLocationManager sharedLocationManager] _applyChinaLocationShift:newLocation];  
        if (newLocation == nil) {  // 很重要,计算location好像是要联网的,软件刚启动时前几次计算会返回nil。  
            return;  
        }  
    }  
    ...  
}  
这样,经转换后的newLocation,已经是中国的位置了。现在在映射到MKMapView上时,会显示正确的所在位置。

2.使用高德接口做坐标偏移校正(高德和MAPABC是一家)

 环境配置:http://api.amap.com/Ios/guide#include_lib

    1、下载最新版本SDK:http://api.amap.com/Ios/download  解压之后把<MASearchKit>文件夹添加到项目中的合适位置(可删除"Release-iphonesimulator/libMASearchKit.a"文件,在模拟器上运行时总是出BUG )

   2、需要在TARGETS -> Summary -> Linked Frameworks and Libraries 中添加如下系统库:
     QuartzCore,CoreText,CoreLocation,SystemConfiguration,libz,libstdc++6.0.9, libxml2.2, CoreTelephony

   3、在TARGETS -> Build -> Settings -> Other Linker Flags 中添加如下内容: -ObjC,-lMASearchKit (也就是去掉库文件名前后的lib和.a,并在前面加上-l参数)

首先引入#import "MAMapKit.h", 一般是viewController遵循MASearchDelegate协议
然后在合适的地方使用下面的代码:

    //用高德地图api校正获取的gps 数据
    MARGCSearchOption* searchOption = [[MARGCSearchOption alloc]init];//初始化SearchOption
    searchOption.config = @"RGC"; //这个是默认的,函数声明的头文件有注释
    searchOption.coors = [NSString stringWithFormat:@"%f,%f;",longitude,latitude];//这个可以同时查几组经纬度值,中间用分号隔开,参数location 是用CLLocationManager获取的经纬度值
    
    NSString *Apikey=@"7c9bca72cfb64b33e868feaa57f9b9c2" ;
    MASearch *search=[[MASearch alloc]initWithSearchKey:Apikey Delegate:self];
    search.delegate=self;//设置代理
    [search gpsOffsetSearchWithOption:searchOption]; //传入searchoption开始查找校正后的经纬度

程序执行完 gpsOffsetSearchWithOption:searchOption方法后会调用一个MAsearchDelegate的代理方法,并且把调用结果返回来,所以你可以在这个代理方法里执行你的处理逻辑
-(void) gpsOffsetSearch:(MARGCSearchOption *)gpsOffSearchOption Result:(MARGCSearchResult *)result
{
    MARGCItem* rgcInfo = [result.rgcItemArray objectAtIndex:0];  //返回的结果result是一个array来的,因为可以同时查找很多组经纬度值,不过我上面代码我只写了一组,所以只取第一个object就行了     
    currentLocation.longitude = [rgcInfo.x floatValue];        //取出经度值
    currentLocation.latitude = [rgcInfo.y floatValue];  //取出纬度值
 }

我写的demo地址:http://download.csdn.net/detail/marujunyy/5248206


高德api地址: http://code.autonavi.com/

MAPABC地址:http://code.mapabc.com/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值