背景:
最近用高德的一个基于web的URI地图路径规划及导航模块,以实现根据起始坐标 实现路径规划,见此处
起点是当前位置,由于没有集成高德API,所以用系统的CLLocationManager实现定位。
问题:
但是实际上,CLLocationManager定位的坐标,在高德地图上标注的位置与实际地点有偏差,并且较大!以前知道不同的地图坐标不能直接通用,但是如我所知,Apple的地图也是基于高德的,为什么CLLocationManager定位出的不准确,而MKMapView的定位却是准确的呢?
原因:
是这样的,按照国家统一的保密要求,任何一个地图产品都不允许使用GPS坐标,国内地图使用的坐标系统是GCJ-02。GCJ-02,国测局02年发布的坐标体系。又称“火星坐标”。在中国,必须至少使用GCJ-02的坐标体系。比如谷歌,腾讯,高德都在用这个坐标体系。
国内其他坐标体系。一般都是由GCJ-02进过偏移算法得到的。这种体系就根据每个公司的不同,坐标体系都不一样了。比如,百度和搜狗就使用自己的坐标体系,与其他坐标体系不兼容。百度(BD_09坐标)
到这里大家可能都猜出了CLLocationManager有偏差,是因为采用的是WGS-84,也就是GPS原始坐标;
Apple的MKMapView框架准确,是因为 老乔想进中国,就得按规矩来咯,所以iOS中的地图理所应当将WGS-84坐标转成了国内GCJ-02坐标;
解决:
思路一:
使用现有API转换,将CLLocationManager的WGS_84坐标转成GCJ_02坐标,调用apple的私有模块类MKLocationManager中得方法来对经纬度做一个偏移修正
问题:但是如此使用会审核被拒,而且iOS 5之后,这个方法已经不再使用。
思路二:
既然MKMapView地图中的定位是准确的,那么用[self.mapView setShowsUserLocation:YES]得了
不足:需要将mapView加到父视图上,不然不会调用上面的代理方法,当然了,可以设置为hidden=YES,也是个办法
思路三:
使用算法,对得到的WGS_84坐标处理,得到GCJ_02坐标
听闻是为了国家安全搞的加密措施,使用的是非线性的偏移值,想得到真实的数据,得同GCJ申请,交钱,才能得到解密方法。不过高手在民间啊,被人破解了,具体算法分析可以看这篇文章
这个算法网上是有的,具体出自谁不清楚,还是要感谢并参考一下,下面贴出位置纠错算法的OC代码:新建一个继承NSObject的类
WGS84ConvertToGCJ02.h 文件:
|
|
WGS84ConvertToGCJ02.m文件:
|
|
以我的项目为例,在CLLocationManager的定位代理方法中这样使用:
|
|
不足:毕竟不是正统解密算法,还是会有偏差,大概10+m,但是精度已经很高了。