vue 是用 hbuilder 打包的 APP 调用百度、高德地图 APP 复盘

今天遇到一个需求,我们用 vue 做的 APP 里有个地图显示图标功能,现在需要在点击图标的时候掉起百度或者高德地图进行导航,在这里记录一下集成过程

在网上找了好多 vue 打包的 APP 调用百度地图 APP 的文章,也看了百度地图的官网文档,结果。。。

估计是打开的方式不对,一篇有用的都没找到,因为前端学的比较粗浅,官网的文档也看不懂。因为之前打包 APP 及处理一些相关问题的时候在 DCloud 社区看到过很多优秀的文章,就去里面搜着碰碰运气

还真被我找到了:uni-app 中如何打开外部应用,如:浏览器、淘宝、AppStore、QQ 等

文章写的很详细,也很实用,我这里只选取调用地图 APP 的部分(这里主要用到原文更多实用例子中打开地图并指定地点部分)

环境

vue:vue2

框架:vant

app 框架:uni-app

原文方法

openMap(){  
            var url = "";  
            if (plus.os.name=="Android") {  
                var hasBaiduMap = plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap',action:'baidumap://'});  
                var hasAmap = plus.runtime.isApplicationExist({pname:'com.autonavi.minimap',action:'androidamap://'});  
                var urlBaiduMap = "baidumap://map/marker?location=39.968789,116.347247&title=DCloud&src=Hello+uni-app";  
                var urlAmap = "androidamap://viewMap?sourceApplication=Hello+uni-app&poiname=DCloud&lat=39.9631018208&lon=116.3406135236&dev=0"  
                if (hasAmap && hasBaiduMap) {  
                    plus.nativeUI.actionSheet({title:"选择地图应用",cancel:"取消",buttons:[{title:"百度地图"},{title:"高德地图"}]}, function(e){  
                        switch (e.index){  
                            case 1:  
                                plus.runtime.openURL(urlBaiduMap);  
                                break;  
                            case 2:  
                                plus.runtime.openURL(urlAmap);  
                                break;  
                        }  
                    })  
                }  
                else if (hasAmap) {  
                    plus.runtime.openURL(urlAmap);  
                }  
                else if (hasBaiduMap) {  
                    plus.runtime.openURL(urlBaiduMap);  
                }  
                else{  
                    url = "geo:39.96310,116.340698?q=%e6%95%b0%e5%ad%97%e5%a4%a9%e5%a0%82";  
                    plus.runtime.openURL(url); //如果是国外应用,应该优先使用这个,会启动google地图。这个接口不能统一坐标系,进入百度地图时会有偏差  
                }  
            } else{  
                // iOS上获取本机是否安装了百度高德地图,需要在manifest里配置,在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加(如urlschemewhitelist:["iosamap","baidumap"])  
                plus.nativeUI.actionSheet({title:"选择地图应用",cancel:"取消",buttons:[{title:"Apple地图"},{title:"百度地图"},{title:"高德地图"}]}, function(e){  
                    console.log("e.index: " + e.index);  
                    switch (e.index){  
                        case 1:  
                            url = "http://maps.apple.com/?q=%e6%95%b0%e5%ad%97%e5%a4%a9%e5%a0%82&ll=39.96310,116.340698&spn=0.008766,0.019441";  
                            break;  
                        case 2:  
                            url = "baidumap://map/marker?location=39.968789,116.347247&title=DCloud&src=Hello+uni-app";  
                            break;  
                        case 3:  
                            url = "iosamap://viewMap?sourceApplication=Hello+uni-app&poiname=DCloud&lat=39.9631018208&lon=116.3406135236&dev=0";  
                            break;  
                        default:  
                            break;  
                    }  
                    if (url!="") {  
                        plus.runtime.openURL( url, function( e ) {  
                            plus.nativeUI.alert("本机未安装指定的地图应用");  
                        });  
                    }  
                })  
            }  
        },  

定义公共方法

对原文方法进行改装,定义自己的公共方法

// 调用第三方应用进行导航
export function openMap (title, lat, lon) {
  if (plus.os.name == 'Android') {
    var hasBaiduMap = plus.runtime.isApplicationExist({ pname: 'com.baidu.BaiduMap', action: 'baidumap://' })
    var hasAmap = plus.runtime.isApplicationExist({ pname: 'com.autonavi.minimap', action: 'androidamap://' })
    var urlBaiduMap = 'baidumap://map/marker?location=' + lat + ',' + lon + '&title=' + title + '&src=';
    var urlAmap = 'androidamap://viewMap?poiname=' + title + '&lat=' + lat + '&lon=' + lon + '&dev=0'
    if (hasAmap && hasBaiduMap) {
      plus.nativeUI.actionSheet({ title: '选择地图应用', cancel: '取消', buttons: [{ title: '百度地图' }, { title: '高德地图' }] }, function (e) {
        switch (e.index) {
          case 1:
            plus.runtime.openURL(urlBaiduMap)
            break
          case 2:
            plus.runtime.openURL(urlAmap)
            break
        }
      })
    } else if (hasAmap) {
      plus.runtime.openURL(urlAmap)
    } else if (hasBaiduMap) {
      plus.runtime.openURL(urlBaiduMap)
    }
  }
}

因为 APP 只是用 Android 端,所以移除了 IOS 端

  • 此时发现一个问题,跳转到高德地图 APP 后定位是准确的,但是跳转百度地图 APP 后定位有偏差

跳转百度地图 APP 后定位偏差问题

查了一下,这是因为我们获取的坐标是通过高德地图获取的,而百度地图和高德地图之间的坐标是有偏差的,这里找了个高德地图坐标转百度地图坐标的方法:高德地图坐标与百度坐标转换问题

// 高德地图坐标转百度地图坐标
function bd_encrypt (gg_lng, gg_lat) {
  var X_PI = Math.PI * 3000.0 / 180.0
  var x = gg_lng; var 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_lng = z * Math.cos(theta) + 0.0065
  var bd_lat = z * Math.sin(theta) + 0.006
  return {
    bd_lat: bd_lat,
    bd_lng: bd_lng
  }
}

在地图 APP 调用工具类中调用该方法,转换坐标

// 调用第三方应用进行导航
function openMap (title, lat, lon) {
  if (plus.os.name == 'Android') {
    var hasBaiduMap = plus.runtime.isApplicationExist({ pname: 'com.baidu.BaiduMap', action: 'baidumap://' })
    var hasAmap = plus.runtime.isApplicationExist({ pname: 'com.autonavi.minimap', action: 'androidamap://' })

    // 因为坐标是高德的,需要转成百度的
    var bd = bd_encrypt(lon, lat);
    var urlBaiduMap = 'baidumap://map/marker?location=' + bd.bd_lat + ',' + bd.bd_lng + '&title=' + title + '&src=';
    var urlAmap = 'androidamap://viewMap?poiname=' + title + '&lat=' + lat + '&lon=' + lon + '&dev=0'
    if (hasAmap && hasBaiduMap) {
      plus.nativeUI.actionSheet({ title: '选择地图应用', cancel: '取消', buttons: [{ title: '百度地图' }, { title: '高德地图' }] }, function (e) {
        switch (e.index) {
          case 1:
            plus.runtime.openURL(urlBaiduMap)
            break
          case 2:
            plus.runtime.openURL(urlAmap)
            break
        }
      })
    } else if (hasAmap) {
      plus.runtime.openURL(urlAmap)
    } else if (hasBaiduMap) {
      plus.runtime.openURL(urlBaiduMap)
    }
  }
}

至此已经实现了客户需要的功能,完美收工!

联系方式

作者:永夜

邮箱:Evernight@aliyun.com

以上内容有不正确的地方或者不完善的地方烦请指正!🙏🙏🙏

  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    254 引用 • 666 回帖 • 290 关注
  • 复盘
    8 引用 • 5 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
luomuren
永夜降临之前,你都有改变的资格
融合块、大纲和双向链接
构建你永恒的数字花园
思源笔记是一款本地优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步