
来源:快应用官方论坛
作者:初冬、阳光
大家都知道,其他平台小程序,都有官方提供的openLocation接口(通过位置坐标在地图上显示对应的标注,同时支持导航),但是快应用官方没有提供,其实官方并不是没有提供,而是提供了更自由的方式。接下来我给大家介绍一下快应用openLocation适配。
01
首先写好页面的布局模板,展示一个地图,一个地址展示栏,一个导航按钮,一个我的位置控制组件,代码如下:
<template> <div class="open-location-contanier"> <map id='map' class='map' markers="{{markers}}" controls="{{controls}}" @controltap="controlTap" latitude="{{latitude}}" longitude="{{longitude}}" scale="{{scale}}" showmylocation="{{showMylocation}}"></map> <div class='map-tool'> <div class='location-info-box'> <text class='location-name'>{{name}}</text> <text class='location-address'>{{address}}</text> </div> <text class='location-btn' if='{{isShowNav}}' @click="goNavigation">导航</text> </div> </div> </template> |
2、
<style> .open-location-contanier { display: flex; flex: 1; flex-direction: column; } .location-info-box { height: 200px; background-color: #fff; display: flex; flex-direction: column; justify-content: center; } .location-name { font-size: 34px; color: #333; width: 500px; lines: 1; text-overflow: ellipsis; }
.location-address { font-size: 24px; line-height: 30px; color: #666; width: 500px; lines: 1; text-overflow: ellipsis; } .map { flex: 1; } .map-tool { display: flex; justify-content: space-between; align-items: center; padding: 0 40px; } </style> |
3、页面js逻辑
<script> import router from '@system.router' import prompt from '@system.prompt' import pkg from '@system.package' import device from '@system.device'
// 地图列表 const mapList = [ { uri: 'baidumap://map/navi', packageName: 'com.baidu.BaiduMap', name: '百度地图' }, { uri: 'androidamap://navi', packageName: 'com.autonavi.minimap', name: '高德地图' }, { uri: 'qqmap://map/routeplan', packageName: 'com.tencent.map', name: '腾讯地图' } ]
export default { protected: { // 位置名称 必填 name: '故宫', // 地址 必填 address: '故宫', // 缩放级别 scale: 17, //gcj02坐标系 必填 latitude: 0, longitude: 0, }, private: { //是否显示我的位置 showMylocation: false, // 位置标注 markers: [], // 我的位置控制 controls: [ { id: 1, iconPath: './icon_location_btn.png', position: { right: 20, bottom: 20, width: 120, height: 120 } } ], // 是否显示导航按钮 isShowNav: true
}, onInit() { let { name, address, latitude, longitude, scale, } = this
scale = scale && !isNaN(scale) ? scale : 17
//设置位置标注 this.markers = [ { latitude, longitude, width: 160, height: 160, iconPath: 'http://mapp.alicdn.com/1544079046704Gq25RHeyZTQ7hJd.jpg', callout: { content: name, display: 'always', borderRadius: 10, padding: 20, fontSize: 28, backgroundColor: '#FF9645', color: '#ffffff' } } ] //对应品牌隐藏信息 this.checkDecive()
}, // 我的位置组件点击 controlTap(event) { if (event.controlId === 1) { this.showMylocation = true this.$element('map').moveToMyLocation() } }, // 检查设备信息 并对不支持的品牌隐藏按钮 checkDecive() { device.getInfo() .then(({ brand }) => { brand = brand.toLocaleLowerCase(); if (brand.indexOf('vivo') !== -1) { this.isShowNav = false; } }) }, // 打开导航 goNavigation() { let { name, address, latitude, longitude, } = this // 操作框选择需要打开的地图 prompt.showContextMenu({ itemList: mapList.map(v => v.name), success: (res) => { let index = res.index let item = mapList[index] // 检查是否安装了对应的地图app pkg.hasInstalled({ package: item.packageName }) .then((res) => {
let result = res.data.result if (result) { let url //百度地图 if (index === 0) { // 将gcj02坐标系转化成百度坐标系 const { lat, lng } = go_decrypt_bd(latitude, longitude) url = `baidumap://map/direction?destination=${name}|latlng:${lat},${lng}|addr:${address}&src=org.tujia.hotel&coord_type=gcj02` } //高德地图 else if (index === 1) {
url = `amapuri://route/plan?dlat=${latitude}&dlon=${longitude}&dname=${name}&dev=0&t=0` } //腾讯地图 else if (index === 2) { url = `qqmap://map/routeplan?type=drive&referer=kpweizhi&from=我的位置&fromcoord=CurrentLocation&to=${name}&tocoord=${latitude},${longitude}` }
router.push({ uri: url }) } else { prompt.showToast({ message: '请先安装' + item.name }) } }) .catch(err => { console.log('err:', err) }) } }) } }
/** * gcj02坐标系转化成百度地图坐标系 * * @param {number} lat gcj02纬度 * @param {number} lng gcj02经度 * @returns {number,number} 百度地图经纬度 */ function go_decrypt_bd(lat, lng) { var x_pi = (Math.PI * 3000) / 180.0 var x = lng, y = 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) lng = z * Math.cos(theta) + 0.0065 lat = z * Math.sin(theta) + 0.006 return { lat, lng } } |
使用方法:
router.push({ uri: 'pages/openLocation', params: { name: '故宫', address: '北京市东城区景山街前街4号', scale: 17, latitude:116.397067, longitude:39.917399 } }) |
看完代码,大家就知道了,其实就是通过地图组件和
url scheme功能来适配的openLocation,功能很完美。其实快应用相对其他平台很开放,有很多功能值得探索。
提供几张效果图:


