地理定位原理简解及推荐Cordova插件使用

看到群友在折腾地理定位,简单写一下,不过是基于一段时间前的经验,权做参考吧。

首先我们了解一下地理定位的基本知识:

手机定位方式

定位即获取用户当前经纬度,手机定位方式常见有三种:

  1. GPS/北斗:根据系统GPS/北斗模块通过与卫星通信实时计算获取经纬度,精度10-100米左右,限制是容易受环境影响,在室内几乎不起作用。
  2. 基站:根据运营商基站位置计算经纬度,基站可能离手机百米甚至上千米远,所以误差较大,精度100-3000米不等,限制是定位较慢,精度差。
  3. WIFI:根据周围WIFI路由器位置计算经纬度,在城市范围,网络节点比较密集,所以城市精度高点,精度100-200米左右,限制是受周围WIFI数量和分布影响,需要打开手机WIFI开关。

混合式应用地理定位的方案

混合式应用有两种定位方案:

  1. 原生定位;
  2. 网页定位;

原生定位使用GPS/北斗定位,网页定位仅支持基站定位和WIFI定位两种方式,自然优先选型原生定位,但是,为了在一些影响GPS信号接收的地方提高精度,现在的第三方定位SDK大多又引入了后两种方式作为辅助定位补充。高德和百度就是加入辅助定位的优化过的定位方式,其中百度的会比高德的准确一点。

Cordova封装第三方原生定位SDK

IOS平台都是通过系统SDK接口获取的,因此所有App获取定位及精度的能力是相同的,即使Google Maps、百度地图、高德地图这种专业地图App也是如此;而Android平台由于Google Service被阉割导致该系统SDK无法正常使用,国内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插件又是如何考量的?我个人倾向于三个特点:小、易用、新

  1. 如上述提到插件虽是较新的,但用的是百度地图的库,比较臃肿,现在百度地图把定位sdk独立抽离了出来做成了百度定位sdk,所以如果它改成百度定位的库我是比较乐意使用的。
  2. 百度和高德用谁好我也挣扎了一段时间,最后选用高德,因为总体上,高德的文档相对较好,API也比较清晰简洁,对移动端的支持也更友好些(如提供有移动风格的城市列表选择组件)。
  3. 现有的高德定位插件,大多不维护了,使用的第三方库都是2年或以上,比较旧,所以我造了个轮子:cordova-location-amap——但我也没有维护了……

数据偏移之互联网地图坐标系

有时候通过定位获取的经纬度并不是适用所有地图的,如高德定位获取到的经纬度是不能在百度地图上正确打点的,因为地图使用了不同的坐标系,常见的互联网地图坐标系有下面三种:

WGS84(GPS)

国际标准,一般从国际标准的GPS设备获取的坐标都是WGS84,以及国际地图提供商使用的坐标系。

GCJ02

中国标准,国测局02年发布的坐标系。又称“火星坐标”。在中国,基于安全需要,必须至少使用“GCJ02”对地理位置进行加偏处理,把真实的坐标加密成虚假的坐标。比如谷歌中国、高德、腾讯都在用这个坐标系。

BD09

百度标准。 除了火星坐标系统,不同的地图数据商也可能使用自己的坐标系统。百度就在“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>

ionic中简单示例操作:

  1. 去地图服务商申请原生和Web版等key;
  2. 安装基于对应地图服务商的Cordova插件,变量填入申请的key;
  3. 在index.html中添加上述js文件,然后在具体的某个页面,如home.page.html中添加代码(注意指定宽高,不然可能地图出来了,但是却看不多,自己还找半天):
  <div id="container" style="width:100%;height:100%">
  </div>
  1. home.page.ts添加初始化地图代码:
declare let AMap: any;
declare let Zepto: any;
declare let AMapUI: any; 
loadMap() {
    if(typeof (AMapUI) == "undefined" || typeof (Zepto) == "undefined"){
      return;
    }
    // 设置DomLibrary
    AMapUI.setDomLibrary(Zepto);
    if (typeof (AMap) != "undefined") {
      const map = new AMap.Map('container', {
        resizeEnable: true,
        zoom: 10,
        center: this.center
      });
      this.map = map;
      // 加载BasicControl,loadUI的路径参数为模块名中 'ui/' 之后的部分
      AMapUI.loadUI(['control/BasicControl'], (BasicControl)=> {
        // 缩放控件
        this.map.addControl(new BasicControl.Zoom({
            position: 'lt', //left top,左上角
            showZoomNum: true // 显示zoom值
        }));
      });
    }
  }
  1. 调用原生定位功能:
cordova.plugins.aMapLocation.getCurrentPosition(this.configNative,
              (locate: {
                city: string,
                longitude: number,
                latitude: number
              }) => {
               console.log(locate);
              },
              e => {
               console.log(e);
              }
);

基本调用就这样子了,省却部分,仅提供主要代码,如地图key申请等请自行搜索。

定位方案不是唯一的,有的网页定位的接口,会尝试判断是否安装有自家的原生地图应用,有就借用其定位,没有就使用网页定位,有机会的也可以了解一下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容