Android LBS地图开发:地球地理GPS坐标系经纬度偏移偏差

简介: 本文作者:ZhangPhil欢迎各位转载!但请注明转载出处:http://blog.csdn.net/zhangphil/article/details/48024831Android LBS地图开发基础知识之地球地理GPS坐标系经纬度偏移偏差 通常,我们所说的地球地理经纬度是WGS-84坐标系(World Geodetic System-1984 Coordinate System)的经纬度。
本文作者:ZhangPhil
欢迎各位转载!但请注明转载出处:
http://blog.csdn.net/zhangphil/article/details/48024831


Android LBS地图开发基础知识之地球地理GPS坐标系经纬度偏移偏差


 通常,我们所说的地球地理经纬度是WGS-84坐标系(World Geodetic System-1984 Coordinate System)的经纬度。WGS-84坐标系是在1984年制定的全球坐标系,这个坐标系上的每一点经纬度能够精确映射到地球表面的任意一点。我们中学地理教科书中所讲述的地理坐标系其实就是WGS-84坐标系。WGS-84坐标系为GPS而生,是全球通用的坐标系。
 然而,在中国大陆,所有民用和商用的坐标系都不是WGS-84坐标系,而是GCJ-02坐标系(有些地图供应厂商可能在GCJ-02基础二次深度开发形成自家所有的多形式、多标准的地图坐标系,比如百度经纬度坐标系标准bd09ll)。什么是GCJ-02坐标系呢?GCJ-02坐标系是中国国家测绘局2002年制定的、不同于WGS-84坐标系的、中国大陆境内民用和商用经纬度的坐标系。
 GCJ-02坐标系不同于WGS-84坐标系在什么地方呢?
“GCJ-02是由中国国家测绘局制订的地理信息系统的坐标系统。它是一种对经纬度数据的加密算法,即加入随机的偏差。国内出版的各种地图系统(包括电子形式),必须至少采用GCJ-02对地理位置进行首次加密。”
GCJ-02坐标系最关键的地方,概括起来:如果说WGS-84坐标系是地球地理表面某一点真实的经纬度坐标系,那么GCJ-02坐标系是在WGS-84坐标系基础上,把WGS-84真实的经纬度坐标点随机添加一定经纬度偏移量(偏移量计算算法相当复杂,不是简单的随机)而形成的“不真实”的经纬度坐标系。GCJ-02坐标系因此也被称为火星坐标系。
 WGS-84坐标系到GCJ-02坐标系,最核心的地方就是偏移量的计算和添加,偏移量算法目前没有公开资料,据传闻下面一段算法是WGS-84到GCJ-02处理纬度偏移量的一小节算法:

-100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x)) + (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0 + (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0 + (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0

算法相当精巧,该算法目的是保证在WGS-84坐标系添加一定偏移量形成GCJ-02的过程中,输出结果是连续、单调的,每一个WGS-84坐标系的坐标点经过GCJ-02偏移量算法处理后的坐标点是唯一的、一一对应的,只有这样才能保证GCJ-02即便不是真实的经纬度坐标,但是偏移形成后的GCJ-02依然可以完整显示地图。该算法不可逆,无法找到反函数,即便拿到输出结果,也无法推导真实函数工作原理。但是有些人通过GCJ-02偏移量算法输出的值,经过复杂的数量计算和分析,也是可以大概模拟偏移量算法,但还是存在不小误差。
 下图(网传)大体上较为模糊的显示了经过偏移量算法处理后的偏移量值,红色最大,蓝色最小。GCJ-02坐标系将WGS-84坐标系偏移了一定距离,偏移距离在数百米以内,不超过1000米。偏移量越大,意味着定位越不准确,偏移量越小,意味着定位越准确,换言之,偏移量为0即是真实的WGS-84坐标系:
 


中国国内民用商用的地图供应商和服务商,都至少是基于GCJ-02开发的。但GCJ-02明明不是真实的坐标系,那为什么显示的是真实正确的呢?是因为火星坐标系必须配上国内的火星地图,才能在表面上看上去是“真实、正确”的。比如百度,百度地图上给出的某点的坐标系都是处理后的火星坐标系,不是真实的。百度在自己的官方网站(http://developer.baidu.com/map/question.htm)给出了文档加以说明:
 

节选一段百度官方网站的文档内容:

2 坐标体系
2.1 坐标体系是否遵循国家对地理信息保密要求?
百度对外接口的坐标系,都是经过国家测绘局加密处理,符合国家测绘局对地理信息保密要求。
2.3 百度坐标为何有偏移?
国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。百度坐标在此基础上,进行了BD-09二次加密措施,更加保护了个人隐私。百度对外接口的坐标系并不是GPS采集的真实经纬度,需要通过坐标转换接口进行转换。
2.4 如何从其他体系的坐标迁移到百度坐标?
开发者可以使用坐标转换接口进行转换。JavaScript API 、Android SDK、iOS SDK的开发用户可直接调用相应方法进行转换。

百度在其官方网站(http://developer.baidu.com/map/geosdk-android-classv4.0.htm#import.E7.9B.B8.E5.85.B3.E7.B1.BB)给出了自家Android SDK的经纬度标准类型的设置方法:



百度已经开放API接口,提供不同标准的经纬度坐标系转换(纠偏)。百度官方的不同坐标系经纬度转换(纠偏)地址:http://developer.baidu.com/map/changeposition.htm

也有一些其他厂商提供的坐标系转换API接口,比如这个网站提供的GPS火星坐标转换纠偏接口:
 http://www.zdoz.net/apiList.html

 关于经纬度偏移偏差,还有一个重要情况需要在LBS开发时候引起注意,是关于GPS硬件模组本身的,分两类情况,黑盒测试发现,据推测也许应该存在(真实情况有待进一步论证):
(1)中国大陆境内经过正规行货渠道发售的智能手机。这类手机自带的GPS硬件模组,返回的GPS经纬度值不是真实的,也是经过一定偏移量算法处理后的经纬度。这是因为GPS模组在硬件级别的偏移量处理导致。这类国内行货手机的GPS模组在收到GPS卫星返回的真实WGS-84坐标系经纬度后,执行偏移量算法处理成GCJ-02经纬度之后,此时才将GCJ-02经纬度返回给上层软件系统。
(2)国外发售的手机(或者水货),不是国家正规途径许可的手机。由于这类智能手机目标市场不是中国,自身的GPS硬件模组收到WGS-84坐标系经纬度后不做任何偏移量处理,直接返回给上层软件,那么这种情况下,这类手机得到的经纬度是真实的WGS-84坐标系经纬度。但是,如果在中国大陆境内使用这类手机,把底层GPS硬件模组返回的真实WGS-84经纬度交给国内厂商的地图直接定位,也是会出现偏差,原因是国内地图厂商的地图是基于火星经纬度坐标系的!如果不做经纬度转换,国内的地图直接将真实的WGS-84坐标系经纬度误以为是火星坐标系经纬度进行定位,当然会出现偏差!


相关文章
|
4月前
|
JSON Java 定位技术
【Android App】GPS获取定位经纬度和根据经纬度获取详细地址讲解及实战(附源码和演示 超详细)
【Android App】GPS获取定位经纬度和根据经纬度获取详细地址讲解及实战(附源码和演示 超详细)
213 0
|
4月前
|
XML Java 定位技术
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
112 0
|
7月前
|
前端开发 定位技术 Android开发
Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注
我们在做GB28181设备接入端的时候,其中有个功能,不难但非常重要:那就是GB28181实时位置的订阅(mobileposition subscribe)和上报(notify)。
115 0
|
7月前
|
XML Android开发 数据格式
Android GB28181接入端实时位置订阅和上报之-如何获取当前经纬度
我们在做Android平台GB28181的时候,其中实时位置(MobilePosition)订阅和上报这块,涉及到实时经纬度的获取,特别是执法记录、车载系统的那个等场景,几乎就是标配。
|
12月前
|
Java Shell 定位技术
Android 6.0 默认关闭定位和GPS,开启后默认选省电,永不休眠
Android 6.0 默认关闭定位和GPS,开启后默认选省电,永不休眠
215 0
|
Java 定位技术 Android开发
安卓(JAVA)已知两点经纬度,求出一条线上定距(比如隔20米或30一个点)的经纬度。
安卓(JAVA)已知两点经纬度,求出一条线上定距(比如隔20米或30一个点)的经纬度。
234 0
|
Java Android开发
安卓(JAVA)已知两点经纬度,求出一条线上几等分的点的经纬度。
安卓(JAVA)已知两点经纬度,求出一条线上几等分的点的经纬度。
83 0
|
定位技术 API Android开发
安卓基于百度地图计算两个经纬度点的直线距离并只保留两位小数
安卓基于百度地图计算两个经纬度点的直线距离并只保留两位小数
315 0
|
Android开发
【Android 逆向】函数拦截原理 ( 通过修改 GOT 全局偏移表拦截函数 | 通过在实际被调用的函数中添加跳转代码实现函数拦截 )
【Android 逆向】函数拦截原理 ( 通过修改 GOT 全局偏移表拦截函数 | 通过在实际被调用的函数中添加跳转代码实现函数拦截 )
165 0
【Android 逆向】函数拦截原理 ( 通过修改 GOT 全局偏移表拦截函数 | 通过在实际被调用的函数中添加跳转代码实现函数拦截 )
|
Java Linux Android开发
【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )
【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )
212 0
【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )