博客 / 詳情

返回

一篇文章入門-微信小程序地圖開發

前言

最近接了個跟微信小程序地圖有關的開發任務,第一次在小程序上開發地圖,既興奮又忐忑。還好,雖然小程序地圖的 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:設置標記點的 id
  • longitude:設置標記點經度
  • 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>
  }
}

結尾

小程序地圖開發常見的功能需求就是這些啦。

微信小程序地圖功能不多,但是裏面的坑卻不少,回頭也總結一下。

更多內容,可見我的博客。

user avatar peter-wilson 頭像 jidongdehai_co4lxh 頭像 tigerandflower 頭像 yaofly 頭像 hightopo 頭像 esunr 頭像 zhangxishuo 頭像 susouth 頭像 suporka 頭像 huanjinliu 頭像 79px 頭像 dashnowords 頭像
44 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.