微信小程序之高德地图多点路线规划过程示例详解


Posted in Javascript onJanuary 18, 2021

调用

如何调用高德api?

高德官方给出的https://lbs.amap.com/api/wx/summary/开放文档比较详细:

第一步,注册高德开发者

第二部,去控制台创建应用

微信小程序之高德地图多点路线规划过程示例详解

即点击右上角的控制平台创建应用

微信小程序之高德地图多点路线规划过程示例详解

创建应用绑定服务记得选择微信小程序;同时在https://lbs.amap.com/api/wx/gettingstarted中下载开发包

第三步,登陆微信公众平台在开发设置中将高德域名配置上

https://restapi.amap.com

第四步,打开微信开发者工具,打开微信小程序,在项目中新建一个libs文件夹

将在高德官网上下载得到的开发包解压,将其中的 amap-wx.js 文件放在libs文件夹下

微信小程序之高德地图多点路线规划过程示例详解

同时创建config.js

var config = {
 key:'请在此填入你申请的key'
}
module.exports.Config = config;

在其他界面js部分中即可调用高德api

var amapFile = require('../../libs/amap-wx.js');
var config = require('../../libs/config.js');

两点之间的导航

这是实现多点路线规划的基础,非常重要!!!

实现效果

微信小程序之高德地图多点路线规划过程示例详解

微信小程序之高德地图多点路线规划过程示例详解

以驾车为例,注:界面使用的是colorui

wxml部分:

<scroll-view scroll-x class="bg-white nav text-center">
 <view class="cu-item {{index==TabCur?'text-blue cur':''}}" wx:for="{{4}}" wx:key bindtap="tabSelect" data-id="{{index}}">
 {{method[index]}}
 </view>
</scroll-view>
<view class="map">
 <view bindtap='getFormAddress'>
 <view class="cu-form-group">
 <view class="title">出发地</view>
 <input placeholder="出发地" type="text" name="" bindinput="" value='{{markers[0].name}}' />
 </view>
 </view>
 <view bindtap='getToAddress'>
 <view class="cu-form-group">
 <view class="title">目的地</view>
 <input placeholder="目的地" type="text" name="" bindinput="" value='{{markers[1].name}}' />
 </view>
 </view>
​
 <view class="flex" wx:if="{{TabCur==0||TabCur==1}}">
 <button class="cu-btn bg-blue lg" bindtap = 'getSure'>确定</button>
 </view>
​
</view>
<view>
 <view class="map_box" wx:if="{{TabCur==0}}">
 <map id="navi_map" longitude="{{markers[0].longitude}}" latitude="{{markers[0].latitude}}" scale="12" markers="{{markers}}" polyline="{{polyline}}"></map>
 </view>
 <view class="text_box" wx:if='{{TabCur==0}}'>
 <view class="text">{{distance}}</view>
 <view class="text">{{cost}}</view>
 <view class="detail_button" bindtouchstart="goDetail" wx:if="{{state==1}}">详情</view>
 </view>
</view>

js部分:

var amapFile = require('../../libs/amap-wx.js');
var config = require('../../libs/config.js');
const app = getApp()
Page({ 
 /**
 * 页面的初始数据
 */
 data: {
 markers: [{
 iconPath: "../../img/mapicon_navi_s.png",
 id: 0,
 latitude: 39.989643,
 longitude: 116.481028,
 width: 23,
 height: 33
 },{
 iconPath: "../../img/mapicon_navi_e.png",
 id: 0,
 latitude: 39.90816,
 longitude: 116.434446,
 width: 24,
 height: 34
 }],
 distance: '',
 cost: '',
 state: 0,
 method:['驾车','公交','骑行','步行'],
 index:0,
 TabCur:0,
 polyline: [],
 transits: []
 }, 
 /**
 * 生命周期函数--监听页面加载
 */
 onLoad: function(options) {
 var that = this;
 wx.showLoading({
 title: "定位中",
 mask: true
 })
 wx.getLocation({
 type: 'gcj02',
 altitude: true, //高精度定位
 success: function(res) {
 console.info(res);
 var latitude = res.latitude
 var longitude = res.longitude
 var speed = res.speed
 var accuracy = res.accuracy
 that.setData({
 markers: [{
 name: '当前位置',
 latitude: latitude,
 longitude: longitude
 }, {
 name: '您要去哪儿?',
 latitude: '',
 longitude: ''
 }]
 })
 },
 fail: function() {
 wx.showToast({
 title: "定位失败",
 icon: "none"
 })
 }, 
 complete: function() {
 wx.hideLoading()
 }
 })
 },
 //选择器改变函数
 tabSelect(e) {
 this.setData({
 TabCur: e.currentTarget.dataset.id,
 scrollLeft: (e.currentTarget.dataset.id - 1) * 60
 })
},
//获取出发地
 getFormAddress: function() {
 var that = this;
 wx.chooseLocation({
 success: function(res) {
 var name = res.name
 var address = res.address
 var latitude = res.latitude
 var longitude = res.longitude
 var markesName = "markers[" + 0 + "].name";
 var markesLatitude = "markers[" + 0 + "].latitude";
 var markeslongitude = "markers[" + 0 + "].longitude";
 var markesiconPath = "markers[" + 0 + "].iconPath";
 that.setData({
 [markesName]: name,
 [markesLatitude]: latitude,
 [markeslongitude]: longitude,
 [markesiconPath]: "../../img/mapicon_navi_s.png"
 })
 },
 fail: function() {
 wx.showToast({
 title: '定位失败',
 icon: "none"
 })
 },
 complete: function() {
 //隐藏定位中信息进度
 wx.hideLoading()
 }
 })
 }, 
//获取目的地
 getToAddress: function() {
 var that = this;
 wx.chooseLocation({
 success: function(res) {
 console.log(res);
 var name = res.name
 var address = res.address
 var latitude = res.latitude
 var longitude = res.longitude
 var markesName = "markers[" + 1 + "].name";
 var markesLatitude = "markers[" + 1 + "].latitude";
 var markeslongitude = "markers[" + 1 + "].longitude";
 var markesiconPath = "markers[" + 1 + "].iconPath";
 that.setData({
 [markesName]: name,
 [markesLatitude]: latitude,
 [markeslongitude]: longitude,
 [markesiconPath]: "../../img/mapicon_navi_e.png"
 })
 },
 fail: function() {
 wx.showToast({
 title: '定位失败',
 icon: "none"
 })
 },
 complete: function() {
 //隐藏定位中信息进度
 wx.hideLoading()
 }
 })
 },
 /**
 * 确定
 */
 getSure: function() {
 var that = this;
 var origin = that.data.markers[0].longitude + ',' + that.data.markers[0].latitude;//出发地
var destination = that.data.markers[1].longitude + ',' + that.data.markers[1].latitude; //目的地
var TabCur=this.data.TabCur;
app.origin = origin;
app.destination = destination;
var key = config.Config.key;
var myAmapFun = new amapFile.AMapWX({
 key: key
 });
 if(TabCur==0){
  myAmapFun.getDrivingRoute({//获取驾车路线
  origin: origin,
  destination: destination,
  success: function(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])
  })
  }
  }
  }
  that.setData({//将路线在地图上画出来
  state: 1,
  polyline: [{
  points: points,
  color: "#0091ff",
  width: 6
  }]
  });
  if (data.paths[0] && data.paths[0].distance) {
  that.setData({
  distance: data.paths[0].distance + '米'
  });
  }
  if (data.taxi_cost) {
  that.setData({
  cost: '打车约' + parseInt(data.taxi_cost) + '元'
  });
  }
  }
 })
 }
 },
/**
 * 详情页
 */
goDetail: function() {
  var TabCur=this.data.TabCur;
  if(TabCur==0){
  wx.navigateTo({
  url: '../detail/detail'
  })
 }
 },
})

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_title{
 position:absolute;
 top: 10px;
 bottom: 110px;
 left: 0px;
 right: 0px;
 }
 .map_btn{
 position:absolute;
 top: 150px;
 bottom: 220px;
 left: 0px;
 right: 0px;
 }
 .map_box{
 position:absolute;
 top: 187px;
 bottom: 70px;
 left: 0px;
 right: 0px;
 }
 #navi_map{
 width: 100%;
 height: 100%;
 }
 .text_box{
 
 position:absolute;
 height: 70px;
 bottom: 0px;
 left: 0px;
 right: 0px;
 }
 .text_box .text{
 margin: 15px;
 }

详情页部分:

html部分:

<view class="text_box" wx:for="{{steps}}" wx:for-item="i" wx:key="j">
 {{i.instruction}}
</view>

js部分:

var amapFile = require('../../libs/amap-wx.js');
var config = require('../../libs/config.js');
const app = getApp()
Page({
 data: {
 steps: {}
 },
 onLoad: function () {
 var that = this;
 var key = config.Config.key;
 var myAmapFun = new amapFile.AMapWX({ key: key });
 myAmapFun.getDrivingRoute({
 origin: app.origin,
 destination: app.destination,
 success: function (data) {
 if (data.paths && data.paths[0] && data.paths[0].steps) {
 that.setData({
 steps: data.paths[0].steps
 });
 }
 },
 fail: function (info) {
 }
 })
 }
})

wxss部分:

Page{

}
.text_box{
 margin: 0 15px;
 padding: 15px 0;
 border-bottom: 1px solid #c3c3c3;
 font-size: 13px;
}
.text_box .text_item{display:inline-block;line-height: 8px;}

其他公交、骑行、步行方法与驾车类似,可以查看高德开放文档学习

我的设计上公交可以查看不同城市的公交路线,而非只能查看一个城市的,实现很简单,在界面上添加了一个选择器城市参数传至city,即可查看不同城市的公交路线

微信小程序之高德地图多点路线规划过程示例详解

多点路线规划

实现效果:可以选择出发地,选择不同的景点,根据不同的出行方式给出一条距离最短的路径

微信小程序之高德地图多点路线规划过程示例详解微信小程序之高德地图多点路线规划过程示例详解

实现思路:

  • 获取到周边的景点位置等相关信息
  • 将用户添加的景点信息传到下一个页面进行计算
  • 获得所有可能的路线并计算每一条路线的长度找出距离最短的一条

踩坑

  • 一开始打算利用深度优先搜索算法实现,但是发现在现实的地图中,任意两点之间几乎都存在路,并不像抽象后的数学题一样。于是最后使用了全排列的方法获取到了所有的路线
  • 在全排列的过程中需要递归调用函数,涉及到传参问题,需要将自定义的带参函数写在Page外,写在Page里的话,我尝试了很多方式调用函数都会报错。
  • 在使用高德api获取路径的函数后,无法计算每一段路线的长度,最后发现是在函数调用的过程中,存储路线距离的数组只是暂存的,在函数调用后无法使用该数组来计算距离。于是最后我在函数调用的过程中计算每一条路线的长度并进行比较,最后用this.setData的方法将最后得到的路线展示在界面上。

具体实现

  • 获取出发地、出行方式并赋值给全局变量传递掉下一个界面,如app.origin = origin
  • 利用getPoiAround函数获取到周边的景点信息,querykeywords可以固定设置为景区,将返回的前二十条景区信息展示在界面上。
  • 将用户选择的景点信息存入数组并传递到下一个界面进行计算。
  • 利用全排列获取到所有可能的路线并去重。
  • 计算每一条路线的长度并找到最小的一条将其展示在界面上。

注:获取到每一条路线距离的方法和获取到两个地点之间不同出行方式路线的方法在前面两点之间的导航部分,多点之间的路线导航其实就是将多个两点之间的路线导航连在了一起。先将前面的两点之间的不同出行方式导航实现后,改动细微的部分,再加入全排列的算法和大小比较的算法即可实现,在此就不贴出源码。

希望我的思路能给予你启发~

可优化部分

  • querykeywords可以设置为让用户选择不同的标签,如:户外、娱乐、美食、宾馆等等。
  • 可让用户选择不同标签的地点将其存入数组计算一条出行的最短路径。
  • 可以在最终的展示界面显示地图让用户更直观地查看各个地点之间的方位及距离信息。
  • 最优导航形式:实时导航。

注:以上四条是我暂时想到的可优化的部分,算是给自己挖了一个坑,等我填完来这里写个实现方式。

到此这篇关于微信小程序之高德地图多点路线规划过程示例详解的文章就介绍到这了,更多相关高德地图多点路线规划内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript中的new的使用方法与注意事项
May 16 Javascript
二行代码解决全部网页木马
Mar 28 Javascript
JavaScript 事件对象的实现
Jul 13 Javascript
使用JavaScript switch case 另类写法
Mar 14 Javascript
IE6/7 and IE8/9/10(IE7模式)依次隐藏具有absolute或relative的父元素和子元素后再显示父元素
Jul 31 Javascript
实测jquery data()如何存值
Aug 18 Javascript
JavaScript两种跨域技术全面介绍
Apr 16 Javascript
JavaScript保存并运算页面中数字类型变量的写法
Jul 06 Javascript
浅谈ECMAScript6新特性之let、const
Aug 02 Javascript
说说如何利用 Node.js 代理解决跨域问题
Apr 22 Javascript
深入理解redux之compose的具体应用
Jan 12 Javascript
vue和小程序项目中使用iconfont的方法
May 19 Javascript
从源码角度来回答keep-alive组件的缓存原理
Jan 18 #Javascript
在JavaScript中查找字符串中最长单词的三种方法(推荐)
Jan 18 #Javascript
vue-resource 拦截器interceptors使用详解
Jan 18 #Vue.js
js数组的基本使用总结
Jan 18 #Javascript
JavaScript/TypeScript 实现并发请求控制的示例代码
Jan 18 #Javascript
js加减乘除精确运算方法实例代码
Jan 17 #Javascript
Angular处理未可知异常错误的方法详解
Jan 17 #Javascript
You might like
php定时计划任务的实现方法详解
2013/06/06 PHP
探讨php中防止SQL注入最好的方法是什么
2013/06/10 PHP
php创建sprite
2014/02/11 PHP
php判断电脑访问、手机访问的例子
2014/05/10 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
JavaScript中的DSL元编程介绍
2015/03/15 Javascript
jQuery插件expander实现图片翻转特效
2015/05/21 Javascript
JavaScript开发者必备的10个Sublime Text插件
2016/02/27 Javascript
iframe高度自适应及隐藏滚动条的实例详解
2017/09/29 Javascript
在weex中愉快的使用scss的方法步骤
2020/01/02 Javascript
微信小程序实现聊天室
2020/08/21 Javascript
JavaScript 常见的继承方式汇总
2020/09/17 Javascript
基于Vant UI框架实现时间段选择器
2020/12/24 Javascript
[01:00:30]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第二场 10.31
2020/11/02 DOTA
python使用any判断一个对象是否为空的方法
2014/11/19 Python
使用Python的Zato发送AMQP消息的教程
2015/04/16 Python
Python检测网站链接是否已存在
2016/04/07 Python
Python+tkinter使用40行代码实现计算器功能
2018/01/30 Python
python实战之实现excel读取、统计、写入的示例讲解
2018/05/02 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
2020/04/30 Python
python利用os模块编写文件复制功能——copy()函数用法
2020/07/13 Python
python用Configobj模块读取配置文件
2020/09/26 Python
python爬虫爬取某网站视频的示例代码
2021/02/20 Python
一道SQL存储过程面试题
2016/10/07 面试题
php优化查询foreach代码实例讲解
2021/03/24 PHP
物流专业大学生的自我鉴定
2013/11/13 职场文书
四风问题班子对照检查材料
2014/09/27 职场文书
县政府班子个人对照检查材料
2014/10/05 职场文书
售后服务承诺函格式
2015/01/21 职场文书
秋收起义观后感
2015/06/11 职场文书
暑期辅导班宣传单
2015/07/14 职场文书
导游词之泰山玉皇顶
2019/12/23 职场文书
基于Python实现股票收益率分析
2022/04/02 Python
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL