iOS + Android용 React 기본 지도 구성요소
이 프로젝트는 소규모 그룹에 의해 유지 관리되고 있으며 문제 및 끌어오기 요청에 대한 도움은 언제나 감사하게 생각합니다. 기여할 수 있고 기여할 의향이 있다면 지침을 읽어보시기 바랍니다.
설치 지침을 참조하세요.
포함된 예제 프로젝트에 대한 설정 지침을 참조하세요.
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의 경우: 앱에서 앱 전송 보안 구성
이 라이브러리는 New Renderer Interop Layer를 사용하여 Fabric과 함께 작동합니다.
해당 단계가 필요하지 않다는 경고 메시지가 있습니다. 하지만 지금까지는 그것들 없이는 예제가 작동하지 않았습니다.
구성 파일 열기 : 프로젝트 디렉터리에서 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 속성을 사용할 수 있는 MapView로 설정하기만 하면 googleMapId 아래에 게시됩니다. 스타일 지도 자세한 내용은 여기: Google 지도 ID
<MapView />
구성 요소와 해당 하위 구성 요소에는 구독할 수 있는 여러 이벤트가 있습니다. 이 예에서는 그 중 일부를 로그에 데모로 표시합니다.
참조 및 구성 요소 메서드를 사용하거나 업데이트된 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에 여러 지도가 있을 때 적합합니다.
Poi는 클릭할 수 있으므로 이벤트를 포착하여 해당 정보를 얻을 수 있습니다(일반적으로 placeId를 사용하여 Google 장소에서 전체 세부정보를 가져옵니다).
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 지도를 사용하는 <MapView>
앱을 백그라운드로 사용하거나 다른 앱으로 전환할 때 가끔 충돌이 발생합니다. 이는 Metal API 유효성 검사를 사용하는 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 }