1. 程式人生 > >React Native 高德地圖元件的使用(react-native-amap3d)

React Native 高德地圖元件的使用(react-native-amap3d)

這篇文章主要介紹 RN 高德地圖元件 react-native-amap3d,安裝過程請參考 README。

基本使用

import {MapView} from 'react-native-amap3d'

render() {
  return <MapView style={StyleSheet.absoluteFill}/>
}

設定地圖狀態

所謂的地圖狀態包括:中心座標(coordinate)、縮放級別(zoomLevel)、傾斜度(titl)、旋轉角度(rotation)、顯示區域(region)。

通過 coordinate、zoomLevel 設定顯示區域

<MapView
  style={StyleSheet.absoluteFill}
  coordinate={{
    latitude
: 39.90980, longitude: 116.37296, }} zoomLevel={18} tilt={45} showsIndoorMap />

通過 region 設定顯示區域

region 由中心座標和經緯跨度組成,相對於 zoomLevel,region 可以精確控制顯示邊界。

<MapView
  style={StyleSheet.absoluteFill}
  region={{
    latitude: 39.90980,
    longitude: 116.37296,
    latitudeDelta: 0.1,
    longitudeDelta
: 0.1, }} />

動畫過渡

通過屬性控制的地圖狀態切換會顯得比較生硬,如果希望地圖狀態切換是動畫過渡的,可以使用 animateTo 方法。

<MapView ref={ref => this._mapView} style={StyleSheet.absoluteFill}/>

this._mapView.animateTo({
  tilt: 45,
  rotation: 90,
  zoomLevel: 18,
  coordinate: {
    latitude: 39.97837,
    longitude: 116.31363,
  }
})

5種地圖模式

目前高德地圖支援5種地圖模式:

  • 標準(standard)
  • 衛星(satellite)
  • 導航(navigation)
  • 公交(bus)
  • 夜間(night)
<MapView
  style={StyleSheet.absoluteFill}
  zoomLevel={14}
  mapType='satellite'
/>
衛星地圖
衛星地圖
導航地圖
導航地圖
公交地圖
公交地圖
夜間地圖
夜間地圖

地圖事件

目前支援的地圖事件有:

  • onPress 點按事件
  • onLongPress 長按事件
  • onLocation 定位事件
  • onStatusChange 地圖狀態變化事件,變化過程會一直呼叫
  • onStatusChangeComplete 地圖狀態變化結束事件

可以通過 event.nativeEvent 獲取事件傳遞過來的資料

定位

通過 locationEnabled 控制是否啟用定位,通過 locationInterval distanceFilter 可以控制定位頻次。

<MapView
  style={StyleSheet.absoluteFill}
  locationEnabled
  locationInterval={10000}
  distanceFilter={10}
  onLocation={({nativeEvent}) =>
    console.log(`${nativeEvent.latitude}, ${nativeEvent.longitude}`)}
/>

新增標註點

預設標註點

<MapView style={StyleSheet.absoluteFill}>
  <Marker
    active
    title='這是一個標註點'
    color='red'
    description='Hello world!'
    coordinate={{
      latitude: 39.806901,
      longitude: 116.397972,
    }}
  />
</MapView>

可拖拽的標註點

<Marker
  draggable
  onDragEnd={({nativeEvent}) =>
    console.log(`${nativeEvent.latitude}, ${nativeEvent.longitude}`)}
  coordinate={{
    latitude: 39.806901,
    longitude: 116.397972,
  }}
/>

自定義圖片

可以通過 image 屬性設定標註點圖片,image 的值是圖片資源的名字,對於 android 是 drawable,對於 ios 是 Images.xcassets。

<Marker
  title='自定義圖片'
  image='flag'
  coordinate={{
    latitude: 39.806901,
    longitude: 116.397972,
  }}
/>

自定義 View

除了 image,還可以用 View 作為標註點,更自由的控制標註點的顯示。

<Marker
  active
  title='自定義 View'
  coordinate={{
    latitude: 39.806901,
    longitude: 116.397972,
  }}
  icon={() =>
    <View style={style.marker}>
      <Text style={style.markerText}>{(new Date()).toLocaleTimeString()}</Text>
    </View>
  }
/>

const style = StyleSheet.create({
  marker: {
    backgroundColor: '#009688',
    alignItems: 'center',
    borderRadius: 5,
    padding: 5,
  },
  markerText: {
    color: '#fff',
  },
})

自定義彈出視窗

<Marker
  active
  coordinate={{
    latitude: 39.806901,
    longitude: 116.397972,
  }}
>
  <View style={style.infoWindow}>
    <Text>自定義彈出視窗</Text>
  </View>
</Marker>

const style = StyleSheet.create({
  infoWindow: {
    backgroundColor: '#8bc34a',
    padding: 10,
    borderRadius: 10,
    elevation: 4,
    borderWidth: 2,
    borderColor: '#689F38',
  },
})

繪製線段

<MapView zoomLevel={10} style={StyleSheet.absoluteFill}>
  <Polyline
    width={10}
    color='rgba(255, 0, 0, 0.5)'
    coordinates={[
      {
        latitude: 40.006901,
        longitude: 116.097972,
      },
      {
        latitude: 40.006901,
        longitude: 116.597972,
      },
      {
        latitude: 39.706901,
        longitude: 116.597972,
      },
    ]}
  />
</MapView>

熱力圖

import {MapView, HeatMap} from 'react-native-amap3d'

_coordinates = (new Array(200)).fill(0).map(i => ({
  latitude: 39.5 + Math.random(),
  longitude: 116 + Math.random(),
}))

<MapView zoomLevel={9} style={StyleSheet.absoluteFill}>
  <HeatMap
    opacity={0.8}
    radius={20}
    coordinates={this._coordinates}/>
</MapView>

海量點

批量新增的 Marker 數量過多會出現效能問題,這時可以考慮用海量點(MultiPoint)。

import {MapView, MultiPoint} from 'react-native-amap3d'

_points = Array(1000).fill(0).map(i => ({
  latitude: 39.5 + Math.random(),
  longitude: 116 + Math.random(),
}))

_onItemPress = point => Alert.alert(this._points.indexOf(point).toString())

<MapView zoomLevel={10} style={StyleSheet.absoluteFill}>
  <MultiPoint
    image='point'
    points={this._points}
    onItemPress={this._onItemPress}
  />
</MapView>

更多示例