
تحدّد العلامات المواقع الجغرافية على الخريطة. يستخدم المحدّد التلقائي رمزًا عاديًا، وهو شائع في مظهر "خرائط Google". يمكنك تغيير لون الرمز أو صورته أو نقطة الارتكاز الخاصة به من خلال واجهة برمجة التطبيقات. العلامات هي عناصر من النوع
Marker، وتتم إضافتها إلى الخريطة باستخدام الطريقة
GoogleMap.addMarker(markerOptions).
تم تصميم العلامات لتكون تفاعلية. تتلقّى هذه العناصر أحداث click تلقائيًا، ويتم استخدامها غالبًا مع أدوات معالجة الأحداث لعرض نوافذ المعلومات. يؤدي ضبط السمة draggable لعلامة على true
إلى السماح للمستخدم بتغيير موضع العلامة. اضغط مع الاستمرار لتفعيل إمكانية تحريك محدّد الموقع.
تلقائيًا، عندما ينقر المستخدم على علامة، يظهر شريط أدوات الخريطة في أسفل يسار الخريطة، ما يتيح للمستخدم الوصول بسرعة إلى تطبيق "خرائط Google" للأجهزة الجوّالة. ويمكنك إيقاف شريط الأدوات. لمزيد من المعلومات، يُرجى الاطّلاع على دليل عناصر التحكّم.
إضافة علامة
يوضّح المثال التالي كيفية إضافة علامة إلى خريطة. يتم إنشاء العلامة عند الإحداثيات -33.852,151.211 (سيدني، أستراليا)، وتعرض السلسلة "علامة في سيدني" في نافذة معلومات عند النقر عليها.
Kotlin
override fun onMapReady(googleMap: GoogleMap) { // Add a marker in Sydney, Australia, // and move the map's camera to the same location. val sydney = LatLng(-33.852, 151.211) googleMap.addMarker( MarkerOptions() .position(sydney) .title("Marker in Sydney") ) googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)) }
جافا
@Override public void onMapReady(GoogleMap googleMap) { // Add a marker in Sydney, Australia, // and move the map's camera to the same location. LatLng sydney = new LatLng(-33.852, 151.211); googleMap.addMarker(new MarkerOptions() .position(sydney) .title("Marker in Sydney")); googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); }
عرض معلومات إضافية عن علامة
من المتطلبات الشائعة عرض معلومات إضافية حول مكان أو موقع جغرافي عندما ينقر المستخدم على علامة على الخريطة. راجِع دليل نوافذ المعلومات.
ربط البيانات بمحدّد موقع
يمكنك تخزين كائن بيانات عشوائي مع علامة باستخدام Marker.setTag()، واسترداد كائن البيانات باستخدام Marker.getTag(). يوضّح المثال أدناه كيف يمكنك احتساب عدد المرات التي تم فيها النقر على علامة باستخدام العلامات:
Kotlin
/** * A demo class that stores and retrieves data objects with each marker. */ class MarkerDemoActivity : AppCompatActivity(), OnMarkerClickListener, OnMapReadyCallback { private val PERTH = LatLng(-31.952854, 115.857342) private val SYDNEY = LatLng(-33.87365, 151.20689) private val BRISBANE = LatLng(-27.47093, 153.0235) private var markerPerth: Marker? = null private var markerSydney: Marker? = null private var markerBrisbane: Marker? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_markers) val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment? mapFragment!!.getMapAsync(this) } /** Called when the map is ready. */ override fun onMapReady(map: GoogleMap) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker( MarkerOptions() .position(PERTH) .title("Perth") ) markerPerth?.tag = 0 markerSydney = map.addMarker( MarkerOptions() .position(SYDNEY) .title("Sydney") ) markerSydney?.tag = 0 markerBrisbane = map.addMarker( MarkerOptions() .position(BRISBANE) .title("Brisbane") ) markerBrisbane?.tag = 0 // Set a listener for marker click. map.setOnMarkerClickListener(this) } /** Called when the user clicks a marker. */ override fun onMarkerClick(marker: Marker): Boolean { // Retrieve the data from the marker. val clickCount = marker.tag as? Int // Check if a click count was set, then display the click count. clickCount?.let { val newClickCount = it + 1 marker.tag = newClickCount Toast.makeText( this, "${marker.title} has been clicked $newClickCount times.", Toast.LENGTH_SHORT ).show() } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false } }
جافا
/** * A demo class that stores and retrieves data objects with each marker. */ public class MarkerDemoActivity extends AppCompatActivity implements GoogleMap.OnMarkerClickListener, OnMapReadyCallback { private final LatLng PERTH = new LatLng(-31.952854, 115.857342); private final LatLng SYDNEY = new LatLng(-33.87365, 151.20689); private final LatLng BRISBANE = new LatLng(-27.47093, 153.0235); private Marker markerPerth; private Marker markerSydney; private Marker markerBrisbane; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_markers); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** Called when the map is ready. */ @Override public void onMapReady(GoogleMap map) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker(new MarkerOptions() .position(PERTH) .title("Perth")); markerPerth.setTag(0); markerSydney = map.addMarker(new MarkerOptions() .position(SYDNEY) .title("Sydney")); markerSydney.setTag(0); markerBrisbane = map.addMarker(new MarkerOptions() .position(BRISBANE) .title("Brisbane")); markerBrisbane.setTag(0); // Set a listener for marker click. map.setOnMarkerClickListener(this); } /** Called when the user clicks a marker. */ @Override public boolean onMarkerClick(final Marker marker) { // Retrieve the data from the marker. Integer clickCount = (Integer) marker.getTag(); // Check if a click count was set, then display the click count. if (clickCount != null) { clickCount = clickCount + 1; marker.setTag(clickCount); Toast.makeText(this, marker.getTitle() + " has been clicked " + clickCount + " times.", Toast.LENGTH_SHORT).show(); } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false; } }
في ما يلي بعض الأمثلة على السيناريوهات التي يكون فيها تخزين البيانات واسترجاعها باستخدام العلامات مفيدًا:
- قد يوفّر تطبيقك أنواعًا مختلفة من العلامات، وتريد التعامل معها بشكل مختلف عندما ينقر عليها المستخدم. لإجراء ذلك، يمكنك تخزين
Stringمع العلامة التي تشير إلى النوع. - قد تتعامل مع نظام يتضمّن معرّفات سجلّ فريدة، حيث تمثّل العلامات سجلّات معيّنة في ذلك النظام.
- قد تشير بيانات العلامة إلى أولوية يجب استخدامها عند تحديد قيمة z-index الخاصة بعلامة.
جعل علامة قابلة للسحب
يمكنك إعادة ضبط موضع علامة بعد إضافتها إلى الخريطة طالما أنّ قيمة السمة draggable هي true. اضغط مع الاستمرار على العلامة لتفعيل ميزة السحب. عند رفع إصبعك عن الشاشة، سيبقى المؤشر في هذا الموضع.
لا يمكن سحب العلامات تلقائيًا. يجب ضبط العلامة بشكل صريح على أنّها قابلة للسحب باستخدام MarkerOptions.draggable(boolean) قبل إضافتها إلى الخريطة، أو باستخدام Marker.setDraggable(boolean) بعد إضافتها إلى الخريطة.
يمكنك الاستماع إلى أحداث السحب على العلامة، كما هو موضّح في أحداث سحب العلامة.
يضيف المقتطف أدناه علامة قابلة للسحب في بيرث، أستراليا.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .draggable(true) )
جافا
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .draggable(true));
تخصيص علامة
يعرض هذا الفيديو طرقًا لاستخدام علامات لتصوّر المواقع الجغرافية على الخريطة.
يمكن أن تحدّد العلامات صورة مخصّصة لعرضها بدلاً من الرمز التلقائي. يتضمّن تحديد رمز ضبط عدد من السمات التي تؤثّر في السلوك المرئي للعلامة.
تتيح العلامات تخصيصها من خلال السمات التالية:
- الموضع (مطلوب)
- قيمة
LatLngموضع العلامة على الخريطة. هذه هي السمة الوحيدة المطلوبة لكائنMarker. - نقطة إرساء
- النقطة على الصورة التي سيتم وضعها في موضع LatLng الخاص بالعلامة. يكون هذا الخيار تلقائيًا في منتصف أسفل الصورة.
- إصدار أولي
- تضبط مستوى تعتيم العلامة. القيمة التلقائية هي 1.0.
- العنوان
- تمثّل هذه السمة سلسلة يتم عرضها في نافذة المعلومات عندما ينقر المستخدم على العلامة.
- المقتطف
- نص إضافي يظهر أسفل العنوان
- رمز
- صورة نقطية يتم عرضها بدلاً من صورة العلامة التلقائية
- عنصر قابل للسحب
- اضبط هذا الخيار على
trueإذا كنت تريد السماح للمستخدم بنقل العلامة. القيمة التلقائية هيfalse. - Visible
- اضبط القيمة على
falseلإخفاء العلامة. القيمة التلقائية هيtrue. - الاتجاه الأفقي أو اتجاه اللوحة الإعلانية
- تستخدم العلامات تلقائيًا اتجاه اللوحة الإعلانية، ما يعني أنّه يتم رسمها بشكل موجّه نحو شاشة الجهاز بدلاً من سطح الخريطة. لا يؤدي تدوير الخريطة أو إمالتها أو تكبيرها/تصغيرها إلى تغيير اتجاه العلامة. يمكنك ضبط اتجاه العلامة لتكون مسطّحة على الأرض. تدور العلامات المسطّحة عند تدوير الخريطة، وتتغير المنظور عند إمالة الخريطة. وكما هو الحال مع علامات اللوحات الإعلانية، تحتفظ العلامات المسطّحة بحجمها عند تكبير الخريطة أو تصغيرها.
- تدوير
- اتجاه العلامة، ويتم تحديده بالدرجات في اتجاه عقارب الساعة. يتغيّر الموضع التلقائي إذا كانت العلامة مسطّحة. يكون الموضع التلقائي لعلامة مسطّحة محاذيًا للشمال. عندما لا يكون العلامة مسطّحة، يكون الموضع التلقائي متّجهًا للأعلى ويكون الدوران بحيث تكون العلامة متّجهة دائمًا نحو الكاميرا.
ينشئ المقتطف أدناه علامة بسيطة باستخدام الرمز التلقائي.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) )
جافا
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation));
تخصيص لون العلامة
يمكن تخصيص لون صورة العلامة التلقائية من خلال تمرير
عنصر BitmapDescriptor إلى طريقة icon(). يمكنك استخدام مجموعة من الألوان المحدّدة مسبقًا في العنصر BitmapDescriptorFactory، أو ضبط لون مخصّص للعلامة باستخدام الطريقة BitmapDescriptorFactory.defaultMarker(float hue). الصبغة هي قيمة
تتراوح بين 0 و360، وتمثّل نقاطًا على عجلة الألوان.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)) )
جافا
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
تخصيص مستوى تعتيم العلامة
يمكنك التحكّم في مستوى عتامة العلامة باستخدام طريقة MarkerOptions.alpha(). يجب تحديد قيمة ألفا كعدد عشري بين 0.0 و1.0، حيث 0 تعني شفافية كاملة و1 تعني تعتيمًا كاملاً.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .alpha(0.7f) )
جافا
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker(new MarkerOptions() .position(melbourneLocation) .alpha(0.7f));
تخصيص صورة العلامة
يمكنك استبدال صورة العلامة التلقائية بصورة علامة مخصّصة، ويُطلق عليها غالبًا اسم رمز. يتم دائمًا ضبط الرموز المخصّصة على BitmapDescriptor، ويتم تحديدها باستخدام إحدى الطرق في الفئة BitmapDescriptorFactory.
fromAsset(String assetName)- تنشئ هذه السمة محدّد موقع مخصّص باستخدام اسم صورة نقطية في مجلّد الموارد.
fromBitmap(Bitmap image)- تُنشئ هذه السمة محدّد موقع مخصّص من صورة نقطية.
fromFile(String fileName)- تُنشئ هذه السمة رمزًا مخصّصًا باستخدام اسم ملف صورة نقطية (Bitmap) مخزّن في وحدة تخزين داخلية.
fromPath(String absolutePath)- تنشئ هذه السمة محدّد موقع مخصّص من مسار ملف مطلق لصورة نقطية.
fromResource(int resourceId)- تنشئ هذه الطريقة محدّد موقع مخصّص باستخدام رقم تعريف المورد لصورة نقطية.
ينشئ المقتطف أدناه علامة مع رمز مخصّص.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .title("Melbourne") .snippet("Population: 4,137,400") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)) )
جافا
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .title("Melbourne") .snippet("Population: 4,137,400") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
تسطيح علامة
يتم عادةً رسم رموز العلامات بالنسبة إلى الشاشة، ولن يؤدي تدوير الخريطة أو إمالتها أو تكبيرها أو تصغيرها إلى تغيير اتجاه العلامة. يمكنك ضبط اتجاه العلامة لتكون مسطّحة على الأرض. ستدور العلامات التي تم توجيهها بهذه الطريقة عند تدوير الخريطة، وستتغير زاوية النظر إليها عند إمالة الخريطة. ستحتفظ العلامات المسطّحة بحجمها عند تكبير الخريطة أو تصغيرها.
لتغيير اتجاه العلامة، اضبط السمة flat الخاصة بالعلامة على true.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .flat(true) )
جافا
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .flat(true));
تدوير علامة
يمكنك تدوير علامة حول نقطة الارتكاز باستخدام
Marker.طريقة setRotation() يتم قياس التدوير بالدرجات في اتجاه عقارب الساعة
من الموضع التلقائي. عندما يكون محدّد الموقع مسطّحًا على الخريطة، يكون الموضع التلقائي هو الشمال. عندما لا يكون العلامة مسطّحة، يكون الموضع التلقائي متّجهًا للأعلى، ويكون الدوران بحيث تكون العلامة متّجهة دائمًا نحو الكاميرا.
يعرض المثال أدناه كيفية تدوير العلامة بمقدار 90 درجة. يؤدي ضبط نقطة الارتكاز على 0.5,0.5 إلى تدوير العلامة حول مركزها بدلاً من قاعدتها.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .anchor(0.5f, 0.5f) .rotation(90.0f) )
جافا
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .anchor(0.5f,0.5f) .rotation(90.0f));
فهرس Z الخاص بالعلامة
تحدّد السمة z-index ترتيب التراص لهذا العلامة، مقارنةً بالعلامات الأخرى على الخريطة. يتم رسم علامة ذات فهرس z مرتفع فوق العلامات ذات فهارس z المنخفضة. القيمة التلقائية لـ z-index هي 0.
اضبط قيمة z-index في عنصر خيارات العلامة عن طريق استدعاء
MarkerOptions.zIndex()، كما هو موضّح في مقتطف الرمز البرمجي التالي:
Kotlin
map.addMarker( MarkerOptions() .position(LatLng(10.0, 10.0)) .title("Marker z1") .zIndex(1.0f) )
جافا
map.addMarker(new MarkerOptions() .position(new LatLng(10, 10)) .title("Marker z1") .zIndex(1.0f));
يمكنك الوصول إلى فهرس z الخاص بالعلامة من خلال استدعاء Marker.getZIndex()، ويمكنك تغييره من خلال استدعاء Marker.setZIndex().
يتم دائمًا رسم العلامات فوق طبقات المربّعات وغيرها من الإضافات التي لا تتضمّن علامات (الإضافات الأرضية، والخطوط المتعددة، والمضلّعات، والأشكال الأخرى) بغض النظر عن قيمة z-index الخاصة بالإضافات الأخرى. يتم اعتبار العلامات بشكل فعّال في مجموعة z-index منفصلة مقارنةً بالتراكبات الأخرى.
يمكنك الاطّلاع أدناه على تأثير z-index في أحداث النقر.
التعامل مع أحداث العلامات
تتيح لك واجهة برمجة التطبيقات Maps API الاستماع إلى أحداث العلامات والردّ عليها. للاستماع إلى هذه الأحداث، يجب ضبط أداة معالجة الأحداث المقابلة على عنصر GoogleMap الذي تنتمي إليه العلامات. عندما يقع الحدث على إحدى العلامات على الخريطة، سيتم استدعاء دالة رد الاتصال الخاصة بمعالج الحدث مع تمرير كائن Marker المقابل كمعلَمة. لمقارنة عنصر Marker هذا بمرجعك الخاص إلى عنصر Marker، يجب استخدام equals() وليس ==.
يمكنك الاستماع إلى الأحداث التالية:
الأحداث الناتجة عن النقر على العلامات
يمكنك استخدام OnMarkerClickListener للاستماع إلى أحداث النقر على العلامة. لضبط أداة معالجة الأحداث هذه على الخريطة، استخدِم الدالة
GoogleMap.setOnMarkerClickListener(OnMarkerClickListener). عندما ينقر المستخدم على علامة، سيتم استدعاء onMarkerClick(Marker) وسيتم تمرير العلامة كوسيطة. تعرض هذه الطريقة قيمة منطقية تشير إلى ما إذا كنت قد استهلكت الحدث (أي، ما إذا كنت تريد إلغاء السلوك التلقائي). إذا عرضت false، سيتم تنفيذ السلوك التلقائي بالإضافة إلى السلوك المخصّص. السلوك التلقائي لحدث النقر على علامة هو عرض نافذة المعلومات الخاصة بها (إذا كانت متاحة) وتحريك الكاميرا بحيث تكون العلامة في منتصف الخريطة.
تأثير z-index على أحداث النقر:
- عندما ينقر المستخدم على مجموعة من العلامات، يتم تشغيل حدث ناتج عن النقر للعلامة التي لديها أعلى قيمة z-index.
- يتمّ بدء حدث واحد على الأكثر لكلّ نقرة. بعبارة أخرى، لا يتم تمرير النقرة إلى العلامات أو التراكبات الأخرى التي تتضمّن قيم z-index أقل.
- يؤدي النقر على مجموعة من العلامات إلى تكرار النقر على المجموعة، واختيار كل علامة بالتسلسل. يتم ترتيب العناصر في الدورة حسب الأولوية، بدءًا من z-index، ثم حسب مدى قربها من نقطة النقر.
- إذا نقر المستخدم خارج نطاق المجموعة، تعيد واجهة برمجة التطبيقات احتساب المجموعة وتعيد ضبط حالة دورة النقر لتبدأ من البداية.
- يتم اعتبار العلامات بشكل فعّال في مجموعة z-index منفصلة مقارنةً بالتراكبات أو الأشكال الأخرى (الخطوط المتعددة والمضلّعات والدوائر و/أو التراكبات الأرضية)، بغض النظر عن z-index للتراكبات الأخرى. إذا تمّت إضافة عدّة علامات أو أشكال أو تراكبات بعضها فوق بعض، سيتمّ تكرار حدث ناتج عن النقر من خلال مجموعة العلامات أولاً.
أحداث سحب العلامات
يمكنك استخدام OnMarkerDragListener للاستماع إلى أحداث السحب على علامة. لضبط أداة معالجة الأحداث هذه على الخريطة، استخدِم الدالة
GoogleMap.setOnMarkerDragListener. لسحب علامة، على المستخدم الضغط مع الاستمرار على العلامة. عندما يرفع المستخدم إصبعه عن الشاشة، سيبقى المؤشر في هذا الموضع. عند سحب علامة، يتم استدعاء onMarkerDragStart(Marker) في البداية. أثناء سحب العلامة، يتم استدعاء onMarkerDrag(Marker) باستمرار. في نهاية عملية السحب، يتم استدعاء onMarkerDragEnd(Marker). يمكنك الحصول على موضع العلامة في أي وقت من خلال استدعاء Marker.getPosition().