工作日志:用uniapp实现路线规划,导航,获取路程距离及时间

4,234 阅读5分钟

这是我的千日蜕变计划第二篇,我计划在未来的1000天,三天更新一篇博客。希望大家监督,也希望自己可以坚持。

内容:uni-app实现基础的导航功能 来源: 工作日常

功能分析

  1. 获取用户当前的位置
  2. 获取当前位置到目的地的路线规划
  3. 切换步行、骑行、驾车三种切换
  4. 调用第三方导航

效果图如下:

代码部分

html部分

<view>
            <view class="map-wrapper">
                <map :latitude="latitude" scale="12" :longitude="longitude" :markers="markers" :polyline="polyline" ></map>
                <view class="info-wrapper">
                    <view class="selectType">
                        <view @click="goTo('car')" class="type" :class="active === 'car' ? 'active' : ''">驾车</view>
                        <view @click="goTo('walk')" class="type" :class="active === 'walk' ? 'active' : ''">步行</view>
                        <view @click="goTo('ride')" class="type" :class="active === 'ride' ? 'active' : ''">骑行</view>
                    </view>
                    <view class="navigatePic" @click="handleNavigate">导航</view>
                    <view v-if="maxDuration && active!=='car'" class="info">
                        <text>距离太远,请选择合适的方式前往</text>
                    </view>
                    <view v-else class="info">
                        <text>{{duration | formatTime}}小时</text>
                        <text>{{distance | filterDistance}}公里</text>
                    </view>
                </view>
            </view>
        </view>
    </view>

JS部分

  • 数据部分
// 第一步: 需要引用高德导航的js文件
import amapFile from './amap-wx.js';
data() {
        return {
            title: 'map',
            latitude: xxx, // 目的地的位置
            longitude: xxx, // 目的地的位置
            key: 'c290b7e016c85e8f279b2f80018c6fbf', // 高德导航的key
            distance: 0,
            duration: 0,
            maxDuration: false,
            curentLatitude: '',
            curentLongitude: '',
            active: 'car',
            polyline: null,
            markers: [{
                latitude: 28.193688,
                longitude: 113.010925,
                // iconPath: '地图的标注icon',
                title:'xxx',
                label:{
                    content:'xxx',
                    color:'#F76350',
                    bgColor:'#fff',
                    padding:5,
                    borderRadius:4
                },
                callout:{
                    content:'xxx',
                    color:'#F76350',
                    fontSize:12
                }
            }, {
                latitude: 28.188597,
                longitude: 113.006853,
                // iconPath: '地图的标注icon',
                title:'您的位置',
                label:{
                    content:'您的位置',
                    color:'#F76350',
                    bgColor:'#fff',
                    padding:5,
                    borderRadius:4
                },
                callout:{
                    content:'您的位置',
                    color:'#F76350',
                    fontSize:12    
                }
            }]
        }
    },

  • 页面加载的时候执行的方法
// 获取当前用户的位置
uni.getLocation({
    type: 'gcj02',
    success: (res) => {
        // 这里给你的位置赋值
        this.markers[1].latitude = res.latitude;
        this.markers[1].longitude = res.longitude;
        this.currentLatitude = res.latitude;
        this.currentLongitude = res.longitude;
    },
    fail: function() {
        console.log('fail')
    },
    complete: () => {
        // 默认调用开车方式
        this.goTo('car')
    }
})

  • 绘制路线相关代码
drawPolyline(self,color){
    return {
      origin: this.longitude + ',' + this.latitude,
      destination: this.currentLongitude +',' +this.currentLatitude,
      success(data) {
        var points = [];
        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])
              })
            }
          }
        }
        self.distance= data.paths[0].distance;
        if(data.paths[0].distance / 1000 > 50) {
            self.maxDuration = true;
        } else {
            self.maxDuration = false;
        }
        self.duration= parseInt(data.paths[0].duration/60),
        self.polyline= [{
            points: points,
            color: color,
            width: 6,
            arrowLine: true
        }]
        
      },
      fail(e) {
          console.log(e)
      },
      complete() {
          console.log('complate')
      }
    }
  },
  
  getPolyline(_type){
    var amap = new amapFile.AMapWX({ key: this.key });
    var self = this;
    switch (_type){
      case 'car':
        amap.getDrivingRoute(this.drawPolyline(this,"#0091ff"));
        break;
      case 'walk':
        if(this.maxDuration) {
            return false;
        }
        amap.getWalkingRoute(this.drawPolyline(this, "#1afa29"));
        break;
      case 'ride':
        if(this.maxDuration) {
            return false;
        }
        amap.getRidingRoute(this.drawPolyline(this, "#1296db"));
        break;
      default:
        return false;
    }
  },
  • 最后点击切换方式时调用方法
goTo(_type){
    this.getPolyline(_type);
    this.active = _type;
  }

我是海明月,前端小学生。

我的千日蜕变计划正式启动,希望您能够监督我执行。谢谢。

如果有不对的地方,也希望大佬指正。

完整代码如下
<template>
    <view>
        <!-- <page-head :title="title"></page-head> -->
        <view class="uni-common-mt">
            <view>
                <view class="map-wrapper">
                    <map :latitude="latitude" scale="12" :longitude="longitude" :markers="markers" :polyline="polyline" ></map>
                    <view class="info-wrapper">
                        <view class="selectType">
                            <view @click="goTo('car')" class="type" :class="active === 'car' ? 'active' : ''">驾车</view>
                            <view @click="goTo('walk')" class="type" :class="active === 'walk' ? 'active' : ''">步行</view>
                            <view @click="goTo('ride')" class="type" :class="active === 'ride' ? 'active' : ''">骑行</view>
                        </view>
                        <view class="navigatePic" @click="handleNavigate">导航</view>
                        <view v-if="maxDuration && active!=='car'" class="info">
                            <text>距离太远,请选择合适的方式前往</text>
                        </view>
                        <view v-else class="info">
                            <text>{{duration | formatTime}}小时</text>
                            <text>{{distance | filterDistance}}公里</text>
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    import amapFile from './amap-wx.js';
    export default {
        data() {
            return {
                title: 'map',
                // latitude: 31.886143, // 万达的位置
                // longitude: 117.344212, // 万达管家的位置
                latitude: 28.193688, // 白白管家的位置
                longitude: 113.010925, // 白白管家的位置
                key: 'c290b7e016c85e8f279b2f80018c6fbf',
                distance: 0,
                duration: 0,
                maxDuration: false,
                curentLatitude: '',
                curentLongitude: '',
                active: 'car',
                polyline: null,
                markers: [{
                    latitude: 28.193688,
                    longitude: 113.010925,
                    // iconPath: '../../static/location@3x.png',
                    title:'白白管家',
                    label:{
                        content:'白白管家',
                        color:'#F76350',
                        bgColor:'#fff',
                        padding:5,
                        borderRadius:4
                    },
                    callout:{
                        content:'白白管家',
                        color:'#F76350',
                        fontSize:12
                    }
                }, {
                    latitude: 28.188597,
                    longitude: 113.006853,
                    // iconPath: '../../static/location@3x.png',
                    title:'您的位置',
                    label:{
                        content:'您的位置',
                        color:'#F76350',
                        bgColor:'#fff',
                        padding:5,
                        borderRadius:4
                    },
                    callout:{
                        content:'您的位置',
                        color:'#F76350',
                        fontSize:12    
                    }
                }]
            }
        },
        onLoad() {
            console.log('amapFile', amapFile)
            uni.getLocation({
                type: 'gcj02',
                success: (res) => {
                    this.markers[1].latitude = res.latitude;
                    this.markers[1].longitude = res.longitude;
                    this.currentLatitude = res.latitude;
                    this.currentLongitude = res.longitude;
                },
                fail: function() {
                    console.log('fail')
                },
                complete: () => {
                    this.goTo('car')
                }
            })
        },
        methods: {
            handleNavigate() {
                uni.openLocation({
                    latitude: this.latitude,
                    longitude: this.longitude,
                    name: '白白管家',
                    address: '长沙火车站对面',
                    success: function () {
                        console.log('success');
                    }
                });
            },
            drawPolyline(self,color){
                return {
                  origin: this.longitude + ',' + this.latitude,
                  destination: this.currentLongitude +',' +this.currentLatitude,
                  success(data) {
                    var points = [];
                    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])
                          })
                        }
                      }
                    }
                    self.distance= data.paths[0].distance;
                    console.log(data.paths[0].distance / 1000 > 50)
                    console.log(self.active !== 'car')
                    if(data.paths[0].distance / 1000 > 50) {
                        self.maxDuration = true;
                    } else {
                        self.maxDuration = false;
                    }
                    self.duration= parseInt(data.paths[0].duration/60),
                    self.polyline= [{
                        points: points,
                        color: color,
                        width: 6,
                        arrowLine: true
                    }]
                    
                  },
                  fail(e) {
                      console.log(e)
                  },
                  complete() {
                      console.log('complate')
                  }
                }
              },
              getPolyline(_type){
                var amap = new amapFile.AMapWX({ key: this.key });
                var self = this;
                switch (_type){
                  case 'car':
                    amap.getDrivingRoute(this.drawPolyline(this,"#0091ff"));
                    break;
                  case 'walk':
                    if(this.maxDuration) {
                        return false;
                    }
                    amap.getWalkingRoute(this.drawPolyline(this, "#1afa29"));
                    break;
                  case 'ride':
                    if(this.maxDuration) {
                        return false;
                    }
                    amap.getRidingRoute(this.drawPolyline(this, "#1296db"));
                    break;
                  default:
                    return false;
                }
              },
              goTo(_type){
                this.getPolyline(_type);
                this.active = _type;
              }
        },
        filters: {
            filterDistance(val) {
                return (val/1000).toFixed(2)
            },
            formatTime(val) {
                return (val/60).toFixed(2)
            }
        }
    }
</script>
<style>
    .map-wrapper {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 150upx;
        width: 100%;
    }
    .map-wrapper map {
        width: 100%;
        height: 100%;
    }
    .info-wrapper{
        background: #fff;
        height: 150upx;
        display: flex;
        flex-direction: column;
    }
    .selectType {
        position: relative;
        display: flex;
    }
    .selectType view {
        flex: 1;
        height: 60upx;
        line-height: 60upx;
        text-align: center;
    }
    .type {
        border-bottom: 1px solid #ccc;
    }
    .type:last-child {
        border-right: none;
    }
    .type.active {
        color: #10D5AF;
        border-color: #10D5AF;
    }
    .navigatePic {
        position: absolute;
        right: 10upx;
        background: #10D4AF;
        width: 100upx;
        height: 100upx;
        border-radius: 50%;
        bottom:40upx;
        text-align:center;
        line-height:100upx;
        color:#fff;
        font-weight:bold;
    }
    .info {
        display: flex;
        flex-direction: row;
        line-height: 80upx;
        font-size:32upx;
        font-weight:bold;
        padding:20upx;
    }
    .info text {
        margin-right: 40upx;
    }
</style>