مكونات React Native Map لنظامي التشغيل iOS + Android
تتم صيانة هذا المشروع من قبل مجموعة صغيرة من الأشخاص، ونقدر دائمًا أي مساعدة بشأن المشكلات وطلبات السحب. إذا كنت قادرًا وراغبًا في المساهمة، يرجى قراءة الإرشادات.
انظر تعليمات التثبيت.
راجع تعليمات الإعداد لمشروع المثال المضمن.
react-native >= 0.74
.react-native >= 0.64.3
. <MapView />
واجهة برمجة تطبيقات المكونات
<Marker />
واجهة برمجة تطبيقات المكونات
<Callout />
واجهة برمجة تطبيقات المكونات
<Polygon />
واجهة برمجة تطبيقات المكونات
<Polyline />
واجهة برمجة تطبيقات المكونات
<Circle />
واجهة برمجة تطبيقات المكونات
<Overlay />
واجهة برمجة تطبيقات المكونات
<Heatmap />
واجهة برمجة تطبيقات المكونات
<Geojson />
واجهة برمجة تطبيقات المكونات
import MapView from 'react-native-maps' ;
أو
var MapView = require ( 'react-native-maps' ) ;
تم إنشاء مكون MapView هذا بحيث يتم تحديد الميزات الموجودة على الخريطة (مثل العلامات والمضلعات وما إلى ذلك) كعناصر فرعية لـ MapView نفسه. يوفر ذلك واجهة برمجة تطبيقات بديهية وشبيهة بالتفاعل للتحكم بشكل صريح في الميزات على الخريطة.
< 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 في تطبيقك
تعمل هذه المكتبة مع Fabric باستخدام New Renderer Interop Layer
توجد رسالة تحذير تفيد بأن هذه الخطوات ليست ضرورية؛ لكننا لم نتمكن من جعل المثال يعمل بدونها حتى الآن.
افتح ملف التكوين الخاص بك : حدد موقع ملف react-native-config
في دليل المشروع الخاص بك.
أضف التكوين التالي : قم بتضمين مصفوفة unstable_reactLegacyComponentNames
لكل من نظامي التشغيل Android وiOS كما هو موضح أدناه:
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 على "لا شيء". على سبيل المثال:
<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" />
تدعم خرائط Google على iOS وAndroid التصميم عبر منصة google cloud، ويتم نشر الخرائط المصممة ضمن googleMapId، وذلك ببساطة عن طريق تعيين الخاصية googleMapId إلى MapView، يمكنك استخدام ذلك مزيد من المعلومات حول الخريطة المصممة هنا: معرف خريطة جوجل
يحتوي مكون <MapView />
ومكوناته الفرعية على العديد من الأحداث التي يمكنك الاشتراك فيها. يعرض هذا المثال بعضًا منها في السجل كعرض توضيحي.
يمكن للمرء تغيير موضع عرض الخريطة باستخدام المراجع وطرق المكونات، أو عن طريق تمرير خاصية region
المحدثة. ستسمح أساليب المكونات للفرد بالتحريك إلى موضع معين مثل واجهة برمجة التطبيقات الأصلية.
يمكن جعل مكون <MapView />
يعمل مع واجهة برمجة التطبيقات المتحركة، مع الإعلان عن خاصية region
بأكملها كقيمة متحركة. يتيح ذلك تحريك التكبير/التصغير وموضع MapView جنبًا إلى جنب مع الإيماءات الأخرى، مما يعطي إحساسًا لطيفًا.
علاوة على ذلك، يمكن لطرق عرض العلامة استخدام واجهة برمجة التطبيقات المتحركة لتحسين التأثير.
المشكلة: نظرًا لأن Android يحتاج إلى عرض عروض العلامات الخاصة به كصورة نقطية، فقد لا تكون واجهات برمجة التطبيقات للرسوم المتحركة متوافقة مع طرق عرض العلامات. لست متأكدًا مما إذا كان من الممكن حل هذا الأمر بعد أم لا.
يمكن أيضًا تحريك إحداثيات العلامات، كما هو موضح في هذا المثال:
حتى الآن، تتوفر <Circle />
و <Polygon />
و <Polyline />
لتمريرها كأبناء لمكون <MapView />
.
يمكن إنشاء الخطوط المتعددة المتدرجة باستخدام خاصية strokeColors
الخاصة بالمكون <Polyline>
.
سيتم عرض العلامات الافتراضية ما لم يتم تحديد علامة مخصصة. يمكن للمرء اختياريًا ضبط لون العلامة الافتراضية باستخدام خاصية pinColor
.
يمكن أن تكون وسائل الشرح للعلامات طرق عرض تفاعلية عشوائية تمامًا، تشبه العلامات. ونتيجة لذلك، يمكن التفاعل معها مثل أي وجهة نظر أخرى.
بالإضافة إلى ذلك، يمكنك الرجوع إلى السلوك القياسي المتمثل في الحصول على عنوان/وصف من خلال title
<Marker />
ودعائم description
.
يمكن أن تكون طرق عرض وسائل الشرح المخصصة عبارة عن فقاعة تلميح الأدوات بأكملها، أو مجرد المحتوى الموجود داخل الفقاعة التفسيرية الافتراضية للنظام.
للتعامل مع الضغط على عرض فرعي محدد لوسيلة الشرح، استخدم <CalloutSubview />
مع onPress
. راجع مثال Callouts.js
.
يمكن تخصيص العلامات باستخدام الصور فقط، وتحديدها باستخدام خاصية image
.
العلامات قابلة للسحب، وتصدر أحداث سحب مستمرة لتحديث واجهة المستخدم الأخرى أثناء عمليات السحب.
قم بتمكين الوضع البسيط على Android باستخدام خاصية liteMode
. مثالية عند وجود خرائط متعددة في طريقة عرض أو ScrollView.
يمكن النقر على Poi، ويمكنك متابعة الحدث للحصول على معلوماته (عادةً للحصول على التفاصيل الكاملة من Google Place باستخدام معرف المكان).
يمكن أن يقبل MapView قيمة AnimatedRegion
كدعم region
به. يتيح لك هذا استخدام Animated 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
<MapView>
باستخدام خرائط Apple في mapType: "standard"
أحيانًا عند وضع خلفية التطبيق أو التبديل إلى تطبيق آخر. هذه مشكلة فقط في XCode باستخدام Metal API Validation، ولن تحدث في الإنتاج. للتخلص من هذه المشكلة حتى أثناء تصحيح الأخطاء في XCode، انتقل إلى Edit Scheme... -> Run (Debug) -> Diagnostics
، وقم بإلغاء تحديد Metal -> API Validation
. (ح / ر @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 }