前言
最近接了個跟微信小程序地圖有關的開發任務,第一次在小程序上開發地圖,既興奮又忐忑。還好,雖然小程序地圖的 API 功能有些少,但是基本的需求都能覆蓋到。
在這裏,對微信小程序地圖開發的基本功能進行總結歸納。官方文檔對地圖屬性、方法的歸納比較到位,但缺乏示例代碼,第一次搞還是有點迷糊的。網上的文章又寫得七零八落,沒見到有人專門總結歸納。
本人使用 React + Taro 開發的微信小程序,因此使用的是 Taro 提供的地圖 API,但是和微信官方的是一樣的,Taro 不過是二次封裝而已。
相關鏈接:
- Taro Map 組件
- Taro Map 實例方法
- 微信官方文檔 map
創建地圖
引入 Map 組件,再像普通組件使用即可。可以添加很多屬性,各個屬性的作用詳見 Taro 文檔。
import { Map } from '@tarojs/components';
class TaroMap extends Component {
render() {
<Map
id="taroMap"
longitude={100}
latitude={90}
show-location
/>
}
}
在地圖畫標記點
通過設置 Map 組件的 markers 屬性,在地圖上設置標記點。
標記點一般都需要設置這幾個屬性:
id:設置標記點的 idlongitude:設置標記點經度latitude:設置標記點緯度iconPath:設置標記點圖標width:設置寬度height:設置高度
import { Map } from '@tarojs/components';
import markerImg from './example.svg';
class TaroMap extends Component {
markers = [
{
id: 0,
iconPath: markerImg,
longitude: 100,
latitude: 20,
width: 50,
height: 50,
},
{
id: 1,
iconPath: markerImg,
longitude: 100,
latitude: 20,
width: 50,
height: 50,
},
]
render() {
<Map
id="taroMap"
longitude={100}
latitude={90}
show-location
markers={markers}
/>
}
}
在地圖畫圓圈
通過設置 Map 組件的 circles 屬性,在地圖上畫圈。
圓圈一般都需要設置這幾個屬性:
longitude:設置圓圈中心經度latitude:設置圓圈中心緯度color:設置圓圈邊緣顏色fillColor:設置圓圈填充顏色radius:設置圓圈半徑,單位是米,這裏是實際的半徑大小
import { Map } from '@tarojs/components';
class TaroMap extends Component {
circles = [
{
longitude: 100,
latitude: 20,
color: '#30BC6B',
fillColor: 'blue',
radius: 500,
},
]
render() {
<Map
id="taroMap"
longitude={100}
latitude={90}
show-location
circles={circles}
/>
}
}
初始化地圖中心為當前位置,並畫圈
大部分地圖都會在進入頁面時把中心移動到當前位置,同時會以當前位置為中心畫一個圓圈。
該需求主要利用 getLocation() 方法來實現,getLocation() 方法可以獲取當前的地理位置、速度等信息。
import { Map } from '@tarojs/components';
class TaroMap extends Component {
state = {
longitude: 100,
latitude: 90,
circles: [],
}
componentDidMount() {
this.getCurrentLocation();
}
getCurrentLocation = async () => {
const res = await Taro.getLocation({ type: 'gcj02' });
const { longitude, latitude } = res;
this.setState({
longitude,
latitude,
circles: [{
longitude,
latitude,
color: 'red',
fillColor: 'green',
radius: 500
}],
});
}
render() {
const { longitude, latitude } = this.state;
<Map
id="taroMap"
longitude={longitude}
latitude={latitude}
show-location
circles={circles}
/>
}
}
始終固定圖標在地圖中心
平時常見的地圖,往往都會有一個圖標固定在地圖的中心,並且無論如何拖動地圖,位置都始終不變。
在舊版的微信小程序地圖中,這個功能需要使用 control 控件實現,但官方已經明確説明即將廢棄該方式。後來又通過利用視圖容器 cover-view 來實現,但是 2023 年的現在連 cover-view 也不需要了,直接使用普通的 view 容器組件即可。
這樣一來,就是很普通的設置元素水平垂直居中的問題了。
目前原生組件均已支持同層渲染,建議使用 view 替代
import { Map, View, Image } from '@tarojs/components';
class TaroMap extends Component {
render() {
<Map
id="taroMap"
longitude={100}
latitude={90}
show-location
className="map"
>
<View className="center">
<Image className="center--image" src='./marker.png' />
</View>
</Map>
}
}
.map {
width: 100vw;
height: 100vh;
position: relative;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.center--image {
width: 70px;
height: 70px;
}
返回當前位置
點擊返回圖標,讓地圖回到當前位置,幾乎是每個地圖都必備的功能。而這個功能實現起來其實非常簡單,首先調用 createMapContext() 創建一個地圖實例對象,再調用地圖實例的 moveToLocation() 方法將地圖中心移動到當前定位點即可。
handleBackCurrenLocation = () => {
// 需要把地圖的id傳入
const wxMap = Taro.createMapContext(mapId);
wxMap.moveToLocation({});
}
地圖拖動展示不同的標記點
由於地圖上的標記點可能會非常多,所以一般都不會一口氣把所有的點都畫到地圖上,而是展示地圖中心某個範圍之內的點。
拖動地圖,再展示新的地圖中心附近的標記點。
該功能的實現需要用到 onRegionChange 事件,當地圖視野發生變化時會觸發該事件,也就是拖動地圖。像這種頻繁觸發的事件,最好防抖。
import _ from 'lodash'
class TaroMap extends Component {
// 防抖500毫秒
onRegionChange = _.debounce(async (e) => {
const { type, detail } = e;
// 拖動地圖會觸發兩次onRegionChange事件,我們只需要拖動結束時的事件
if (type === 'end') {
const { centerLocation: { longitude, latitude } } = detail;
// ...獲取新的標記點
const markers = [];
this.setState({ markers });
}
}
}, 500)
render() {
<Map
id="taroMap"
longitude={100}
latitude={90}
show-location
className="map"
onRegionChange={this.onRegionChange}
>
<View className="center">
<Image className="center--image" src='./marker.png' />
</View>
</Map>
}
}
結尾
小程序地圖開發常見的功能需求就是這些啦。
微信小程序地圖功能不多,但是裏面的坑卻不少,回頭也總結一下。
更多內容,可見我的博客。