在App中接入地图是很多项目的需求,咱们可选的有百度地图SDK,高德地图SDK甚至是腾讯地图SDK,当然了谷歌中国区地图就不说了……那么问题来了今天说的是啥呢?当然不是iOS开发技术啦而是科普
做过地图相关开发的同学肯定会遇到这样一个问题:同样的经纬度坐标,在百度地图和高德地图上位置不一样(如上图)。
我们通常用经纬度来表示一个地理位置,但是由于一些原因,我们从不同渠道得到的经纬度信息可能并不是在同一个坐标系下。
不同的坐标系之间可能有几十到几百米的偏移,所以在开发基于地图的产品,或者做地理数据可视化时,我们需要修正不同坐标系之间的偏差。
WGS-84(World Geodetic System, WGS)是使用最广泛的坐标系,也是世界通用的坐标系,GPS设备得到的经纬度就是在WGS84坐标系下的经纬度。通常通过底层接口得到的定位信息都是WGS84坐标系。
GCJ-02(G-Guojia国家,C-Cehui测绘,J-Ju局),又被称为火星坐标系,是一种基于WGS-84制定的大地测量系统,由中国国测局制定。此坐标系所采用的混淆算法会在经纬度中加入随机的偏移。
国家规定,中国大陆所有公开地理数据都需要至少用GCJ-02进行加密,也就是说我们从国内公司的产品中得到的数据,一定是经过了加密的。绝大部分国内互联网地图提供商都是使用GCJ-02坐标系,包括高德地图,谷歌地图中国区等。
导航电子地图在公开出版、销售、传播、展示和使用前,必须进行空间位置技术处理。— GB 20263―2006《导航电子地图安全处理技术基本要求》,4.1
BD-09(Baidu, BD)是百度地图使用的地理坐标系,其在GCJ-02上多增加了一次变换,用来保护用户隐私。从百度产品中得到的坐标都是BD-09坐标系。【以上内容摘自网络博客】
(下文全是以百度地图为例)
有这么的方式,对于需要位置信息的项目咱们怎么设计和存储地理位置信息是个问题。正如上图所示,那么我们项目怎么来高呢?很显然对于我们的App需要统一(位置误差几米几十米还是可以接受的)
前后端统一,按照国标来走
所有位置经纬度统一采用一种编码方式,例如
iOS的百度SDK
android的百度SDK
对于移动端内嵌百度SDK的话,可以看出百度默认的是自家的测绘编码而不是国标的地理编码方式,但是好在初始化的时候提供了修改的地方。作为国标的方式无论是高德还腾讯我想都必须要能够支持,因此我们将默认修改为国标的---GCJ-02
最后推荐一个iOS上的经纬度不同标准间相互转换库
JZLocationConverter
Swift版本(使用边境线坐标,判断是否中国大陆)
Quick start
JZLocationConverter 支持 CocoaPods. 添加下面配置到你的 Podfile:
pod 'JZLocationConverter'
WGS-84世界标准坐标、GCJ-02中国国测局(火星坐标)、BD-09百度坐标系转换 目前有:
WGS-84 -> GCJ-02
此接口当输入坐标为中国大陆以外时,仍旧返回WGS-84坐标
+ (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location;
GCJ-02 -> WGS-84
此接口有1-2米左右的误差,需要精确的场景慎用
+ (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location;
WGS-84 -> BD-09
+ (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location;
BD-09 -> WGS-84
+ (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location;
GCJ-02 -> BD-09
+ (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location;
BD-09 -> GCJ-02
此接口有1-2米左右的误差,需要精确的场景慎用
+ (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location;