微信小程序之高德地圖多點路線規(guī)劃過程示例詳解
調用
如何調用高德api?
高德官方給出的https://lbs.amap.com/api/wx/summary/開放文檔比較詳細:
第一步,注冊高德開發(fā)者
第二部,去控制臺創(chuàng)建應用

即點擊右上角的控制平臺創(chuàng)建應用

創(chuàng)建應用綁定服務記得選擇微信小程序;同時在https://lbs.amap.com/api/wx/gettingstarted中下載開發(fā)包
第三步,登陸微信公眾平臺在開發(fā)設置中將高德域名配置上
第四步,打開微信開發(fā)者工具,打開微信小程序,在項目中新建一個libs文件夾
將在高德官網上下載得到的開發(fā)包解壓,將其中的 amap-wx.js 文件放在libs文件夾下

同時創(chuàng)建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');
兩點之間的導航
這是實現(xiàn)多點路線規(guī)劃的基礎,非常重要!?。?/p>
實現(xiàn)效果


以駕車為例,注:界面使用的是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">出發(fā)地</view>
<input placeholder="出發(fā)地" 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({
/**
* 頁面的初始數(shù)據
*/
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: []
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面加載
*/
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()
}
})
},
//選擇器改變函數(shù)
tabSelect(e) {
this.setData({
TabCur: e.currentTarget.dataset.id,
scrollLeft: (e.currentTarget.dataset.id - 1) * 60
})
},
//獲取出發(fā)地
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;//出發(fā)地
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;}
其他公交、騎行、步行方法與駕車類似,可以查看高德開放文檔學習
我的設計上公交可以查看不同城市的公交路線,而非只能查看一個城市的,實現(xiàn)很簡單,在界面上添加了一個選擇器城市參數(shù)傳至city,即可查看不同城市的公交路線

多點路線規(guī)劃
實現(xiàn)效果:可以選擇出發(fā)地,選擇不同的景點,根據不同的出行方式給出一條距離最短的路徑


實現(xiàn)思路:
- 獲取到周邊的景點位置等相關信息
- 將用戶添加的景點信息傳到下一個頁面進行計算
- 獲得所有可能的路線并計算每一條路線的長度找出距離最短的一條
踩坑
- 一開始打算利用深度優(yōu)先搜索算法實現(xiàn),但是發(fā)現(xiàn)在現(xiàn)實的地圖中,任意兩點之間幾乎都存在路,并不像抽象后的數(shù)學題一樣。于是最后使用了全排列的方法獲取到了所有的路線。
- 在全排列的過程中需要遞歸調用函數(shù),涉及到傳參問題,需要將自定義的帶參函數(shù)寫在Page外,寫在Page里的話,我嘗試了很多方式調用函數(shù)都會報錯。
- 在使用高德api獲取路徑的函數(shù)后,無法計算每一段路線的長度,最后發(fā)現(xiàn)是在函數(shù)調用的過程中,存儲路線距離的數(shù)組只是暫存的,在函數(shù)調用后無法使用該數(shù)組來計算距離。于是最后我在函數(shù)調用的過程中計算每一條路線的長度并進行比較,最后用this.setData的方法將最后得到的路線展示在界面上。
具體實現(xiàn)
- 獲取出發(fā)地、出行方式并賦值給全局變量傳遞掉下一個界面,如
app.origin = origin。 - 利用
getPoiAround函數(shù)獲取到周邊的景點信息,querykeywords可以固定設置為景區(qū),將返回的前二十條景區(qū)信息展示在界面上。 - 將用戶選擇的景點信息存入數(shù)組并傳遞到下一個界面進行計算。
- 利用全排列獲取到所有可能的路線并去重。
- 計算每一條路線的長度并找到最小的一條將其展示在界面上。
注:獲取到每一條路線距離的方法和獲取到兩個地點之間不同出行方式路線的方法在前面兩點之間的導航部分,多點之間的路線導航其實就是將多個兩點之間的路線導航連在了一起。先將前面的兩點之間的不同出行方式導航實現(xiàn)后,改動細微的部分,再加入全排列的算法和大小比較的算法即可實現(xiàn),在此就不貼出源碼。
希望我的思路能給予你啟發(fā)~
可優(yōu)化部分
querykeywords可以設置為讓用戶選擇不同的標簽,如:戶外、娛樂、美食、賓館等等。- 可讓用戶選擇不同標簽的地點將其存入數(shù)組計算一條出行的最短路徑。
- 可以在最終的展示界面顯示地圖讓用戶更直觀地查看各個地點之間的方位及距離信息。
- 最優(yōu)導航形式:實時導航。
注:以上四條是我暫時想到的可優(yōu)化的部分,算是給自己挖了一個坑,等我填完來這里寫個實現(xiàn)方式。
到此這篇關于微信小程序之高德地圖多點路線規(guī)劃過程示例詳解的文章就介紹到這了,更多相關高德地圖多點路線規(guī)劃內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript對象與JSON格式的轉換及JSON.stringify和JSON.parse的使用方法
這篇文章主要介紹了JavaScript對象與JSON格式的轉換及JSON.stringify和JSON.parse的使用方法,JSON是JavaScript表達值和對象的通用數(shù)據格式,其本質就是符合一定規(guī)范的字符串2022-07-07
javascript 極速 隱藏/顯示萬行表格列只需 60毫秒
隱藏表格列 這種方式的效率極低。例如,隱藏一個千行表格的某列,在我的筆記本(P4 M 1.4G,768M內存)上執(zhí)行需要約 4000毫秒的時間,令人無法忍受。2009-03-03
百度地圖JavascriptApi Marker平滑移動及車頭指向行徑方向
本文主要介紹了百度地圖JavascriptApi Marker平滑移動及車頭指向行徑方向的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03

