微信小程序----map组件实现(路线规划)

WXRUI体验二维码

WXRUI体验码

如果文章对你有帮助的话,请打开微信扫一下二维码,点击一下广告,支持一下作者!谢谢!

效果图

这里写图片描述

实现原理

  1. 通过map组件标记起始点和绘制路线图;
  2. 通过高德地图API获取不同类型的路线坐标点,以及耗费时间和路程。

WXML

<view class="flex-style">
  <view class="flex-item {{status == 'car' ? 'active' : ''}}" data-status="car" bindtouchstart="goTo">驾车</view>
  <view class="flex-item {{status == 'walk' ? 'active' : ''}}" data-status="walk" bindtouchstart="goTo">步行</view>
  <view class="flex-item {{status == 'bus' ? 'active' : ''}}" data-status="bus" bindtouchstart="goTo">公交</view>
  <view class="flex-item {{status == 'ride' ? 'active' : ''}}" data-status="ride" bindtouchstart="goTo">骑行</view>
</view>
<view class="map-inputtips-input">
  <input bindinput="bindInput" placeholder="输入终点" focus="true" />
</view>
<view class="map-search-list {{isShow ? '' : 'map-hide'}}">
  <view bindtouchstart="bindSearch" wx:key="searchId" data-keywords="{{item.name}}" data-location="{{item.location}}" class="map-box" wx:for="{{tips}}">
    {{item.name}}
  </view>
</view>

<view class="map_box {{detailStatus ? 'active' : ''}}">
  <map id="navi_map" longitude="{{longitude}}" latitude="{{latitude}}" scale="14" include-points='{{points}}' markers="{{markers}}" polyline="{{polyline}}"></map>
</view>

<view class="text_box {{detailStatus ? '' : 'map-hide'}}">
  <view class="text">路程:{{distance}}米</view>
  <view class="text">耗时:{{cost}}分钟</view>
  <view class="detail_button" bindtouchstart="goDetail">详情</view>
</view>

WXSS

.flex-style{
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
}
.flex-item{
  height: 35px; 
  line-height: 35px;
  text-align: center;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1
}
.flex-item.active{
  color:#0091ff;
}
.map_box{
  position:absolute;
  top: calc(35px + 80rpx);
  bottom: 0px;
  left: 0px;
  right: 0px;
}
.map_box.active{bottom: 90px;}
#navi_map{
  width: 100%;
  height: 100%;
}
.text_box{
  position:absolute;
  height: 90px;
  bottom: 0px;
  left: 0px;
  right: 0px;
}
.text_box .text{
  margin: 15px;
  color: lightseagreen;
}
.detail_button{
  position:absolute;
  bottom: 30px;
  right: 10px;
  padding: 3px 5px;
  color: #fff;
  background: #0091ff;
  width:50px;
  text-align:center;
  border-radius:5px;
}
.map-inputtips-input{
  height: 80rpx;
  line-height: 80rpx;
  width: 100%;
  box-sizing: border-box;
  font-size: 30rpx;
  padding: 0 10px;
  background-color: #fff;
  position: fixed;
  top: 35px;
  left: 0;
  z-index: 1000;
  border-bottom:1px solid #c3c3c3;
}
.map-inputtips-input input{
  border: 1px solid #ddd;
  border-radius: 5px;
  height: 60rpx;
  line-height: 60rpx;
  width: 100%;
  box-sizing: border-box;
  padding: 0 5px;
  margin-top: 10rpx;
}
.map-box{
  margin: 0 10px;
  border-bottom:1px solid #c3c3c3;
  height: 80rpx;
  line-height: 80rpx;
}
.map-box:last-child{border: none;}
.map-search-list{
  position: fixed;
  top: calc(80rpx + 35px);
  left: 0;
  width: 100%;
  z-index: 1000;
  background-color: #fff;
}

JS

const app = getApp();
const amap = app.data.amap;
const key = app.data.key;

Page({
  data: {
    longitude: '',
    latitude: '',
    isShow: false,
    detailStatus: false,
    status: '',
    markers: [],
    points: [],
    distance: '',
    cost: '',
    city: '',
    tips: {},
    polyline: []
  },
  onLoad() {
    var _this = this;
    wx.getLocation({
      success: function (res) {
        if (res && res.longitude) {
          _this.setData({
            longitude: res.longitude,
            latitude: res.latitude,
            points: [{
              longitude: res.longitude,
              latitude: res.latitude
            }],
            markers: [{
              id: 0,
              longitude: res.longitude,
              latitude: res.latitude,
              iconPath: '../../src/images/navi_s.png',
              width: 32,
              height: 32
            }]
          })
        }
      }
    })
  },
  bindInput: function (e) {
    var _this = this;
    var keywords = e.detail.value;
    var myAmap = new amap.AMapWX({ key: key });
    myAmap.getInputtips({
      keywords: keywords,
      location: '',
      success: function (res) {
        if (res && res.tips) {
          var address = res.tips[0].district;
          _this.setData({
            isShow: true,
            city: address.substring(address.indexOf('省') + 1, address.indexOf('市')),
            tips: res.tips
          });
        }
      }
    })
  },
  bindSearch: function (e) {
    var keywords = e.target.dataset.keywords;

    var location = e.target.dataset.location;
    location = location.split(',');
    if (this.data.markers.length > 1 && this.data.points.length > 1){
      this.data.markers.pop();
      this.data.points.pop();
      this.setData({ polyline:[]});
    }
    var markers = this.data.markers;
    var points = this.data.points;
    markers.push({
      id: 0,
      longitude: location[0],
      latitude: location[1],
      iconPath: '../../src/images/navi_e.png',
      width: 32,
      height: 32
    });
    points.push({
      longitude: location[0],
      latitude: location[1]
    })
    this.setData({
      isShow: false,
      markers: markers,
      points: points
    })
  },
  goTo(e) {
    if (this.data.points.length < 2) {
      wx.showToast({ title: '请输入终点' })
      return;
    }
    var status = e.target.dataset.status;
    var myAmap = new amap.AMapWX({ key: key });

    switch (status) {
      case 'car':
        myAmap.getDrivingRoute(this.getDataObj('#4B0082'));
        break;
      case 'walk':
        myAmap.getWalkingRoute(this.getDataObj());
        break;
      case 'bus':
        myAmap.getTransitRoute(this.getBusData('#008B8B'));
        break;
      case 'ride':
        myAmap.getRidingRoute(this.getDataObj('#00FFFF'));
        break;
      default:
        return;
    }
    this.setData({
      detailStatus: true,
      status: status
    })
  },
  getDataObj(color) {
    var _this = this;
    var color = color || "#0091ff";

    return {
      origin: _this.data.points[0].longitude + ',' + _this.data.points[0].latitude,
      destination: _this.data.points[1].longitude + ',' + _this.data.points[1].latitude,
      success(data) {
        var points = [];
        if (!data.paths || !data.paths[0] || !data.paths[0].steps) {
          wx.showToast({ title: '失败!' });
          return;
        }
        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])
              })
            }
          }
        }
        _this.setData({
          distance: data.paths[0].distance,
          cost: parseInt(data.paths[0].duration / 60),
          polyline: [{
            points: points,
            color: color,
            width: 6
          }]
        });
      },
      fail(info) {
        wx.showToast({ title: '失败!' })
      }
    }
  },
  getBusData(color) {
    var _this = this;
    var color = color || "#0091ff";

    return {
      origin: _this.data.points[0].longitude + ',' + _this.data.points[0].latitude,
      destination: _this.data.points[1].longitude + ',' + _this.data.points[1].latitude,
      city: _this.data.city,
      success(data) {
        var points = [], cost = 0;
        if (data && data.transits) {
          var transits = data.transits;
          for (var i = 0; i < transits.length; i++) {
            cost += parseInt(transits[i].duration);
            var segments = transits[i].segments;
            for (var j = 0; j < segments.length; j++) {
              if (segments[j].bus.buslines[0] && segments[j].bus.buslines[0].polyline) {
                var steps = segments[j].bus.buslines[0].polyline.split(';');
                for (var k = 0; k < steps.length; k++) {
                  var point = steps[k].split(',');
                  points.push({
                    longitude: point[0],
                    latitude: point[1]
                  })
                  if (parseInt(point[0] * 100000) === parseInt(_this.data.points[1].longitude * 100000) && parseInt(point[1] * 100000) === parseInt(_this.data.points[1].latitude * 100000)){
                    _this.setData({
                      distance: data.distance,
                      cost: parseInt(cost / 60),
                      polyline: [{
                        points: points,
                        color: color,
                        width: 6
                      }]
                    });
                    return ;
                  }
                }
              }
            }
          }
        }
      },
      fail(info) {
        wx.showToast({ title: '失败!' })
      }
    }
  }
})

实现步骤

  1. 利用 input 输入终点地址关键字;
  2. 通过关键字利用高德地图API(getInputtips)获取地址坐标列表;
  3. 列表添加选中事件,获取具体的 location ,进行地图标记;
  4. 选择路线类型(驾车,骑行等),通过高德地图对应的API获取规划坐标;
  5. 绘制路线。
  6. 注意:在返回的路线坐标数据格式,公交和其他三种方式的数据格式不同,需要单独进行处理(单独处理公交数据的方法: getBusData)

WXRUI体验二维码

WXRUI体验码

如果文章对你有帮助的话,请打开微信扫一下二维码,点击一下广告,支持一下作者!谢谢!

其他

我的博客,欢迎交流!

我的CSDN博客,欢迎交流!

微信小程序专栏

前端笔记专栏

微信小程序实现部分高德地图功能的DEMO下载

微信小程序实现MUI的部分效果的DEMO下载

微信小程序实现MUI的GIT项目地址

微信小程序实例列表

前端笔记列表

游戏列表

评论 75
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rattenking

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值