项目所需状态:进入小程序获取位置授权并显示站点,点击站点返回对应站点信息。
项目效果图:

关键字知识点:获取本机定位,地图标点markers,路线规划接口使用以及时间,距离转换
关联知识点已经在其他几个文章有说明:
获取本机定位:https://blog.csdn.net/qq_27987023/article/details/91043029
时间距离转换:https://blog.csdn.net/qq_27987023/article/details/97368737
地图标点文档:
marker
标记点用于在地图上显示标记的位置
属性 | 说明 | 类型 | 必填 | 备注 | 最低版本 |
---|
id | 标记点 id | number | 否 | marker 点击事件回调会返回此 id。建议为每个 marker 设置上 number 类型 id,保证更新 marker 时有更好的性能。 | |
latitude | 纬度 | number | 是 | 浮点数,范围 -90 ~ 90 | |
longitude | 经度 | number | 是 | 浮点数,范围 -180 ~ 180 | |
title | 标注点名 | string | 否 | 点击时显示,callout存在时将被忽略 | |
zIndex | 显示层级 | number | 否 | | 2.3.0 |
iconPath | 显示的图标 | string | 是 | 项目目录下的图片路径,支持相对路径写法,以'/'开头则表示相对小程序根目录;也支持临时路径和网络图片(2.3.0) | |
rotate | 旋转角度 | number | 否 | 顺时针旋转的角度,范围 0 ~ 360,默认为 0 | |
alpha | 标注的透明度 | number | 否 | 默认 1,无透明,范围 0 ~ 1 | |
width | 标注图标宽度 | number/string | 否 | 默认为图片实际宽度 | |
height | 标注图标高度 | number/string | 否 | 默认为图片实际高度 | |
callout | 自定义标记点上方的气泡窗口 | Object | 否 | 支持的属性见下表,可识别换行符。 | 1.2.0 |
label | 为标记点旁边增加标签 | Object | 否 | 支持的属性见下表,可识别换行符。 | 1.2.0 |
anchor | 经纬度在标注图标的锚点,默认底边中点 | Object | 否 | {x, y},x 表示横向(0-1),y 表示竖向(0-1)。{x: .5, y: 1} 表示底边中点 | 1.2.0 |
aria-label | 无障碍访问,(属性)元素的额外描述 | string | 否 | | 2.5.0 |
marker 上的气泡 callout
属性 | 说明 | 类型 | 最低版本 |
---|
content | 文本 | string | 1.2.0 |
color | 文本颜色 | string | 1.2.0 |
fontSize | 文字大小 | number | 1.2.0 |
borderRadius | 边框圆角 | number | 1.2.0 |
borderWidth | 边框宽度 | number | 2.3.0 |
borderColor | 边框颜色 | string | 2.3.0 |
bgColor | 背景色 | string | 1.2.0 |
padding | 文本边缘留白 | number | 1.2.0 |
display | 'BYCLICK':点击显示; 'ALWAYS':常显 | string | 1.2.0 |
textAlign | 文本对齐方式。有效值: left, right, center | string | 1.6.0 |
map组件构成
<!--参数说明:latitude,longitude中心点坐标,scale:缩放等级;markers:地图气泡;polyline:路线;bindmarkertap:点击气泡触发事件;bindtap:点击地图触发事件-->
<map id="myMap" style="width: 100%; height: 100%;" latitude="{{latitude}}" longitude="{{longitude}}" scale="12" show-location='true' show-compass="true" markers="{{markers}}" polyline="{{polyline}}" bindmarkertap="markertap" bindtap="change_type">
</map>
我的项目接口返回站点数据格式:

marks核心数据组装
get_list:function(){
wx.showToast({
title: '页面加载中',
icon: 'loading',
});
let _this = this,
markers = new Array();
app._post('getDevGroup', {}, function(result){
if(result.code == 4003){
wx.navigateTo({
url:'/pages/index/login'
})
}else{
for(var i=0;i<result.data.length;i++){
markers[i] = new Object();
markers[i]['id'] = i;
markers[i]['site_id'] = result.data[i].id;
markers[i]['latitude'] = parseFloat(result.data[i].latitude);
markers[i]['longitude'] = parseFloat(result.data[i].longitude);
markers[i]['address'] = result.data[i].address;
markers[i]['site_price'] = result.data[i].price;
markers[i]['dev_outlets_ImgPath'] = result.data[i].outletsImgPath;
markers[i]['countData'] = result.data[i].countData;
markers[i]['callout'] = new Object();
markers[i]['callout']['content'] = result.data[i].outletsName;
markers[i]['callout']['padding'] = 6;
markers[i]['callout']['bgColor'] = "#000000";
markers[i]['callout']['color'] = '#ffffff';
markers[i]['callout']['display'] = 'BYCLICK';
markers[i]['callout']['textAlign'] = 'center';
markers[i]['callout']['borderRadius'] = 6;
markers[i]['iconPath'] = '/images/mark.png';
markers[i]['height'] = 30;
markers[i]['width'] = 30;
}
_this.setData({
markers:markers
})
wx.hideToast({});
}
});
},
至此,地图上会显示返回标注的站点信息,接下来就是点击设置路线规划接口
//获取路线规划,四个参数分别为起始点经纬度,终点经纬度
get_line_info:function(my_latitude,my_longitude,to_latitude,to_longitude){
var that =this,
coors = '',
distance = '',
duration = '',
need_time = '',
need_drive = '',
coors = '';
wx.showToast({
title: '路线规划中',
icon: 'loading',
});
if(my_latitude){
wx.request({
url:'https://apis.map.qq.com/ws/direction/v1/driving/?from='+my_latitude+','+my_longitude+'&to='+to_latitude+','+to_longitude+'&output=json&callback=cb&key=', //拼接上自己的key
success:function(res){
coors = res.data.result.routes[0].polyline;
duration = res.data.result.routes[0].duration; //方案所耗费时间
distance = res.data.result.routes[0].distance; //方案距离
for(var i=2; i< coors.length; i++) {
coors[i]= coors[i-2]+ coors[i]/1000000
}
var b=[];
for(var i=0; i< coors.length; i=i+2) {
b[i/2]={latitude: coors[i],longitude:coors[i+1]};
}
need_time = that.ChangeHourMinutestr(duration); //转换成小时或者分钟
need_drive = that.Changedistance(distance); //转换成千米或者米
that.setData({
polyline: [{
points: b,
color:"#0F9D77",
width:5,
dottedLine:false
}],
need_time: need_time,
need_drive: need_drive,
})
wx.hideToast({});
}
})
}else{
wx.showToast({
title: '请重新加载并授权获取您的位置',
icon: 'none',
});
}
},
现在路线规划接口已经预设好,同时地图上的marks也包含有自己的经纬度信息,则点击气泡,触发路线规划
markertap(e) {
let _this = this,
markers = _this.data.markers,
my_latitude = parseFloat(wx.getStorageSync('my_latitude')),
my_longitude = parseFloat(wx.getStorageSync('my_longitude')),
markerId = e.markerId;
var to_latitude = markers[markerId].latitude
var to_longitude = markers[markerId].longitude
_this.get_line_info(parseFloat(my_latitude),parseFloat(my_longitude),parseFloat(to_latitude),parseFloat(to_longitude));
//处理站点图片
_this.setData({
site_name:markers[markerId]['callout'].content, //站点名称
site_address:markers[markerId].address, //站点地址
site_img:app.upload_path+markers[markerId].dev_outlets_ImgPath, //站点图片
site_price:markers[markerId].site_price*60, //价格
countData:markers[markerId].countData, //可用设备数量
site_id:markers[markerId].site_id, //站点ID
to_latitude:to_latitude, //站点经纬度
to_longitude:to_longitude,
showmodel:true,
})
},
至此大功告成,另外有个计算最近站点的接口,我个人感觉有待优化,用的是返回的站点数组,一次性取出所有的站点距离,然后用冒泡方法去比对,取的最近距离即可,这个站点少倒无所谓,站点多的话估计就凉凉。
//计算最近的距离点
get_nearest_address:function(){
let _this = this,
markers = _this.data.markers,
my_latitude = parseFloat(wx.getStorageSync('my_latitude')),
my_longitude = parseFloat(wx.getStorageSync('my_longitude'));
if(my_latitude){
//有地理位置信息
var to_address = '';
wx.showToast({
title: '获取最近网点中',
icon: 'loading',
});
for(var p in markers){
to_address += markers[p].latitude+','+markers[p].longitude+';'
}
to_address = to_address.substring(0,to_address.length-1);
wx.request({
url:'https://apis.map.qq.com/ws/distance/v1/?mode=driving&from='+my_latitude+','+my_longitude+'&to='+to_address+'&key=4INBZ-SICW3-N433U-3HXH4-IEILO-HRF4N',
success:function(res){
var data_info = res.data.result.elements;
var check_data = new Array();
for(var p in data_info){
check_data[p] = data_info[p].distance
}
var back_distance = _this.get_min_num(check_data);
for(var p in data_info){
if(data_info[p].distance == back_distance){
//找到最近网点,进行路线规划
var to_latitude = markers[p].latitude
var to_longitude = markers[p].longitude
_this.get_line_info(parseFloat(my_latitude),parseFloat(my_longitude),parseFloat(to_latitude),parseFloat(to_longitude));
//处理返回的站点图片
var img_array = markers[p].dev_outlets_ImgPath.split(",");
_this.setData({
showmodel:true,
site_name:markers[p]['callout'].content,
site_img:app.upload_path+img_array[0],
site_address:markers[p].address,
site_price:markers[p].site_price*60,
site_id:markers[p].site_id,
countData:markers[p].countData,
to_latitude:to_latitude,
to_longitude:to_longitude,
})
wx.hideToast({});
}
}
}
})
}else{
_this.getlocation();
}
},
调用冒泡获取最小值:
//获取数组中最小的数
get_min_num:function(array){
var min = array[0];
for(var i = 1; i < array.length; i++) {
var cur = array[i];
cur < min ? min = cur : null
}
return min;
},