知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們在追求其視覺表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
騰訊地圖手把手教你實(shí)現(xiàn)微信小程序路線規(guī)劃
發(fā)表時(shí)間:2021-3-15
發(fā)布人:葵宇科技
瀏覽次數(shù):105
前言
本文旨在以mpvue框架為基礎(chǔ),探討地圖類小程序的開發(fā)思路。 原作者利用mpvue + 騰訊地圖的能力做了一個(gè)地鐵路線規(guī)劃的小程序,主要提供全球主要城市的地鐵線網(wǎng)圖及旅游介紹,其中國內(nèi)城市支持查看地圖和路線規(guī)劃。
目前騰訊位置服務(wù)也推出了 路線規(guī)劃插件 、 地鐵圖插件 ,實(shí)現(xiàn)更加簡單便捷,感興趣的可點(diǎn)擊查看。
運(yùn)行截圖
mpvue 介紹 及項(xiàng)目搭建
mpvue = miniprogram + vue framework,說白了就是用vue框架開發(fā)小程序。mpvue最近升級為2.x版本,支持微信、支付寶、百度和頭條小程序。和傳統(tǒng)方式相比,mpvue開發(fā)具有以下優(yōu)點(diǎn):
徹底的組件化開發(fā)能力:提高代碼復(fù)用性
- 完整的 Vue.js 開發(fā)體驗(yàn)
- 方便的 Vuex 數(shù)據(jù)管理方案:方便構(gòu)建復(fù)雜應(yīng)用
- 快捷的 webpack 構(gòu)建機(jī)制:自定義構(gòu)建策略、開發(fā)階段 hotReload
- 支持使用 npm 外部依賴
- 使用 Vue.js 命令行工具 vue-cli 快速初始化項(xiàng)目
- H5 代碼轉(zhuǎn)換編譯成小程序目標(biāo)代碼的能力
就個(gè)人使用體驗(yàn)來看,還是挺絲滑順暢的,傳統(tǒng)web應(yīng)用開發(fā)無縫切換至小程序開發(fā),基本零門檻。要注意的就是小程序的限制及和vue的差異:
- 小程序使用相對像素 rpx 進(jìn)行樣式布局
- 部分css選擇符不支持,目前只支持 #id | .class | tag | tag,tag | ::after ::before,所以要特別注意
- 組合式生命周期,mpvue將小程序和vue的生命周期混在一塊,詳情見 mpvue.com/mpvue/#_3 ,目前這個(gè)地方還有很多坑,比如在小程序page unload時(shí),vue實(shí)例卻沒被銷毀,導(dǎo)致下次進(jìn)入頁面時(shí),頁面狀態(tài)不變,必須在unLoad時(shí)手動重置狀態(tài)等
- mpvue 會封裝小程序數(shù)據(jù)對象,通常以
$mp
開頭,如event.$mp.detail.target
等 - 小程序的組件和vue組件有差異,不要幻想vue組件的特性都能用,如slot,異步組件等等
- vue store 和 wx localstorage 最好不要弄混,要根據(jù)不同需要選擇不同的存儲方式
- 不要用vue路由,要采用小程序原生的導(dǎo)航機(jī)制
然后,我們搭建開發(fā)環(huán)境,mpvue腳手架是開箱即用的:
# 全局安裝 vue-cli
# 一般是要 sudo 權(quán)限的
$ npm install --global vue-cli@2.9
# 創(chuàng)建一個(gè)基于 mpvue-quickstart 模板的新項(xiàng)目
# 新手一路回車選擇默認(rèn)就可以了
$ vue init mpvue/mpvue-quickstart my-project
# 安裝依賴,走你
$ cd my-project
$ npm install
$ npm run dev
接著,完善文件結(jié)構(gòu),增加 config、store、mixins等模塊,如圖:
app.json是小程序?qū)S梦募?,也需完善下?/p>
{
"pages": [
"pages/citylist/main",
"pages/citydetail/main"
],
"permission": {
"scope.userLocation": {
"desc": "你的位置信息將用于小程序位置接口的效果展示"
}
},
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#eee",
"navigationBarTitleText": "全球地鐵,全程為你",
"navigationBarTextStyle": "black"
}
}
然后就可以愉快的寫Vue代碼了,咔咔一個(gè)頁面,咔咔又是一個(gè)頁面,組件,store,數(shù)據(jù)驅(qū)動,你喜歡的樣子,它都有。
騰訊地圖+ 小程序
著重說一下地圖的接入,騰訊地圖提供了兩個(gè)對接入口給小程序,1是個(gè)性化地圖展示,2是專用SDK,二者共同完善了小程序的地圖生態(tài)。
1、個(gè)性地圖展示需要開發(fā)者自行注冊并申請開發(fā)者密鑰(key),并在管理后臺綁定小程序,然后設(shè)置個(gè)性地圖的樣式,才能使用:
<map
id="citymap"
name="citymap"
:longitude="lng"
:latitude="lat"
:polyline="polyline"
:markers="markers"
scale="12"
:subkey="YOUR_OWN_QQMAP_KEY"
show-location
show-compass
enable-rotate
style="width: 100%; height: 100%;"
>
<cover-view class="map-cover-view">
<button class="explore-btn" type="primary" @tap="exploreCity">查看旅游攻略</button>
</cover-view>
</map>
其中,map是小程序的原生組件,原生組件脫離在 WebView 渲染流程外,它的層級是最高的,所以頁面中的其他組件無論設(shè)置 z-index 為多少,都無法蓋在原生組件上。說白了就是原生組件是微信客戶端提供的,它不屬于內(nèi)置瀏覽器,為此,小程序?qū)iT提供了 cover-view 和 cover-image 組件,可以覆蓋在部分原生組件上面。這兩個(gè)組件也是原生組件,但是使用限制與其他原生組件有所不同。
筆者就因?yàn)檫@個(gè)坑耽誤了不少時(shí)間,有時(shí)候開發(fā)工具可以用,但到了真機(jī)上組件就完全亂了,所以還是要以真機(jī)調(diào)試為準(zhǔn)。對于原生組件,不要用太復(fù)雜的css,它的很多css屬性支持的都不好。
map可以定義多個(gè)參數(shù),經(jīng)緯度不用說,scale指放縮比例,也就是地圖比例尺,polyline在地圖上繪制折線,markers用于標(biāo)記地圖上的點(diǎn),show-location用于顯示用戶所在位置,show-compass顯示指北針。
2、專用SDK,目前提供這些能力:
- search(options:Object) 地點(diǎn)搜索,搜索周邊poi,比如:“酒店” “餐飲” “娛樂” “學(xué)校” 等等
- getSuggestion(options:Object) 用于獲取輸入關(guān)鍵字的補(bǔ)完與提示,幫助用戶快速輸入
- reverseGeocoder(options:Object) 提供由坐標(biāo)到坐標(biāo)所在位置的文字描述的轉(zhuǎn)換。輸入坐標(biāo)返回地理位置信息和附近poi列表
- geocoder(options:Object) 提供由地址描述到所述位置坐標(biāo)的轉(zhuǎn)換,與逆地址解析的過程正好相反
- direction(options:Object) 提供駕車,步行,騎行,公交的路線規(guī)劃能力
- getCityList() 獲取全國城市列表數(shù)據(jù)
- getDistrictByCityId(options:Object) 通過城市ID返回城市下的區(qū)縣
- calculateDistance(options:Object) 計(jì)算一個(gè)點(diǎn)到多點(diǎn)的步行、駕車距離
我們以公共交通路線規(guī)劃為例來看下(以下代碼經(jīng)過簡化處理):
第一步,初始化地圖SDK對象
import config from '@/config'
import QQMapWX from '../../assets/lib/qqmap-wx-jssdk.js' // 這里用未壓縮版的代碼
const QQMapSDK = new QQMapWX({
key: config.qqMapKey || ''
})
第二步,獲取起止坐標(biāo)點(diǎn),并進(jìn)行路線查詢
// 坐標(biāo)從上一頁query傳進(jìn)來,坐標(biāo)為浮點(diǎn)數(shù),可通過geocoder接口獲取
this.fromLocation = {
latitude: +query.from.split(',')[0] || -1,
longitude: +query.from.split(',')[1] || -1
}
this.toLocation = {
latitude: +query.to.split(',')[0] || -1,
longitude: +query.to.split(',')[1] || -1
}
// 查詢地圖路線
queryMapRoutine() {
QQMapSDK.direction({
mode: 'transit', // 'transit'(公交路線規(guī)劃)
// from參數(shù)不填默認(rèn)當(dāng)前地址
from: this.fromLocation,
to: this.toLocation,
success: (res) => {
console.log('路線規(guī)劃結(jié)果', res);
let routes = res.result.routes;
this.routes = routes.map(r => {
// 對每一種路線方案,分別進(jìn)行解析
return this.parseRoute(r)
})
console.log('parsed routes', this.routes)
}
})
}
第三步,路線解析,生成路線描述等
// 解析路線,包括距離,時(shí)間,描述,路線,起止點(diǎn)等
parseRoute(route) {
let result = {}
// 出發(fā)時(shí)間
result.setOutTime = formatTime(new Date())
result.distance = route.distance < 1000 ?
`${route.distance}米` :
`${(route.distance / 1000).toFixed(2)}公里`
result.duration = route.duration < 60 ?
`${route.duration}分鐘` :
`${parseInt(route.duration / 60)}小時(shí)${route.duration % 60}分鐘`
result.desc = []
// 每一個(gè)路線分很多步,如先步行,后乘公交,再搭地鐵等
route.steps.forEach(step => {
// if (step.mode == 'WALKING' && step.distance > 0) {
// result.desc.push(`向${step.direction}步行${step.distance}米`)
// }
if (step.mode == 'TRANSIT' && step.lines[0]) {
let line = step.lines[0]
if (line.vehicle == 'BUS') line.title = `公交車-${line.title}`
if (line.vehicle == 'RAIL') line.title = `鐵路`
result.desc.push(`${line.title}: ${line.geton.title} —> ${line.getoff.title},途經(jīng) ${line.station_count} 站。`)
}
})
result.polyline = []
result.points = []
//獲取各個(gè)步驟的polyline,也就是路線圖
for(let i = 0; i < route.steps.length; i++) {
let step = route.steps[i]
let polyline = this.getStepPolyline(step)
if (polyline) {
result.points = result.points.concat(polyline.points)
result.polyline.push(polyline)
}
}
// 標(biāo)記路線整體顯示坐標(biāo)
this.getStepPolyline.colorIndex = 0
let midPointIndex = Math.floor(result.points.length / 2)
result.latitude = result.points[midPointIndex].latitude
result.longitude = result.points[midPointIndex].longitude
// 標(biāo)記路線起止點(diǎn)
let startPoint = result.points[0]
let endPoint = result.points[result.points.length - 1]
result.markers = [
{
iconPath: this.startIcon,
id: 0,
latitude: startPoint.latitude,
longitude: startPoint.longitude,
width: 28,
height: 28,
zIndex: -1,
anchor: {x: 0.5, y: 1}
},
{
iconPath: this.endIcon,
id: 1,
latitude: endPoint.latitude,
longitude: endPoint.longitude,
width: 28,
height: 28,
zIndex: -1,
anchor: {x: 0.5, y: 1}
}
]
return result
},
第四步,getStepPolyline函數(shù) 獲取路線每一步的路線polyline
getStepPolyline(step) {
let coors = [];
// 隨機(jī)顏色
let colorArr = ['#1aad19', '#10aeff', '#d84e43']
let _dottedLine = true
if (step.mode == 'WALKING' && step.polyline) {
coors.push(step.polyline);
_dottedLine = false
} else if (step.mode == 'TRANSIT' && step.lines[0].polyline) {
coors.push(step.lines[0].polyline);
} else {
return null
}
//坐標(biāo)解壓(返回的點(diǎn)串坐標(biāo),通過前向差分進(jìn)行壓縮)
let kr = 1000000;
for (let i = 0 ; i < coors.length; i++){
for (let j = 2; j < coors[i].length; j++) {
coors[i][j] = Number(coors[i][j - 2]) + Number(coors[i][j]) / kr;
}
}
//定義新數(shù)組,將coors中的數(shù)組合并為一個(gè)數(shù)組
let coorsArr = [];
let _points = [];
for (let i = 0 ; i < coors.length; i ++){
coorsArr = coorsArr.concat(coors[i]);
}
//將解壓后的坐標(biāo)放入點(diǎn)串?dāng)?shù)組_points中
for (let i = 0; i < coorsArr.length; i += 2) {
_points.push({ latitude: coorsArr[i], longitude: coorsArr[i + 1] })
}
if (!this.getStepPolyline.colorIndex) {
this.getStepPolyline.colorIndex = 0
}
let colorIndex = this.getStepPolyline.colorIndex % colorArr.length
this.getStepPolyline.colorIndex++
// 最終polyline結(jié)果
let polyline = {
width: 7,
points: _points,
color: colorArr[colorIndex],
dottedLine: _dottedLine,
arrowLine: true, // 帶箭頭的線, 開發(fā)者工具暫不支持該屬性
borderColor: '#fff',
borderWidth: 1
}
return polyline
}
最后,綁定到地圖上并輸出,我們可以得到一個(gè)大致這樣的結(jié)果:
廣州火車站 -> 廣州塔
9.88km 30分鐘
地鐵5號線 廣州火車站 -> 珠江新城,途徑7站
地鐵3號線 珠江新城 -> 廣州塔,途徑1站
這樣我們就通過direction接口進(jìn)行了簡單的路線規(guī)劃功能,接著把生成的數(shù)據(jù)綁定到地圖組件上,一個(gè)簡易的小程序就做好了,是不是很簡單?當(dāng)然如果想做得更好,就要調(diào)用其他相似接口,慢慢完善細(xì)節(jié)。
<map
id="citymap"
name="citymap"
:latitude="currentRoute.latitude"
:longitude="currentRoute.longitude"
:polyline="currentRoute.polyline"
:markers="currentRoute.markers"
scale="12"
:subkey="qqMapKey"
show-location
show-compass
enable-rotate
style="width: 100%; height: 100%;"
></map>
效果
作者:棱鏡_jh
鏈接: https://juejin.cn/post/684490...
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
相關(guān)案例查看更多
相關(guān)閱讀
- 小程序用戶登錄
- 報(bào)廢車拆解系統(tǒng)
- 云南小程序哪家好
- 汽車報(bào)廢
- 昆明網(wǎng)站設(shè)計(jì)
- 報(bào)廢車
- 云南企業(yè)網(wǎng)站
- 做小程序被騙
- 網(wǎng)站建設(shè)服務(wù)公司
- 智慧農(nóng)貿(mào)市場
- 云南網(wǎng)站建設(shè)招商
- 生成海報(bào)
- 網(wǎng)站沒排名
- 云南網(wǎng)站建設(shè)電話
- 二叉樹
- 汽車報(bào)廢拆解管理系統(tǒng)
- 保山小程序開發(fā)
- 網(wǎng)站建設(shè)案例
- typescript
- 網(wǎng)站制作哪家好
- APP
- 網(wǎng)站排名
- 昆明網(wǎng)站開發(fā)
- 汽車拆解管理系統(tǒng)
- 云南小程序開發(fā)公司
- 云南小程序開發(fā)公司推薦
- 云南網(wǎng)站建設(shè)專家
- 汽車拆解管理軟件
- 云南小程序商城
- 云南網(wǎng)絡(luò)營銷