请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册
搜索

技术分享 快应用适配微信openLocation接口

1
回复
388
查看
[复制链接]

1

主题

3

帖子

20

积分

 楼主| 2019-7-24 22:51:18 显示全部楼层 |阅读模式
本帖最后由 初冬、阳光 于 2019-7-25 10:29 编辑

快应用适配微信openLocation接口



     大家都知道,其他平台小程序,都有官方提供的openLocation接口(通过位置坐标在地图上显示对应的标注,同时支持导航),但是快应用官方没有提供,其实官方并不是没有提供,而是提供了更自由的方式。接下来我给大家介绍一下快应用openLocation适配。


1、首先写好页面的布局模板,展示一个地图,一个地址展示栏,一个导航按钮,一个我的位置控制组件,代码如下:


  1. <template>
  2.   <div class="open-location-contanier">
  3.     <map id='map' class='map' markers="{{markers}}" controls="{{controls}}" @controltap="controlTap" latitude="{{latitude}}" longitude="{{longitude}}" scale="{{scale}}" showmylocation="{{showMylocation}}"></map>
  4.     <div class='map-tool'>
  5.       <div class='location-info-box'>
  6.         <text class='location-name'>{{name}}</text>
  7.         <text class='location-address'>{{address}}</text>
  8.       </div>
  9.       <text class='location-btn' if='{{isShowNav}}' @click="goNavigation">导航</text>
  10.     </div>
  11.   </div>
  12. </template>
复制代码

2、样式如下,大家可以自定义
  1. <style>
  2. .open-location-contanier {
  3.   display: flex;
  4.   flex: 1;
  5.   flex-direction: column;
  6. }

  7. .location-info-box {
  8.   height: 200px;
  9.   background-color: #fff;
  10.   display: flex;
  11.   flex-direction: column;
  12.   justify-content: center;
  13. }

  14. .location-name {
  15.   font-size: 34px;
  16.   color: #333;
  17.   width: 500px;
  18.   lines: 1;
  19.   text-overflow: ellipsis;
  20. }

  21. .location-address {
  22.   font-size: 24px;
  23.   line-height: 30px;
  24.   color: #666;
  25.   width: 500px;
  26.   lines: 1;
  27.   text-overflow: ellipsis;
  28. }

  29. .map {
  30.   flex: 1;
  31. }

  32. .map-tool {
  33.   display: flex;
  34.   justify-content: space-between;
  35.   align-items: center;
  36.   padding: 0 40px;
  37. }
  38. </style>
复制代码


3、页面js逻辑
  1. <script>
  2. import router from '@system.router'
  3. import prompt from '@system.prompt'
  4. import pkg from '@system.package'
  5. import device from '@system.device'

  6. // 地图列表
  7. const mapList = [
  8.   {
  9.     uri: 'baidumap://map/navi',
  10.     packageName: 'com.baidu.BaiduMap',
  11.     name: '百度地图'
  12.   },
  13.   {
  14.     uri: 'androidamap://navi',
  15.     packageName: 'com.autonavi.minimap',
  16.     name: '高德地图'
  17.   },
  18.   {
  19.     uri: 'qqmap://map/routeplan',
  20.     packageName: 'com.tencent.map',
  21.     name: '腾讯地图'
  22.   }
  23. ]

  24. export default {
  25.   protected: {
  26.     // 位置名称  必填
  27.     name: '故宫',
  28.     // 地址  必填
  29.     address: '故宫',
  30.     // 缩放级别
  31.     scale: 17,
  32.     //gcj02坐标系 必填
  33.     latitude: 0,
  34.     longitude: 0,
  35.   },
  36.   private: {
  37.     //是否显示我的位置
  38.     showMylocation: false,
  39.     // 位置标注
  40.     markers: [],
  41.     // 我的位置控制
  42.     controls: [
  43.       {
  44.         id: 1,
  45.         iconPath: './icon_location_btn.png',
  46.         position: {
  47.           right: 20,
  48.           bottom: 20,
  49.           width: 120,
  50.           height: 120
  51.         }
  52.       }
  53.     ],
  54.     // 是否显示导航按钮
  55.     isShowNav: true

  56.   },
  57.   onInit() {
  58.     let {
  59.       name,
  60.       address,
  61.       latitude,
  62.       longitude,
  63.       scale,
  64.     } = this

  65.     scale = scale && !isNaN(scale) ? scale : 17

  66.     //设置位置标注
  67.     this.markers = [
  68.       {
  69.         latitude,
  70.         longitude,
  71.         width: 160,
  72.         height: 160,
  73.         iconPath: 'http://mapp.alicdn.com/1544079046704Gq25RHeyZTQ7hJd.jpg',
  74.         callout: {
  75.           content: name,
  76.           display: 'always',
  77.           borderRadius: 10,
  78.           padding: 20,
  79.           fontSize: 28,
  80.           backgroundColor: '#FF9645',
  81.           color: '#ffffff'
  82.         }
  83.       }
  84.     ]
  85.     //对应品牌隐藏信息
  86.     this.checkDecive()


  87.   },
  88.   // 我的位置组件点击
  89.   controlTap(event) {
  90.     if (event.controlId === 1) {
  91.       this.showMylocation = true
  92.       this.$element('map').moveToMyLocation()
  93.     }
  94.   },
  95.   // 检查设备信息 并对不支持的品牌隐藏按钮
  96.   checkDecive() {
  97.     device.getInfo()
  98.       .then(({ brand }) => {
  99.         brand = brand.toLocaleLowerCase();
  100.         if (brand.indexOf('vivo') !== -1) {
  101.           this.isShowNav = false;
  102.         }
  103.       })
  104.   },
  105.   // 打开导航
  106.   goNavigation() {
  107.     let {
  108.       name,
  109.       address,
  110.       latitude,
  111.       longitude,
  112.     } = this
  113.     // 操作框选择需要打开的地图
  114.     prompt.showContextMenu({
  115.       itemList: mapList.map(v => v.name),
  116.       success: (res) => {
  117.         let index = res.index
  118.         let item = mapList[index]
  119.         // 检查是否安装了对应的地图app
  120.         pkg.hasInstalled({
  121.           package: item.packageName
  122.         })
  123.           .then((res) => {

  124.             let result = res.data.result
  125.             if (result) {
  126.               let url
  127.               //百度地图
  128.               if (index === 0) {
  129.                 // 将gcj02坐标系转化成百度坐标系
  130.                 const {
  131.                   lat, lng
  132.                 } = go_decrypt_bd(latitude, longitude)
  133.                 url = `baidumap://map/direction?destination=${name}|latlng:${lat},${lng}|addr:${address}&src=org.tujia.hotel&coord_type=gcj02`
  134.               }
  135.               //高德地图
  136.               else if (index === 1) {
  137.             
  138.                 url = `amapuri://route/plan?dlat=${latitude}&dlon=${longitude}&dname=${name}&dev=0&t=0`
  139.               }
  140.               //腾讯地图
  141.               else if (index === 2) {
  142.                 url = `qqmap://map/routeplan?type=drive&referer=kpweizhi&from=我的位置&fromcoord=CurrentLocation&to=${name}&tocoord=${latitude},${longitude}`
  143.               }

  144.               router.push({
  145.                 uri: url
  146.               })
  147.             }
  148.             else {
  149.               prompt.showToast({
  150.                 message: '请先安装' + item.name
  151.               })
  152.             }
  153.           })
  154.           .catch(err => {
  155.             console.log('err:', err)
  156.           })
  157.       }
  158.     })
  159.   }
  160. }


  161. /**
  162. * gcj02坐标系转化成百度地图坐标系
  163. *
  164. * @param {number} lat     gcj02纬度
  165. * @param {number} lng     gcj02经度
  166. * @returns {number,number}     百度地图经纬度
  167. */
  168. function go_decrypt_bd(lat, lng) {
  169.   var x_pi = (Math.PI * 3000) / 180.0
  170.   var x = lng,
  171.     y = lat
  172.   var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi)
  173.   var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi)
  174.   lng = z * Math.cos(theta) + 0.0065
  175.   lat = z * Math.sin(theta) + 0.006
  176.   return {
  177.     lat,
  178.     lng
  179.   }
  180. }
复制代码


使用方法:
  1. router.push({
  2.   uri: 'pages/openLocation',
  3.   params: {
  4.     name: '故宫',
  5.     address: '北京市东城区景山街前街4号',
  6.     scale: 17,
  7.     latitude:116.397067,
  8.     longitude:39.917399
  9.   }
  10. })
复制代码



看完代码,大家就知道了,其实就是通过地图组件和url scheme功能来适配的openLocation,功能很完美。其实快应用相对其他平台很开放,有很多功能值得探索。


提供几张效果图:


Screenshot_2019-07-24-22-34-55-380_org.hapjs.mock.png Screenshot_2019-07-24-22-35-00-366_org.hapjs.mock.png Screenshot_2019-07-24-22-35-59-187_com.autonavi.m.png






回复

使用道具 举报

7

主题

162

帖子

845

积分

2019-11-18 14:29:37 显示全部楼层
666
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册