微信小程序之高德地圖多點(diǎn)路線規(guī)劃過(guò)程示例詳解
調(diào)用
如何調(diào)用高德api?
高德官方給出的https://lbs.amap.com/api/wx/summary/開(kāi)放文檔比較詳細(xì):
第一步,注冊(cè)高德開(kāi)發(fā)者
第二部,去控制臺(tái)創(chuàng)建應(yīng)用
即點(diǎn)擊右上角的控制平臺(tái)創(chuàng)建應(yīng)用
創(chuàng)建應(yīng)用綁定服務(wù)記得選擇微信小程序;同時(shí)在https://lbs.amap.com/api/wx/gettingstarted中下載開(kāi)發(fā)包
第三步,登陸微信公眾平臺(tái)在開(kāi)發(fā)設(shè)置中將高德域名配置上
第四步,打開(kāi)微信開(kāi)發(fā)者工具,打開(kāi)微信小程序,在項(xiàng)目中新建一個(gè)libs文件夾
將在高德官網(wǎng)上下載得到的開(kāi)發(fā)包解壓,將其中的 amap-wx.js 文件放在libs文件夾下
同時(shí)創(chuàng)建config.js
var config = { key:'請(qǐng)?jiān)诖颂钊肽闵暾?qǐng)的key' } module.exports.Config = config;
在其他界面js部分中即可調(diào)用高德api
var amapFile = require('../../libs/amap-wx.js'); var config = require('../../libs/config.js');
兩點(diǎn)之間的導(dǎo)航
這是實(shí)現(xiàn)多點(diǎn)路線規(guī)劃的基礎(chǔ),非常重要?。。?/p>
實(shí)現(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({ /** * 頁(yè)面的初始數(shù)據(jù) */ 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)聽(tīng)頁(yè)面加載 */ 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: '當(dāng)前位置', 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() { //隱藏定位中信息進(jìn)度 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() { //隱藏定位中信息進(jìn)度 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({//將路線在地圖上畫出來(lái) 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) + '元' }); } } }) } }, /** * 詳情頁(yè) */ 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; }
詳情頁(yè)部分:
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;}
其他公交、騎行、步行方法與駕車類似,可以查看高德開(kāi)放文檔學(xué)習(xí)
我的設(shè)計(jì)上公交可以查看不同城市的公交路線,而非只能查看一個(gè)城市的,實(shí)現(xiàn)很簡(jiǎn)單,在界面上添加了一個(gè)選擇器城市參數(shù)傳至city,即可查看不同城市的公交路線
多點(diǎn)路線規(guī)劃
實(shí)現(xiàn)效果:可以選擇出發(fā)地,選擇不同的景點(diǎn),根據(jù)不同的出行方式給出一條距離最短的路徑
實(shí)現(xiàn)思路:
- 獲取到周邊的景點(diǎn)位置等相關(guān)信息
- 將用戶添加的景點(diǎn)信息傳到下一個(gè)頁(yè)面進(jìn)行計(jì)算
- 獲得所有可能的路線并計(jì)算每一條路線的長(zhǎng)度找出距離最短的一條
踩坑
- 一開(kāi)始打算利用深度優(yōu)先搜索算法實(shí)現(xiàn),但是發(fā)現(xiàn)在現(xiàn)實(shí)的地圖中,任意兩點(diǎn)之間幾乎都存在路,并不像抽象后的數(shù)學(xué)題一樣。于是最后使用了全排列的方法獲取到了所有的路線。
- 在全排列的過(guò)程中需要遞歸調(diào)用函數(shù),涉及到傳參問(wèn)題,需要將自定義的帶參函數(shù)寫在Page外,寫在Page里的話,我嘗試了很多方式調(diào)用函數(shù)都會(huì)報(bào)錯(cuò)。
- 在使用高德api獲取路徑的函數(shù)后,無(wú)法計(jì)算每一段路線的長(zhǎng)度,最后發(fā)現(xiàn)是在函數(shù)調(diào)用的過(guò)程中,存儲(chǔ)路線距離的數(shù)組只是暫存的,在函數(shù)調(diào)用后無(wú)法使用該數(shù)組來(lái)計(jì)算距離。于是最后我在函數(shù)調(diào)用的過(guò)程中計(jì)算每一條路線的長(zhǎng)度并進(jìn)行比較,最后用this.setData的方法將最后得到的路線展示在界面上。
具體實(shí)現(xiàn)
- 獲取出發(fā)地、出行方式并賦值給全局變量傳遞掉下一個(gè)界面,如
app.origin = origin
。 - 利用
getPoiAround
函數(shù)獲取到周邊的景點(diǎn)信息,querykeywords
可以固定設(shè)置為景區(qū),將返回的前二十條景區(qū)信息展示在界面上。 - 將用戶選擇的景點(diǎn)信息存入數(shù)組并傳遞到下一個(gè)界面進(jìn)行計(jì)算。
- 利用全排列獲取到所有可能的路線并去重。
- 計(jì)算每一條路線的長(zhǎng)度并找到最小的一條將其展示在界面上。
注:獲取到每一條路線距離的方法和獲取到兩個(gè)地點(diǎn)之間不同出行方式路線的方法在前面兩點(diǎn)之間的導(dǎo)航部分,多點(diǎn)之間的路線導(dǎo)航其實(shí)就是將多個(gè)兩點(diǎn)之間的路線導(dǎo)航連在了一起。先將前面的兩點(diǎn)之間的不同出行方式導(dǎo)航實(shí)現(xiàn)后,改動(dòng)細(xì)微的部分,再加入全排列的算法和大小比較的算法即可實(shí)現(xiàn),在此就不貼出源碼。
希望我的思路能給予你啟發(fā)~
可優(yōu)化部分
querykeywords
可以設(shè)置為讓用戶選擇不同的標(biāo)簽,如:戶外、娛樂(lè)、美食、賓館等等。- 可讓用戶選擇不同標(biāo)簽的地點(diǎn)將其存入數(shù)組計(jì)算一條出行的最短路徑。
- 可以在最終的展示界面顯示地圖讓用戶更直觀地查看各個(gè)地點(diǎn)之間的方位及距離信息。
- 最優(yōu)導(dǎo)航形式:實(shí)時(shí)導(dǎo)航。
注:以上四條是我暫時(shí)想到的可優(yōu)化的部分,算是給自己挖了一個(gè)坑,等我填完來(lái)這里寫個(gè)實(shí)現(xiàn)方式。
到此這篇關(guān)于微信小程序之高德地圖多點(diǎn)路線規(guī)劃過(guò)程示例詳解的文章就介紹到這了,更多相關(guān)高德地圖多點(diǎn)路線規(guī)劃內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript 組件之旅(一)分析和設(shè)計(jì)
毫無(wú)疑問(wèn),JavaScript 是一種非常靈活的腳本語(yǔ)言,有時(shí)候它像一只難以馴服的野馬——你受益于它的靈活性的同時(shí),也要時(shí)刻提防它變得失去控制2009-10-10js自動(dòng)生成的元素與頁(yè)面原有元素發(fā)生堆疊的解決方法
商品屬性和商品規(guī)格是js動(dòng)態(tài)生成的元素,商品擴(kuò)展信息的兩個(gè)文本框是原有的元素,他們發(fā)生堆疊,下面是一些解決思路2014-09-09JavaScript的垃圾回收機(jī)制與內(nèi)存管理
這篇文章主要介紹了JavaScript的垃圾回收機(jī)制與內(nèi)存管理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08JavaScript對(duì)象與JSON格式的轉(zhuǎn)換及JSON.stringify和JSON.parse的使用方法
這篇文章主要介紹了JavaScript對(duì)象與JSON格式的轉(zhuǎn)換及JSON.stringify和JSON.parse的使用方法,JSON是JavaScript表達(dá)值和對(duì)象的通用數(shù)據(jù)格式,其本質(zhì)就是符合一定規(guī)范的字符串2022-07-07javascript 極速 隱藏/顯示萬(wàn)行表格列只需 60毫秒
隱藏表格列 這種方式的效率極低。例如,隱藏一個(gè)千行表格的某列,在我的筆記本(P4 M 1.4G,768M內(nèi)存)上執(zhí)行需要約 4000毫秒的時(shí)間,令人無(wú)法忍受。2009-03-03js實(shí)現(xiàn)讓某個(gè)動(dòng)作延遲幾秒執(zhí)行
這篇文章主要介紹了使用js實(shí)現(xiàn)讓某個(gè)動(dòng)作延遲幾秒執(zhí)行的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06js將列表組裝成樹(shù)結(jié)構(gòu)的兩種實(shí)現(xiàn)方式分享
最近做的任務(wù)提了新的需求,需要實(shí)現(xiàn)一個(gè)樹(shù)形結(jié)構(gòu),所以下面這篇文章主要給大家介紹了關(guān)于js將列表組裝成樹(shù)結(jié)構(gòu)的兩種實(shí)現(xiàn)方式,需要的朋友可以參考下2022-01-01百度地圖JavascriptApi Marker平滑移動(dòng)及車頭指向行徑方向
本文主要介紹了百度地圖JavascriptApi Marker平滑移動(dòng)及車頭指向行徑方向的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03JavaScript 阻止超鏈接跳轉(zhuǎn)的操作方法(多種寫法)
很多朋友問(wèn)小編能否通過(guò)JavaScript來(lái)阻止超鏈接的跳轉(zhuǎn)呢,今天給大家通過(guò)多種寫法來(lái)實(shí)現(xiàn)這一功能,具體實(shí)例代碼跟隨小編一起看看吧2021-06-06