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

调用

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

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

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

(0)

相关推荐

  • 微信小程序使用map组件实现路线规划功能示例

    本文实例讲述了微信小程序使用map组件实现路线规划功能.分享给大家供大家参考,具体如下: 效果图 实现原理 1. 通过map组件标记起始点和绘制路线图: 2. 通过高德地图API获取不同类型的路线坐标点,以及耗费时间和路程. WXML <view class="flex-style"> <view class="flex-item {{status == 'car' ? 'active' : ''}}" data-status="car&

  • 微信小程序map组件结合高德地图API实现wx.chooseLocation功能示例

    本文实例讲述了微信小程序map组件结合高德地图API实现wx.chooseLocation功能.分享给大家供大家参考,具体如下: 声明 bug: 页面搜索返回的列表在真机测试是会出现不显示问题? 造成原因:在小程序map组件的同一区域,map组件的视图层比普通的文本视图层要高,所以在真机会遮挡! 解决办法:将该文本视图采用cover-view,放在map中. 感谢: 感谢Lrj_estranged指出问题! 效果图 实现原理 通过高德地图的微信小程序开发API(getInputtips),实现关

  • 微信小程序 高德地图SDK详解及简单实例(源码下载)

    微信小程序 高德地图SDK: 简介 微信小程序 SDK 帮您在微信小程序中获取高德丰富的地址描述.POI和实时天气数据. 功能介绍 账号与Key的申请 注册成为高德开发者需要分三步: 第一步,注册高德开发者:第二步,去控制台创建应用:第三步,获取Key. 1注册高德开发者 2创建应用 3获取API key 获取API Key 入门指南 最后更新时间: 2017年1月9日 本指南是使用微信小程序SDK的快速入门指南. 第 1 步:下载并安装微信小程序开发工具 按照微信小程序开发文档下载并安装微信小

  • 微信小程序 高德地图路线规划实现过程详解

    前言 最近项目中做到相关网约车小程序.需要使用到地图中的路线规划,对3种地图进行了分析.这里稍微做一下总结: 百度地图 百度坐标 (BD-09) 腾讯地图 火星坐标(GCJ-02) 高德地图 火星坐标(GCJ-02) 微信小程序中使用的是腾讯地图作为底图.因此如果使用百度地图时,需要注意坐标的转换.此类坐标的转换函数在网上都有,这里不做过多解释 准备工作: 1.在做小程序 ---- 路线规划之前,需要准备小程序APPID 以及相应使用地图的KEY值. 2.微信小程序API 之 位置 API wx

  • 微信小程序基于高德地图查找位置并显示文字

    这篇文章主要介绍了微信小程序基于高德地图查找位置并显示文字,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.根据经纬度在 地图上查找定位 var key = app.globalData.amapKey; var myAmapFun = new amapFile.AMapWX({ key: key }); myAmapFun.getRegeo({ iconPath: "../../assets/marker_checked.png"

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

    调用 如何调用高德api? 高德官方给出的https://lbs.amap.com/api/wx/summary/开放文档比较详细: 第一步,注册高德开发者 第二部,去控制台创建应用 即点击右上角的控制平台创建应用 创建应用绑定服务记得选择微信小程序:同时在https://lbs.amap.com/api/wx/gettingstarted中下载开发包 第三步,登陆微信公众平台在开发设置中将高德域名配置上 https://restapi.amap.com 第四步,打开微信开发者工具,打开微信小程

  • 微信小程序基于高德地图API实现天气组件(动态效果)

    ​在社区翻腾了许久,没有找到合适的天气插件.迫不得已,只好借鉴互联网上的web项目,手动迁移到小程序中使用.现在分享到互联网社区中,帮助后续有需要的开发者. 1.组件介绍 1.1 组件效果预览图 ​小程序组件继承了外部样式colorui的色彩,但实际动画会根据父节点的color属性自动填充颜色,即使不引入colorui这个样式库,也可以在该组件引用外定义一个有color属性的块包裹该组件,同样可以达到如图的效果. 1.2 构造形式 1.3 支持的动画效果 简单介绍下,动画由3个部分组成 一个是主

  • 微信小程序中button组件的边框设置的实例详解

    微信小程序中button组件的边框设置的实例详解 button的边框是用:after方式实现的,用户如果在button上定义边框会出现两条线,需用:after的方式去覆盖默认值. 如果设置了Button的背景色,没有用:after设置边框的颜色,则button的四个角会出现模糊的尖角.如下图所示: 如上图四个角会模糊..wxss代码如下: .clickEncryptBtn{ width:130px; border-radius: 3px; margin:20px auto; padding-to

  • 微信小程序引用公共js里的方法的实例详解

    微信小程序引用公共js里的方法的实例详解 一个小程序页面由四个文件组成,一个小程序页面的四个文件具有相同路径与文件名,由此我们可知一个小程序页面对应着一个跟页面同名的js文件.可是当有些公共方法,我们想抽离出来成为一个独立公共的js文件.我们该如何实现呢. 在根目录下有一个app.js文件.这个根目录的js 文件我们可以通过getApp()轻松调用. //app.js App({ globaData:'huangenai' }) //test.js var app = getApp(); Pag

  • 微信小程序:数据存储、传值、取值详解

    小程序界面传值 父级界面:A界面 子级界面:B界面 一.url传值 详细的配置参数可以查看组件导航:navigator,这里不再做过多的解释. 1. 正向传值:A界面 –>B界面 用 navigator标签或 wx.navigator传值,A界面向B界面传id值 A界面获取id值传向B界面如果需要传多个参数, 用 & 链接即可 // 方法一:navigator标签传值 <navigator url="/page/index/index?id=110" >传值&

  • 微信小程序学习笔记之获取位置信息操作图文详解

    本文实例讲述了微信小程序学习笔记之获取位置信息操作.分享给大家供大家参考,具体如下: 前面介绍了微信小程序文件上传.下载操作.这里分析一下获取位置信息操作. [获取当前位置信息]wx.getLocation() getlocation.wxml: <view> <button bindtap="getlocation">获取位置</button> </view> getlocation.js: Page({ getlocation: fu

  • 微信小程序 动态的设置图片的高度和宽度详解及实例代码

    微信小程序图片等比例缩放 动态的获取图片的高度和宽度 动态的设置图片的高度和宽度 前言: 在小程序布局中,如果图片不是固定高度和高度,但image设置的是固定的高度和宽度,这时候原始图片相对image设置的固定高度和宽度不是等比例大小,那么这张图片就会变形,变的不清晰.这时就可以使用下面的等比例缩放的方式缩放图片,让图片不变形.或者通过image的bindload方法动态的获取图片的高度和宽度,动态的设置图片的高度和宽度,是图片布局的高度和宽度和原始图片的高度和宽度相等. 1.图片等比例缩放工具

  • 微信小程序授权获取用户详细信息openid的实例详解

    小程序获取用户的头像昵称openid之类 第一种使用wx.getUserInfo直接获取微信头像,昵称 wx.getUserInfo({ success: function (res) { that.setData({ nickName: res.userInfo.nickName, avatarUrl: res.userInfo.avatarUrl, }) }, }) 第二种 我们在使用小程序wx.login API进行登录的时候,直接使用wx.getUserInfo是不能获取更多的信息的,如

随机推荐