iOS + Android 用の React Native Map コンポーネント
このプロジェクトは少人数のグループによって維持されており、問題やプル リクエストに関するサポートをいつでも歓迎します。貢献する能力と意欲がある場合は、ガイドラインをお読みください。
インストール手順を参照してください。
付属のサンプル プロジェクトのセットアップ手順を参照してください。
react-native >= 0.74
が必要です。react-native >= 0.64.3
が必要です。 <MapView />
コンポーネント API
<Marker />
コンポーネント API
<Callout />
コンポーネント API
<Polygon />
コンポーネント API
<Polyline />
コンポーネント API
<Circle />
コンポーネント API
<Overlay />
コンポーネント API
<Heatmap />
コンポーネント API
<Geojson />
コンポーネント API
import MapView from 'react-native-maps' ;
または
var MapView = require ( 'react-native-maps' ) ;
この MapView コンポーネントは、マップ上のフィーチャ (マーカー、ポリゴンなど) が MapView 自体の子として指定されるように構築されています。これにより、マップ上のフィーチャを宣言的に制御するための直感的で反応に似た API が提供されます。
< MapView
initialRegion = { {
latitude : 37.78825 ,
longitude : - 122.4324 ,
latitudeDelta : 0.0922 ,
longitudeDelta : 0.0421 ,
} }
/ >
getInitialState ( ) {
return {
region : {
latitude : 37.78825 ,
longitude : - 122.4324 ,
latitudeDelta : 0.0922 ,
longitudeDelta : 0.0421 ,
} ,
} ;
}
onRegionChange ( region ) {
this . setState ( { region } ) ;
}
render ( ) {
return (
< MapView
region = { this . state . region }
onRegionChange = { this . onRegionChange }
/ >
) ;
}
import { Marker } from 'react-native-maps' ;
< MapView region = { this . state . region } onRegionChange = { this . onRegionChange } >
{ this . state . markers . map ( ( marker , index ) => (
< Marker
key = { index }
coordinate = { marker . latlng }
title = { marker . title }
description = { marker . description }
/ >
) ) }
< / MapView > ;
png
画像を生成する必要があります (これらをcustom_pin
と呼びます) - 詳細については、Android、iOS を参照してください。 < Marker
coordinate = { { latitude : latitude , longitude : longitude } }
image = { { uri : 'custom_pin' } }
/ >
注: image={require('custom_pin.png')}
のような画像バイナリ データを渡すこともできますが、これは画面サイズが異なると適切に拡張できません。
注: これはパフォーマンスに影響します。より単純なソリューションが必要な場合は、カスタム イメージを使用してください (面倒なことは避けてください)。
< Marker coordinate = { { latitude : latitude , longitude : longitude } } >
< MyCustomMarkerView { ... marker } / >
< / Marker >
import { Callout } from 'react-native-maps' ;
< Marker coordinate = { marker . latlng } >
< MyCustomMarkerView { ... marker } / >
< Callout >
< MyCustomCalloutView { ... marker } / >
< / Callout >
< / Marker > ;
< MapView initialRegion = { ... } >
< Marker draggable
coordinate = { this . state . x }
onDragEnd = { ( e ) => this . setState ( { x : e . nativeEvent . coordinate } ) }
/ >
< / MapView >
import { UrlTile } from 'react-native-maps' ;
< MapView region = { this . state . region } onRegionChange = { this . onRegionChange } >
< UrlTile
/**
* The url template of the tile server. The patterns {x} {y} {z} will be replaced at runtime
* For example, http://c.tile.openstreetmap.org/{z}/{x}/{y}.png
*/
urlTemplate = { this . state . urlTemplate }
/**
* The maximum zoom level for this tile overlay. Corresponds to the maximumZ setting in
* MKTileOverlay. iOS only.
*/
maximumZ = { 19 }
/**
* flipY allows tiles with inverted y coordinates (origin at bottom left of map)
* to be used. Its default value is false.
*/
flipY = { false }
/ >
< / MapView > ;
Android の場合: AndroidManifest.xml に次の行を追加します。
< uses-permission android : name = " android.permission.INTERNET " />
IOS の場合: アプリで App Transport Security を構成する
このライブラリは、新しいレンダラー相互運用レイヤーを使用してファブリックで動作します
これらの手順は必要ないという警告メッセージが表示されます。しかし、これまでのところ、これらがなければサンプルを動作させることができませんでした。
設定ファイルを開きます。 プロジェクト ディレクトリで、 react-native-config
ファイルを見つけます。
次の構成を追加します。以下に示すように、Android プラットフォームと iOS プラットフォームの両方にunstable_reactLegacyComponentNames
配列を含めます。
module . exports = {
project : {
android : {
unstable_reactLegacyComponentNames : [
'AIRMap' ,
'AIRMapCallout' ,
'AIRMapCalloutSubview' ,
'AIRMapCircle' ,
'AIRMapHeatmap' ,
'AIRMapLocalTile' ,
'AIRMapMarker' ,
'AIRMapOverlay' ,
'AIRMapPolygon' ,
'AIRMapPolyline' ,
'AIRMapUrlTile' ,
'AIRMapWMSTile' ,
] ,
} ,
ios : {
unstable_reactLegacyComponentNames : [
'AIRMap' ,
'AIRMapCallout' ,
'AIRMapCalloutSubview' ,
'AIRMapCircle' ,
'AIRMapHeatmap' ,
'AIRMapLocalTile' ,
'AIRMapMarker' ,
'AIRMapOverlay' ,
'AIRMapPolygon' ,
'AIRMapPolyline' ,
'AIRMapUrlTile' ,
'AIRMapWMSTile' ,
] ,
} ,
} ,
} ;
サンプル プロジェクトをチェックアウトして、実際の動作を確認してください。
タイルは、xyz タイル スキーマを使用してデバイス内にローカルに保存でき、タイル オーバーレイとしても表示できます。これは、デバイス ストレージ内の選択したマップ領域でタイルが利用可能な場合に、オフライン マップを使用する場合に特に便利です。
import { LocalTile } from 'react-native-maps' ;
< MapView region = { this . state . region } onRegionChange = { this . onRegionChange } >
< LocalTile
/**
* The path template of the locally stored tiles. The patterns {x} {y} {z} will be replaced at runtime
* For example, /storage/emulated/0/mytiles/{z}/{x}/{y}.png
*/
pathTemplate = { this . state . pathTemplate }
/**
* The size of provided local tiles (usually 256 or 512).
*/
tileSize = { 256 }
/ >
< / MapView > ;
Android の場合: LocalTile はまだ元のマップ タイルの上にオーバーレイされているだけです。これは、デバイスがオンラインの場合でも、基礎となるタイルがダウンロードされることを意味します。元のタイルのダウンロード/表示が望ましくない場合は、mapType を「none」に設定します。例えば:
<MapView
mapType={Platform.OS == "android" ? "none" : "standard"}
>
オフラインで使用するためにタイルをダウンロードする方法については、OSM Wiki を参照してください。
MapView
をオーバーレイするコンポーネントをMapView
終了タグの下に配置します。これらの要素を絶対に配置します。
render ( ) {
return (
< MapView
region = { this . state . region }
/ >
< OverlayComponent
style = { { position : "absolute" , bottom : 50 } }
/ >
) ;
}
<MapView provider="google" googleMapId="yourStyledMapId" />
iOS および Android の Google マップは、Google クラウド プラットフォームを介したスタイル設定をサポートしており、スタイル付きの地図は googleMapId の下で公開されます。プロパティ googleMapId を MapView に設定するだけで、それを使用できます。スタイル付き地図の詳細はこちら: Google マップ ID
<MapView />
コンポーネントとその子コンポーネントには、サブスクライブできるイベントがいくつかあります。この例では、デモンストレーションとしてログにそれらの一部を表示します。
refs メソッドとコンポーネント メソッドを使用するか、更新されたregion
プロパティを渡すことによって、マップビューの位置を変更できます。コンポーネント メソッドを使用すると、ネイティブ API と同様に、特定の位置にアニメーション化できます。
<MapView />
コンポーネントは、アニメーション化された API で動作するように作成でき、 region
プロパティ全体をアニメーション化された値として宣言できます。これにより、MapView のズームや位置を他のジェスチャとともにアニメーション化でき、快適な操作感が得られます。
さらに、マーカー ビューはアニメーション API を使用して効果を高めることができます。
問題: Android はマーカー ビューをビットマップとしてレンダリングする必要があるため、アニメーション API はマーカー ビューと互換性がない可能性があります。これを回避できるかどうかはまだわかりません。
次の例に示すように、マーカーの座標をアニメーション化することもできます。
これまでのところ、 <Circle />
、 <Polygon />
、および<Polyline />
を子として<MapView />
コンポーネントに渡すことができます。
グラデーション ポリラインは、 <Polyline>
コンポーネントのstrokeColors
プロップを使用して作成できます。
カスタム マーカーが指定されない限り、デフォルトのマーカーがレンダリングされます。必要に応じて、 pinColor
プロップを使用してデフォルトのマーカーの色を調整できます。
マーカーへのコールアウトは、マーカーと同様に、完全に任意の反応ビューにすることができます。その結果、他のビューと同様に操作できます。
さらに、 <Marker />
のtitle
とdescription
小道具を使用して、タイトル/説明だけを持つ標準の動作に戻すこともできます。
カスタム吹き出しビューは、ツールヒントのバブル全体、またはシステムのデフォルトのバブル内のコンテンツのみにすることができます。
コールアウトの特定のサブビューでの押下を処理するにはonPress
で<CalloutSubview />
を使用します。 Callouts.js
例を参照してください。
マーカーは画像を使用するだけでカスタマイズでき、 image
プロップを使用して指定できます。
マーカーはドラッグ可能で、ドラッグ中に継続的なドラッグ イベントを発行して他の UI を更新します。
liteMode
prop を使用して Android でライト モードを有効にします。 View または ScrollView に複数のマップがある場合に最適です。
ポイはクリック可能で、イベントをキャッチしてその情報を取得できます (通常は、placeId を使用して Google Place から詳細を取得します)。
MapView は、 AnimatedRegion
値をそのregion
プロパティとして受け入れることができます。これにより、アニメーション API を利用してマップの中心とズームを制御できるようになります。
import MapView , { AnimatedRegion , Animated } from 'react-native-maps' ;
getInitialState ( ) {
return {
region : new AnimatedRegion ( {
latitude : LATITUDE ,
longitude : LONGITUDE ,
latitudeDelta : LATITUDE_DELTA ,
longitudeDelta : LONGITUDE_DELTA ,
} ) ,
} ;
}
onRegionChange ( region ) {
this . state . region . setValue ( region ) ;
}
render ( ) {
return (
< Animated
region = { this . state . region }
onRegionChange = { this . onRegionChange }
/ >
) ;
}
マーカーは、 AnimatedRegion
値を座標として受け入れることもできます。
import MapView , { AnimatedRegion , MarkerAnimated } from 'react-native-maps' ;
getInitialState ( ) {
return {
coordinate : new AnimatedRegion ( {
latitude : LATITUDE ,
longitude : LONGITUDE ,
} ) ,
} ;
}
componentWillReceiveProps ( nextProps ) {
const duration = 500
if ( this . props . coordinate !== nextProps . coordinate ) {
if ( Platform . OS === 'android' ) {
if ( this . marker ) {
this . marker . animateMarkerToCoordinate (
nextProps . coordinate ,
duration
) ;
}
} else {
this . state . coordinate . timing ( {
... nextProps . coordinate ,
useNativeDriver : true , // defaults to false if not passed explicitly
duration
} ) . start ( ) ;
}
}
}
render ( ) {
return (
< MapView initialRegion = { ... } >
< MarkerAnimated
ref = { marker => { this . marker = marker } }
coordinate = { this . state . coordinate }
/ >
< / MapView >
) ;
}
import MapView , { Marker } from 'react-native-maps' ;
getInitialState ( ) {
return {
coordinate : {
latitude : LATITUDE ,
longitude : LONGITUDE ,
} ,
} ;
}
takeSnapshot ( ) {
// 'takeSnapshot' takes a config object with the
// following options
const snapshot = this . map . takeSnapshot ( {
width : 300 , // optional, when omitted the view-width is used
height : 300 , // optional, when omitted the view-height is used
region : { . . } , // iOS only, optional region to render
format : 'png' , // image formats: 'png', 'jpg' (default: 'png')
quality : 0.8 , // image quality: 0..1 (only relevant for jpg, default: 1)
result : 'file' // result types: 'file', 'base64' (default: 'file')
} ) ;
snapshot . then ( ( uri ) => {
this . setState ( { mapSnapshot : uri } ) ;
} ) ;
}
render ( ) {
return (
< View >
< MapView initialRegion = { ... } ref = { map => { this . map = map } } >
< Marker coordinate = { this . state . coordinate } / >
< / MapView >
< Image source = { { uri : this . state . mapSnapshot . uri } } / >
< TouchableOpacity onPress = { this . takeSnapshot } >
Take Snapshot
< / TouchableOpacity >
< / View >
) ;
}
マップのフォーカスを再設定するには、マーカー識別子の配列を渡します。
座標の配列を渡して、その座標にマップ領域の焦点を合わせます。
const styles = StyleSheet . create ( {
map : {
... StyleSheet . absoluteFillObject ,
} ,
} ) ;
< MapView
style = { styles . map }
// other props
/ >
悪い:
< View >
< TextInput / >
< MapView / >
< / View >
良い:
< View >
< MapView / >
< TextInput / >
< / View >
MapView の独自のレンダリング方法により、このライブラリで宣言されていないコンポーネント (例: マーカー、ポリライン) を MapView コンポーネントの子にすることはできません。カスタム コンポーネント/ビューを MapView コンポーネントの外側に配置し、必要な場合にのみ再レンダリングされるように絶対位置に配置します。例: 悪い:
< View style = { StyleSheet . absoluteFillObject } >
< MapView style = { StyleSheet . absoluteFillObject } >
< View style = { { position : 'absolute' , top : 100 , left : 50 } } / >
< / MapView >
< / View >
良い:
< View style = { StyleSheet . absoluteFillObject } >
< MapView style = { StyleSheet . absoluteFillObject } / >
< View style = { { position : 'absolute' , top : 100 , left : 50 } } / >
< / View >
出典: #1901
mapType: "standard"
で Apple Maps を使用する<MapView>
、アプリをバックグラウンドで実行するか、別のアプリに切り替えるとクラッシュすることがあります。これは、Metal API Validation を使用する XCode でのみ問題となり、運用環境では発生しません。 XCode でのデバッグ中でもこの問題を解決するには、 Edit Scheme... -> Run (Debug) -> Diagnostics
、 Metal -> API Validation
チェックを外します。 (h/t @Simon-TechForm)。
出典: #3957 (コメント)
onRegionChangeComplete
での状態の変更が無限に呼び出される場合は、ユーザーのアクションの結果として領域変更が行われた場合にのみこれらの呼び出しが発生するように制限する条件を追加します。
onRegionChangeComplete = { ( region , gesture ) => {
// This fix only works on Google Maps because isGesture is NOT available on Apple Maps
if ( ! gesture . isGesture ) {
return ;
}
// You can use
dispatch ( { type : "map_region" , payload : { mapRegion : region }