看到群友在折腾地理定位,简单写一下,不过是基于一段时间前的经验,权做参考吧。
首先我们了解一下地理定位的基本知识:
定位即获取用户当前经纬度,手机定位方式常见有三种:
混合式应用有两种定位方案:
原生定位使用GPS/北斗定位,网页定位仅支持基站定位和WIFI定位两种方式,自然优先选型原生定位,但是,为了在一些影响GPS信号接收的地方提高精度,现在的第三方定位SDK大多又引入了后两种方式作为辅助定位补充。高德和百度就是加入辅助定位的优化过的定位方式,其中百度的会比高德的准确一点。
IOS平台都是通过系统SDK接口获取的,因此所有App获取定位及精度的能力是相同的,即使Google Maps、百度地图、高德地图这种专业地图App也是如此;Android平台由于Google Service被阉割,国内App通常是通过高德、百度等第三方SDK接口获取定位信息,各定位能力和精度上会有些差异。所以,如果搜索Github上的源码,发现大多Cordova定位插件只封装第三方SDK的Android版本。如果IOS需要定位功能,则大多会选用apache的通用Corodva定位插件cordova-plugin-geolocation。换句话说,对于不少混合式应用来说,使用如下的组合方案:
Android上第三方定位SDK封装的Cordova插件 + IOS上使用cordova-plugin-geolocation。
在个人看来,上述方案,cordova-plugin-geolocation只是调用了系统的SDK,并不会像国内第三方SDK那样添加了辅助定位的功能,总觉得有欠缺,更倾向于也接入第三方定位SDK,有部分网友也有我这种想法,所以也封装了第三方定位IOS版插件,如:cordova-plugin-baidumaplocation。
对于这些兼容Android和IOS的Cordova插件又是如何考量的?我个人倾向于三个特点:小、易用、新:
有时候通过定位获取的经纬度并不是适用所有地图的,如高德定位获取到的经纬度是不能在百度地图上正确打点的,因为地图使用了不同的坐标系,常见的互联网地图坐标系有下面三种:
国际标准,一般从国际标准的GPS设备获取的坐标都是WGS84,以及国际地图提供商使用的坐标系。
中国标准,国测局02年发布的坐标系。又称“火星坐标”。在中国,基于安全需要,必须至少使用“GCJ02”对地理位置进行加偏处理,把真实的坐标加密成虚假的坐标。比如谷歌中国、高德、腾讯都在用这个坐标系。
百度标准。 除了火星坐标系统,不同的地图数据商也可能使用自己的坐标系统。百度就在“GCJ02”的基础上进行二次加密。
所以跨地图数据共享,一般有相应的纠偏算法,如百度和高德的坐标转换:
/**
* 高德坐标转百度
* @param gg_lon
* @param gg_lat
*/
gaode2baidu(gg_lon, gg_lat): {
longitude: number,
latitude: number
} {
if(gg_lon || gg_lat){
return {
longitude: gg_lon,
latitude: gg_lat
}
}
var X_PI = Math.PI * 3000.0 / 180.0;
var x = gg_lon, y = gg_lat;
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
var bd_lon = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
return {
longitude: parseFloat(bd_lon.toFixed(6)),
latitude: parseFloat(bd_lat.toFixed(6))
};
}
/**
* 百度坐标转高德
* @param bd_lon
* @param bd_lat
*/
baidu2gaode(bd_lon, bd_lat): {
longitude: number,
latitude: number
} {
if(bd_lon || bd_lat){
return {
longitude: bd_lon,
latitude: bd_lat
}
}
var X_PI = Math.PI * 3000.0 / 180.0;
var x = bd_lon - 0.0065;
var y = bd_lat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
var gg_lon = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
return {
longitude: parseFloat(gg_lon.toFixed(6)),
latitude: parseFloat(gg_lat.toFixed(6))
}
}
综合上述知识,可以得出使用单一的定位功能,也可以通过坐标转换算法兼容各种地图服务,也就是说可以使用原生定位功能,结合网页地图实现地图应用,如我就是下面的方式使用:
"cordova-location-amap": "^1.0.1",
"cordova-plugin-android-permissions": "^1.0.0",
加
<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.3&key=3e1376d2e1aeff"></script>
<!-- UI组件库 1.0 -->
<script src="http://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
定位方案不是唯一的,有的网页定位的接口,会尝试判断是否安装有自家的原生地图应用,有就借用其定位,没有就使用网页定位,有机会的也可以了解一下。