快应用适配微信openLocation接口

248 阅读3分钟


来源:快应用官方论坛

作者:初冬、阳光


大家都知道,其他平台小程序,都有官方提供的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,功能很完美。其实快应用相对其他平台很开放,有很多功能值得探索。


提供几张效果图: