• Welcome to Journal web site.

我是 PHP 程序员

- 开发无止境 -

Next
Prev

(1条消息) 小程序路线规划,计算长度以及行驶时间_优倍素材网技术总结

Data: 2016-04-22 16:19:53Form: JournalClick: 7

小程序路线规划,计算长度以及行驶时间
(1条消息) 小程序路线规划,计算长度以及行驶时间_优倍素材网技术总结-CSDN博客

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

项目效果图:

关键字知识点:获取本机定位,地图标点markers,路线规划接口使用以及时间,距离转换

关联知识点已经在其他几个文章有说明:

获取本机定位:https://blog.csdn.net/qq_27987023/article/details/91043029

时间距离转换:https://blog.csdn.net/qq_27987023/article/details/97368737

地图标点文档:

marker

标记点用于在地图上显示标记的位置

属性说明类型必填备注最低版本
id标记点 idnumbermarker 点击事件回调会返回此 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文本string1.2.0
color文本颜色string1.2.0
fontSize文字大小number1.2.0
borderRadius边框圆角number1.2.0
borderWidth边框宽度number2.3.0
borderColor边框颜色string2.3.0
bgColor背景色string1.2.0
padding文本边缘留白number1.2.0
display'BYCLICK':点击显示; 'ALWAYS':常显string1.2.0
textAlign文本对齐方式。有效值: left, right, centerstring1.6.0

map组件构成

  1. <!--参数说明:latitude,longitude中心点坐标,scale:缩放等级;markers:地图气泡;polyline:路线;bindmarkertap:点击气泡触发事件;bindtap:点击地图触发事件-->

  2. <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">

  3.   </map>

我的项目接口返回站点数据格式:

marks核心数据组装

  1. //获取网点信息

  2. get_list:function(){

  3.       wx.showToast({

  4.         title: '页面加载中',

  5.       icon: 'loading',

  6.       });

  7.       let _this = this,

  8.       markers = new Array();

  9.       app._post('getDevGroup', {}, function(result){

  10.       if(result.code == 4003){

  11.         wx.navigateTo({

  12.           url:'/pages/index/login'

  13.         })

  14.       }else{

  15.         for(var i=0;i<result.data.length;i++){

  16.           markers[i] = new Object();

  17.           markers[i]['id'] = i;

  18.           markers[i]['site_id'] = result.data[i].id;

  19.           markers[i]['latitude'] = parseFloat(result.data[i].latitude);

  20.           markers[i]['longitude'] = parseFloat(result.data[i].longitude);

  21.           markers[i]['address'] = result.data[i].address;

  22.           markers[i]['site_price'] = result.data[i].price;

  23.           markers[i]['dev_outlets_ImgPath'] = result.data[i].outletsImgPath;

  24.           markers[i]['countData'] = result.data[i].countData;

  25.           markers[i]['callout'] = new Object();

  26.           markers[i]['callout']['content'] = result.data[i].outletsName;

  27.           markers[i]['callout']['padding'] = 6;

  28.           markers[i]['callout']['bgColor'] = "#000000";

  29.           markers[i]['callout']['color'] = '#ffffff';

  30.           markers[i]['callout']['display'] = 'BYCLICK';

  31.           markers[i]['callout']['textAlign'] = 'center';

  32.           markers[i]['callout']['borderRadius'] = 6;

  33.           markers[i]['iconPath'] = '/images/mark.png';

  34.           markers[i]['height'] = 30;

  35.           markers[i]['width'] = 30;

  36.         }

  37.         _this.setData({

  38.           markers:markers

  39.         })

  40.         wx.hideToast({});

  41.       }

  42.     });

  43.   },

至此,地图上会显示返回标注的站点信息,接下来就是点击设置路线规划接口
//获取路线规划,四个参数分别为起始点经纬度,终点经纬度
  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;
  },
Name:
<提交>