
這里要說(shuō)的是,小程序官方的 map 地圖說(shuō)明文檔已經(jīng)非常詳細(xì)了,但是鑒于如果沒(méi)有一個(gè)合適的使用場(chǎng)景,對(duì)于剛接觸 map 的我們,看著這些繁雜又賊多的屬性名和字段,外加急切的開(kāi)發(fā)需求,暈頭轉(zhuǎn)向是不可避免的了。接下來(lái)我會(huì)將自己在項(xiàng)目中對(duì) map 的一些使用做一個(gè)總結(jié),不敢說(shuō)寫(xiě)得非常棒,但絕對(duì)比一大堆直接復(fù)制官方文檔的文章要好得多,希望能幫助到正在開(kāi)發(fā)的你 ??。
如果你正在開(kāi)發(fā)小程序,但是并沒(méi)有接觸到 map 地圖相關(guān)功能,沒(méi)關(guān)系,收藏起來(lái),沒(méi)準(zhǔn)哪天就能用得上,遇見(jiàn)就不再錯(cuò)過(guò),想想就刺激 ??。
請(qǐng)粗略的瀏覽下這兩篇介紹文檔,確保下面的內(nèi)容看起來(lái)更通俗易懂
小程序不支持直接獲取到定位的地點(diǎn)信息,返回的是當(dāng)前位置的經(jīng)緯度,如果你需要用到 「逆地址解析」(將指定經(jīng)緯度轉(zhuǎn)換為具體地址) 、「關(guān)鍵詞輸入提示」等功能,個(gè)人建議使用「騰訊位置服務(wù)微信小程序JavaScript SDK」,都是騰訊家的,在定位上的精準(zhǔn)度要好得多,當(dāng)然也可以使用百度、高德等小程序 API 服務(wù)。
如果你想做成類似 ofo 、mobike 和滴滴打車的效果,這篇文章是你的不二選擇。
先放上一張效果圖:開(kāi)發(fā)工具的效果會(huì)差一點(diǎn),真機(jī)上體驗(yàn)還是不錯(cuò)的,頂部的提示框的樣式在真機(jī)上顯示正常,在小程序開(kāi)發(fā)工具上卻不居中,很傷。

因?yàn)槭枪卷?xiàng)目,stone 君只能小心翼翼剔除一些涉及公司隱私的代碼,不過(guò)主要的邏輯和思路都是在的,東西不多,但蒼蠅再小也是肉啊 ??。
先貼出 map 標(biāo)簽 css 代碼,并對(duì)其中重要屬性進(jìn)行說(shuō)明
<map class='map' id='myMap' longitude="{{longitude}}" latitude="{{latitude}}" scale="{{scale}}"
show-location="true" markers="{{markers}}" bindmarkertap="bindMakertap" bindcontroltap='controlTap'
bindregionchange='regionChange' controls='{{controls}}'
bindtap='bindMapTap'>
- id :map 組件的 id,在 wx.createMapContext(mapId, this) 中需要用到
- longitude :map 組件的中心經(jīng)度
- latitude:map 組件的中心緯度
- scale:縮放級(jí)別,取值范圍為5-18,默認(rèn)為16
- show-location:顯示帶有方向的當(dāng)前定位點(diǎn),即顯示代表當(dāng)前位置的藍(lán)色定位點(diǎn)圖標(biāo),另外 mapContext 的 moveToLocation() 方法在官方文檔有著這樣的說(shuō)明(將地圖中心移動(dòng)到當(dāng)前定位點(diǎn),需要配合map組件的show-location使用)
- markers:標(biāo)記點(diǎn)用于在地圖上顯示標(biāo)記的位置,是一個(gè)數(shù)組對(duì)象
- bindmarkertap:點(diǎn)擊 marker 標(biāo)記點(diǎn)時(shí)觸發(fā)
- bindcontroltap:點(diǎn)擊控件時(shí)觸發(fā)
- bindregionchange:拖動(dòng)地圖觸發(fā)
- controls:在地圖上顯示控件,控件不隨著地圖移動(dòng),是一個(gè)數(shù)組對(duì)象
- bindtap: 點(diǎn)擊地圖時(shí)觸發(fā)(拖動(dòng)地圖時(shí)不會(huì)觸發(fā)點(diǎn)擊)
下面給出我在項(xiàng)目中遇到的問(wèn)題,以及一些功能的解決方案。
1、map 上無(wú)法顯示 view 等標(biāo)簽
map 上放置常規(guī)標(biāo)簽,在開(kāi)發(fā)工具模擬器上能顯示,在真機(jī)卻顯示不出來(lái)。
原因:map 組件是由客戶端創(chuàng)建的原生組件,它的層級(jí)是最高的,不能通過(guò) z-index 控制層級(jí)。
這里有兩個(gè)解決方案,為了方便,此處采用微信提供的 cover-view 控件:
//這里是演示圖中頂部提示視圖的部分代碼
<!--頂部提示-->
<cover-view class='cover-tip-wrapper' wx:if='{{showTopTip}}' bindtap='showNewMarkerClick'>
<cover-image class='tip-bg' src='../../img/tip-bg.png'>
</cover-image>
<cover-view class='cover-tip-content'>
<cover-image class='trumpet-icon' src='../../img/notification.png'>
</cover-image>
<cover-view class='tip-text'>{{warningText}}</cover-view>
<cover-image class='right-arrow' src='../../img/right-arrow.png'></cover-image>
</cover-view>
</cover-view>
2、怎么定位到某個(gè)坐標(biāo),并且讓這個(gè)經(jīng)緯度地址處于地圖中心?

map 的兩個(gè)屬性 longitude 和 latitude 表示當(dāng)前地圖的中心經(jīng)緯度,和當(dāng)前用戶定位的經(jīng)緯度是兩個(gè)概念,并無(wú)直接關(guān)系,如果我們一直改變此 longitude 和 latitude,地圖的中心是會(huì)一直變化的,所以只要利用好了這兩個(gè)屬性變量,實(shí)現(xiàn)上面的功能是很簡(jiǎn)單的
that.setData({
latitude: res.latitude,
longitude: res.longitude,
})
3、怎么實(shí)現(xiàn)拖動(dòng)地圖,讓定位圖標(biāo)一直在地圖中心,并實(shí)時(shí)獲取中心經(jīng)緯度?(參考上方 GIF 效果)
- map 中有個(gè) controls 屬性,點(diǎn)擊查看官方介紹
- mapContext 對(duì)象的 getCenterLocation()方法,點(diǎn)擊查看
//創(chuàng)建中心指針圖標(biāo)(代碼中具體屬性請(qǐng)參考 demo)
that.setData({
controls: [{
id: 1,
iconPath: '../../img/center-location.png',
position: {
left: (windowWidth - controlsWidth) / 2,
top: (windowHeight - bottomHeight) / 2 - controlsHeight * 3 / 4,
width: controlsWidth,
height: controlsHeight
},
clickable: true
}]
})
/**
* 拖動(dòng)地圖回調(diào)
*/
regionChange: function (res) {
var that = this;
// 改變中心點(diǎn)位置
if (res.type == "end") {
that.getCenterLocation();
}
},
/**
* 得到中心點(diǎn)坐標(biāo)
*/
getCenterLocation: function () {
var that = this;
//mapId 就是你在 map 標(biāo)簽中定義的 id
var mapCtx = wx.createMapContext(mapId);
mapCtx.getCenterLocation({
success: function (res) {
console.log('getCenterLocation----------------------->');
console.log(res);
that.updateCenterLocation(res.latitude, res.longitude);
that.regeocodingAddress();
that.queryMarkerInfo();
}
})
},
4、如何準(zhǔn)確回到當(dāng)前定位點(diǎn)
//請(qǐng)求當(dāng)前定位
wx.getLocation({
type: 'gcj02',
success: function (res) {
that.setData({
latitude: res.latitude,
longitude: res.longitude,
})
that.moveTolocation();
},
})
/**
* 移動(dòng)到中心點(diǎn)
*/
moveTolocation: function () {
//mapId 就是你在 map 標(biāo)簽中定義的 id
var mapCtx = wx.createMapContext(mapId);
mapCtx.moveToLocation();
},
5、如何創(chuàng)建 marker 點(diǎn)
markers 是包含一個(gè)至多個(gè) marker 點(diǎn)的數(shù)組,一個(gè) marker 標(biāo)記點(diǎn)至少需要包含圖標(biāo) iconPath,出現(xiàn)的經(jīng)度坐標(biāo)點(diǎn) longitude,出現(xiàn)的緯度坐標(biāo)點(diǎn) latitude,你可以自定義 marker 點(diǎn)的寬高(單位為 px),如果你有點(diǎn)擊 marker 進(jìn)行邏輯操作的要求,那就一定要為每一個(gè) marker 標(biāo)記點(diǎn)設(shè)置一個(gè)唯一的 id,用于在點(diǎn)擊觸發(fā)時(shí)判斷點(diǎn)擊的是哪一個(gè) marker 點(diǎn)。
//marker 點(diǎn)的格式是這樣的,需要一個(gè)
markers: [{
iconPath: "/resources/others.png",
id: 0,
latitude: 23.099994,
longitude: 113.324520,
width: 50,
height: 50
}],
//但是更多時(shí)候是請(qǐng)求服務(wù)器返回 marker 點(diǎn)集合,類似膜拜和 ofo,拖動(dòng)地圖,改變中心點(diǎn)就會(huì)刷新改變周圍的 marker 點(diǎn),這些點(diǎn)可能是客戶端上傳的,也有可能是膜拜這種車載GPS模塊發(fā)送給服務(wù)器記錄的。
//大致類似于以下這樣,但是代碼僅供參考
/**
* 創(chuàng)建marker
*/
createMarker: function (dataList) {
var that = this;
var currentMarker = [];
var markerList = dataList.data;
for (var key in markerList) {
var marker = markerList[key];
marker.id = marker.info_id;
marker.latitude = marker.lat;
marker.longitude = marker.lng;
marker.width = 40;
marker.height = 40;
if (marker.image) {
marker.iconPath = '../../img/dog-select.png';
} else {
marker.iconPath = '../../img/dog-yellow.png';
}
}
currentMarker = currentMarker.concat(markerList);
consoleUtil.log('-----------------------');
consoleUtil.log(currentMarker);
that.setData({
markers: currentMarker
})
},
這次先寫(xiě)到這里,如果有更新,后續(xù)會(huì)一直補(bǔ)全。
戳我查看 Demo
這里有一些關(guān)于小程序的一些開(kāi)發(fā)者社區(qū):