为什么你们的定位总是不准确

4,824 阅读4分钟

前言

我们常常会有这样的需求,获取当前位置并显示在地图上或者是根据当前位置匹配当前位置供用户选择。

我们在这时候想到的一定是使用国内三大地图api来实现功能,事实上当然,程序员不应该重复造轮子,何况是如此大的一个工程。

but! 你们有没有发现,每当你们使用定位获取到经纬度并且使用api进行地质解析的时候,获取到的地址总与真实地址有差异。

一般人遇到这些问题的时候就当做定位误差了,没有深层次考虑原因就提交,测试也觉得这是合理误差。。。

但是,我要说的是,真不是定位问题!

定位误差是存在的,但是这往往不是造成你位置偏移的主要原因,你和精确的位置之间可能只差了一个坐标系!

坐标系概念

众所周知地球是一个不规则椭圆体,GIS中的坐标系定义由基准面和地图投影两组参数确定,而基准面的定义则由特定椭球体及其对应的转换参数确定。 基准面是利用特定椭球体对特定地区地球表面的逼近,因此每个国家或地区均有各自的基准面。基准面是在椭球体基础上建立的,椭球体可以对应多个基准面,而基准面只能对应一个椭球体。

意思就是无论是谷歌地图、搜搜地图还是高德地图、百度地图区别只是针对不同的大地地理坐标系标准制作的经纬度,不存在准不准的问题,大家都是准的只是参照物或者说是标准不一样。

谷歌地图采用的是WGS84地理坐标系(中国范围除外),谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系,百度采用的是BD09坐标系,而设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系。

记住,这一点很重要。

产生原因

这么多坐标系为什么不统一用WGS84呢,这就是国家地理测绘总局对于出版地图的要求,出版地图必须符合GCJ02坐标系标准了,也就是国家规定不能直接使用WGS84地理坐标系。

那么产生定位差的问题就很明显了,你把GPS芯片获取到的WGS84坐标系的坐标用到地图里,填错坑了。

解决

如果你使用的是leaflet这一类的开放地图,那么就把获取到的坐标点转换成地图展示的坐标系点就可以了,例:

var map = L.map('allmap',{
  minZoom: 4,
  maxZoom: 13,
  crs: L.CRS.EPSG4326 // 设置成
}).setView([48.505, 3.09], 13);

如上例中使用leaflet设置为EPSG4326坐标系(其实就是WGS84的别名),那么就不需要坐标转换,直接使用就可以了。

如果使用别的开源坐标系,也是能找到转换方法的,例如WGS-84 到 GCJ-02 的转换(即 GPS 加偏)算法:

WGS-84 到 GCJ-02 的转换(即 GPS 加偏)算法

使用算法转换后的坐标系用在地图中就可以了。

但是一些地图产商,尤其是国内的几大地图,使用的都是自己的坐标系,并且没有开源,所以在使用这些地图的时候,你就只能把获取到的GPS坐标转换成对应地图的坐标,并且只有调用他们的api来转换。

例如在微信公众号中获取到的经纬度然后使用腾讯地图服务获取地址当前地址:

wx.getLocation({
    success: (data) => {
        let x = data.latitude;
        let y = data.longitude;
        let API_KEY = 'XXX-XXX';
        jsonp(`https://apis.map.qq.com/ws/coord/v1/translate/?locations=${x},${y}&type=1&key=${API_KEY}&output=jsonp`, null, (err, res) => {
            if (!err && res.status === 0) {
                jsonp(`https://apis.map.qq.com/ws/geocoder/v1/?location=${res.locations[0].lat},${res.locations[0].lng}&key=${API_KEY}&get_poi=1&output=jsonp`, null, (err, data) => {】
                    if (err || data.status !== 0) {
                        ... //do something
                    } else {
                        ... //do something error
                    }
                });
            } else {
                ... //do something error
            }
        });
    },

    cancel: (res) => {
        ... //do something cancel
    }
});

也就是说我们使用该地图就需要调用该地图的坐标转换方法,转换后的坐标才能应用到对应地图上。

国内三大地图厂商转换api

以下为国内三大地图的坐标系转换api介绍:

腾讯地图坐标转换服务: lbs.qq.com/webservice_…

百度地图坐标转换服务: developer.baidu.com/map/wiki/in…

高德地图坐标转换服务: lbs.amap.com/api/webserv…

结语

大部分人在获取到经纬度之后直接就放到地图中去展示了,这样得到的位置展示往往和真实位置相差甚远,只要加上坐标转换就没这个问题。

一些使用地图的经验分享给大家。

--The End