小demo,不太建议完全照抄,需要的可以在上边完成拓展,不喜勿喷!!!
这个功能最重要的就是路线规划,路线两端分别是点外卖的人,商家,送外卖的骑手,商家的位置,后端接口直接就能拿到给前端,而用户的位置,由于地址是自己填的,因此前端也可以轻松的拿到地址转为经纬度。那骑手的位置呢?这就要从第三方物流接口去获取了,那得看实际的项目接入的是顺丰,美团还是哒哒或者其他什么。而且这个小demo也不需要那么复杂,虽然没有骑手位置,那就简单模拟一下好了。首先在小程序上创建一张地图出来:
代码语言:javascript复制<view class="map-container">
<map class="gaode-map" id="map" markers="{{markers}}" longitude="{{longitude}}" polyline="{{polyline}}" latitude="{{latitude}}" scale="14"></map>
</view>
css
代码语言:javascript复制 page,html,body {
width:100%;
height:100%;
}
.map-container {
width:100%;
height:100%;
}
.gaode-map {
width:100%;
height:100%;
}
js文件
代码语言:javascript复制const gaodeMap = require('../../amap-wx.js'); // 引入高德sdk
const map = new gaodeMap.AMapWX({
key: 'xxxxxxxx' // 高德申请的key
});
Page({
data: {
longitude: 116.397128, // 给个默认的经纬度 定位到北京天安门
latitude: 39.916527, //
distance: 0, // 骑手距离
cost: 0, // 大概时间
polyline: [], // 存放路线的经纬度
markers: [{ // 自己设置的三个mark标记,分别是 商家,用户,骑手
iconPath: "/images/shangjia.png",
id: 0,
latitude: 39.916527,
longitude: 116.397128,
width: 20,
height: 23
}, {
iconPath: "/images/weizhi.png",
id: 1,
latitude: 31.23035,
longitude: 121.473717,
width: 20,
height: 23
}, {
iconPath: "/images/qishou.png",
id: 2,
latitude: 31.23035,
longitude: 121.473717,
width: 20,
height: 23
}],
},
// 获取用户位置信息
getUserLocation() {
let that = this
wx.getLocation({
success: (res) => {
that.setData({
longitude: res.longitude,
latitude: res.latitude,
['markers[0].latitude']: res.latitude,
['markers[0].longitude']: res.longitude
}, () => {
map.getRidingRoute({
origin: '121.473717,31.23035', // 路线规划的起点 随便在我附近搜的位置转的经纬度
destination: `${res.longitude},${res.latitude}`, // 目的地经纬度
success: (data) => {
let points = [];
let distance = 0
let cost = 0
if (data.paths && data.paths[0] && data.paths[0].steps) {
var steps = data.paths[0].steps;
for (var i = 0; i < steps.length; i ) {
var poLen = steps[i].polyline.split(';');
for (var j = 0; j < poLen.length; j ) {
points.push({
longitude: parseFloat(poLen[j].split(',')[0]),
latitude: parseFloat(poLen[j].split(',')[1])
})
}
}
}
if (data.paths[0] && data.paths[0].distance) {
distance = data.paths[0].distance '米'
}
if (data.paths[0] && data.paths[0].duration) {
cost = parseInt(data.paths[0].duration / 60) '分钟'
}
that.setData({
polyline: [{
points: points,
color: "#0091ff",
width: 6
}],
distance,
cost,
['markers[2].longitude']: points[120].longitude,
['markers[2].latitude']: points[120].latitude
})
let tempNum = 0
// 设置一个定时器根据路线规划上的经纬度每100毫秒前进一步
let timer = setInterval(()=>{
if(tempNum >= points.length){
// 跑完了规划路线就停止
clearInterval(this.data.timer)
}
if(!this.data.timer){
// 将定时器设置为全局的,方便退出组件时销毁
this.setData({
timer:timer
})
}
//
this.setData({
['markers[2].longitude']: points[ tempNum].longitude,
['markers[2].latitude']: points[ tempNum].latitude
})
},100)
}
})
})
},
})
},
// 用户授权
userAuth() {
wx.getSetting({
success: (res) => {
if (!res.authSetting['scope.userLocation']) {
wx.authorize({
scope: 'scope.userLocation',
success: () => {
// 同意授权位置
this.getUserLocation()
},
fail: () => {
wx.showModal({
content: '拒绝授权将无法获取您的位置,请授权。',
showCancel: false,
success: (r) => {
if (r.confirm) {
// 打开设置页面让用户手动开启权限
wx.openSetting({
success:(v)=>{
}
})
}
}
})
}
})
}
},
})
},
onLoad: function () {
},
onShow:function(){
this.userAuth()
},
onUnload:function(){
clearInterval(this.data.timer)
}
})
s文件50行之下的那段代码是直接从高德文档copy过来的,顺便修改了一下。当调用高德的getRidingRoute函数之后,传入两个点的经纬度,他会返回一长串数组形式的经纬度给我们:
polyline就是我们需要的路线的经纬度,在代码中经过for循环去取出经纬度计算,就可以拿到预计达到时间以及路程长短,这个计算并不难,而且高德文档本身就有,上面那段计算的代码就是现成的。为了模拟出那个骑手移动的效果,我在下面加了一个定时器,每100毫秒让电动车图标根据路线的经纬度移动一下,但实际情况的话,骑手的位置应该是由其他接口给前端才对,这里只是为了看看效果,仅此而已。地图上的那条路线,只是用来给用户看的而已,因为别人在送外卖的时候,不止送一份,还会去给别人,因此在地图上获取骑手位置的时候,人家可能压根不在那条线上,也可能是走其他小路穿插,这都是正常的。还有就是骑手的位置也并非实时更新,我看美团的好像就不是实时更新,而是隔一段时间更新一次,前端做个轮询就好了,简单粗暴。以上代码示例并非真实项目,只是为了看实现效果写的小示例而已。