微信小程序自带地图map标签,他是基于canvas画图功能进行的地图渲染,同时依赖微信的getlocation获取经纬度,绘制周边地图。地图上可以标点,画线,查看当地地理信息。但是自带的导航功能模块不能对个人开发者公开。
高德地图提供了基于微信小程序map标签的导航功能,只需要将高德文件导入项目,即可获取周边地理信息及导航、天气等信息。返回数据为微信小程序map标签的markers和linear对象形式,只需要稍加修饰,便可实现类似于官方导航的功能。
主要过程为
本次使用的是uniapp 使用vue+默认小程序模板创建项目,
在manifest.json中开启位置授权
1.获取高德支持文件
在高德开放平台下载libs文件 并存放在项目文件夹内
微信原生开发直接按上文配置即可,uniapp的话有可能打包不过去,可以放在这里(一般不用),
然后vue3框架需要修改输出方式
这样import就可以正常引用
import amap from '../../libs/amap-wx.130.js'
2.绘制腾讯地图
在这里我们需要用原生的map先搞一个地图出来,同时wx.getlocation获取用户位置
这里的markers和polyline后面要用,先做个空的容器,其中markers可以先把当前位置标出来
<template>
<view class="map_container">
<map class="map" id="map"
:longitude="longitude" :latitude="latitude"
scale="14" show-location="true"
:markers="markers" bindmarkertap="makertap"
:polyline="polyline"
v-if="latitude"
></map>
</view>
<input type="text" placeholder="起点" v-model="start">
<input type="text" placeholder="终点" @input="bindinput" v-model="target">
<view class="tips" v-for="item in tips" :key="item.id" @click="selectThis(item)" >
{{item.name}}
</view>
<button @click="bindWalk">步行</button>
<button>驾车</button>
<button>公交</button>
</template>
在onload中初始化地图,并加载高德地图实例
onLoad() {
// 初始化高德地图对象
console.log(amap)
this.amap = new amap.AMapWX({key:'35e208c3050694260e292c0bb9eed6f1'})
// 初始化地图
let _this = this
uni.getLocation({
type: 'wgs84',//北斗
success: function (res) {
// _this.setData({
// longitude : res.longitude,
// latitude : res.latitude
// })
_this.markers =[..._this.markers,{
id:0,
longitude: res.longitude,
latitude:res.latitude,
height:30,
width:30,
iconPath:'../../static/logo.png'
}]
_this.longitude = res.longitude
_this.latitude = res.latitude
_this.points = [..._this.points,{
longitude: res.longitude,
latitude:res.latitude,
}]
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
}
});
3.获取导航信息并渲染
可以注意到我上方的结构是有input框的 ,他用于输入目的地
他的回调可以从高德处获取模糊查询结果,我门将其渲染到input框底部,当点击后选定,并执行后续搜索,点击选定与模糊搜素如下
bindinput(e){
console.log(e.target.value)
let keywords = e.target.value
// console.log(this.amap)
this.amap.getInputtips({
keywords:keywords,
location :'',
success:(res)=>{
if(res.tips[0]){
this.tips = res.tips
console.log(this.tips)
}
}
})
},
selectThis(item){
console.log(item)
// 记录location
let targetTemp = item.location.split(',')
this.target = item.name
this.tips=[]
// this.points = [...this.points,{
// longitude: targetTemp[0],
// latitude: targetTemp[1],
// }]
this.points[1] ={
longitude: targetTemp[0],
latitude: targetTemp[1],
}
this.markers =[...this.markers,{
id:2,
longitude: targetTemp[0],
latitude: targetTemp[1],
height:30,
width:30,
iconPath:'../../static/logo.png'
}]
},
html结构
然后我们点击上面的寻路按钮
他的回调是获取步行线路 this.amap.getWalkingRoute()
bindWalk(){
// console.log(">>",this.polyline)
this.polyline=[]
this.amap.getWalkingRoute(this.getDataObject());
},
而this.getDataObject()是输入目的地和目前位置的坐标(经纬度),在传入经纬度时我们可以同时传入success回调来处理getWalkingRoute的res,按照下文的方式可以分解为我们需要的画线对象,将其传入准备好的画线容器,大功告成
getDataObject(color){
let _this = this;
let colors = color || '#00AC62';
// console.log("@",this.points)
return{
origin:_this.points[0].longitude+','+_this.points[0].latitude,
destination:_this.points[1].longitude+','+_this.points[1].latitude,
success:function(data){
// console.log(">>",data)
if(!data.paths){
console.log('search failed')
return;
}
let steps = data.paths[0].steps
let points = []
// console.log(">",steps)
for(let i = 0 ; i <steps.length;i++){
let polylines = steps[i].polyline.split(';')
for(let j = 0 ; j <polylines.length;j++){
let locations = polylines[j].split(',');
points.push({
longitude: locations[0],
latitude: locations[1],
})
}
}
// 注意这里
_this.polyline =[{
points:points,
color:colors,
width:6
}]
// _this.polyline =[..._this.polyline,{
// points:points,
// color:colors,
// width:6
// }]
// console.log("@",_this.polyline)
}
}
}
演示
:
再吃输入,这里有一点需要注意,再次寻路时清空线路数组,始发地目前是本地,如果用选择目的地相同的方法选择始发地,替换掉markers的第一项,并将其经纬度替换后传入getWalkingRoute可以获得两点导航,如果只是目的地导航,则要保证markers第一个点不动
还有一点markers第一个本地位置是初始化后就有的,入伙需要动态导航还需要双向绑定第一个标点与本人位置的经纬度,我的方法是当经纬度变化时重新标点,然后将位已规划好的线路按当前位置分为两段(filter),用不同颜色标识。(我正在写,所以不提供代码只提供思路)