Markers

اختيار نظام أساسي: Android iOS JavaScript

تشير محدّدات المواقع إلى مواقع فردية على الخريطة. يمكنك تخصيص علاماتك عن طريق تغيير اللون الافتراضي أو استبدال رمز العلامة بصورة مخصصة. يمكن أن توفر نوافذ المعلومات سياقًا إضافيًا للعلامة.

عيّنات تعليمات برمجية

يتضمن مستودع ApiDemos على GitHub نموذجًا يعرض ميزات مختلفة للعلامة:

Java

كوتلين

المقدمة

تحدد محدّدات المواقع المواقع على الخريطة. تستخدم العلامة الافتراضية رمزًا قياسيًا، شائعًا على شكل وأسلوب خرائط Google. من الممكن تغيير لون الرمز أو صورته أو نقطة الارتساء عبر واجهة برمجة التطبيقات. العلامات هي عناصر من النوع Marker، وتتم إضافتها إلى الخريطة باستخدام طريقة GoogleMap.addMarker(markerOptions).

تم تصميم المحددات بحيث تكون تفاعلية. فهي تتلقى أحداث click بشكل تلقائي، وغالبًا ما تُستخدم مع أدوات معالجة الأحداث لإظهار نوافذ المعلومات. يؤدي ضبط سمة draggable للعلامة على true إلى السماح للمستخدم بتغيير موضع العلامة. استخدم الضغط مع الاستمرار لتفعيل إمكانية تحريك العلامة.

بشكلٍ تلقائي، عندما ينقر المستخدم على محدّد موقع، يظهر شريط أدوات الخريطة في أسفل يسار الخريطة، ما يمنح المستخدم إمكانية الوصول السريع إلى تطبيق "خرائط Google" المتوافق مع الأجهزة الجوّالة. ويمكنك إيقاف شريط الأدوات. لمزيد من المعلومات، راجع دليل عناصر التحكم.

الخطوات الأولى لاستخدام العلامات

تغطي هذه الحلقة من Maps Live أساسيات إضافة علامات إلى خريطتك باستخدام SDK للخرائط في Android.

إضافة علامة

يوضح المثال التالي كيفية إضافة محدّد موقع إلى خريطة. يتم إنشاء العلامة على الإحداثيات -33.852,151.211 (سيدني، أستراليا)، وتعرض السلسلة النصية "ماركر في سيدني" في نافذة المعلومات عند النقر عليها.

لغة Java


@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));
}

      

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))
}

      

عرض معلومات إضافية عن المحدد

من المتطلبات الشائعة عرض معلومات إضافية عن المكان أو الموقع عندما ينقر المستخدم على علامة على الخريطة. راجع دليل نوافذ المعلومات.

ربط البيانات بأحد المحدِّدات

يمكنك تخزين عنصر بيانات عشوائي باستخدام علامة باستخدام Marker.setTag() واسترداد عنصر البيانات باستخدام Marker.getTag(). يوضح النموذج التالي كيف يمكنك حساب عدد مرات النقر على علامة باستخدام العلامات:

لغة Java


/**
 * 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;
    }
}

      

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
    }
}

      

في ما يلي بعض الأمثلة على سيناريوهات عندما يكون من المفيد تخزين البيانات واستردادها باستخدام محدّدات المواقع:

  • قد يلبي تطبيقك أنواعًا مختلفة من العلامات، وترغب في التعامل معها بشكل مختلف عند نقر المستخدم عليها. لتحقيق ذلك، يمكنك تخزين String مع العلامة التي تشير إلى النوع.
  • قد تكون تواجه نظامًا له معرّفات سجل فريدة، حيث تمثل محددات السجلات سجلات محددة في هذا النظام.
  • قد تشير بيانات العلامة إلى الأولوية التي سيتم استخدامها عند تحديد فهرس z للعلامة.

جعل أداة السحب قابلة للسحب

يمكنك إعادة ضبط موضع محدّد الموقع بعد إضافته إلى الخريطة طالما تم ضبط السمة draggable على true. اضغط مع الاستمرار على المحدد لتمكين السحب. عند رفع إصبعك عن الشاشة، ستظل العلامة في ذلك الموضع.

لا يمكن سحب المحددات افتراضيًا. يجب تعيين محدّد الموقع بشكل واضح ليكون قابلاً للسحب إما مع MarkerOptions.draggable(boolean) قبل إضافته إلى الخريطة، أو Marker.setDraggable(boolean) بعد إضافته إلى الخريطة. يمكنك الاستماع إلى أحداث السحب على العلامة، كما هو موضح في أحداث سحب العلامة.

يضيف المقتطف أدناه علامة قابلة للسحب في بيرث، أستراليا.

لغة Java


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .draggable(true));

      

Kotlin


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .draggable(true)
)

      

تخصيص علامة

يعرض هذا الفيديو طرقًا لاستخدام العلامات لوضع تمثيلات بصرية للمواقع على الخريطة.

يمكن أن تحدد العلامات صورة مخصصة لتظهر بدلاً من الرمز الافتراضي. يتضمن تعريف الرمز تعيين عدد من الخصائص التي تؤثر في السلوك المرئي للعلامة.

تتيح العلامات إمكانية التخصيص من خلال الخصائص التالية:

الموضع (مطلوب)
قيمة LatLng لموضع العلامة على الخريطة. هذه هي السمة المطلوبة الوحيدة لكائن Marker.
مرساة
النقطة على الصورة التي سيتم وضعها في موضع خط الطول والعرض. يتم تعيين هذا الإعداد بشكل افتراضي على منتصف الجزء السفلي من الصورة.
إصدار أولي
يضبط تعتيم العلامة. الإعداد التلقائي هو 1.0.
العنوان
سلسلة يتم عرضها في نافذة المعلومات عندما ينقر المستخدم على العلامة.
المقتطف
النص الإضافي الذي يتم عرضه أسفل العنوان.
الرمز
صورة نقطية يتم عرضها بدلاً من صورة العلامة التلقائية
قابل للسحب
يمكنك التعيين إلى true إذا كنت تريد السماح للمستخدم بنقل العلامة. ضبط القيمة التلقائية على false.
مرئي
يمكنك التعيين إلى false لجعل العلامة غير مرئية. ضبط القيمة التلقائية على true.
اتجاه مسطح أو لوحة إعلانات
تستخدم محدّدات المواقع تلقائيًا اتجاه لوحة الإعلانات، ما يعني أنها مرسومة على شاشة الجهاز بدلاً من سطح الخريطة. لا يؤدي تدوير الخريطة أو إمالتها أو تكبيرها/تصغيرها إلى تغيير اتجاه العلامة. يمكنك تعيين اتجاه محدد بحيث يكون مسطحًا على الأرض. يتم تدوير العلامات المسطحة عند تدوير الخريطة، وتغيير المنظور عند إمالة الخريطة. كما هو الحال مع محدّدات المواقع للوحة الإعلانات، تحتفظ محدّدات المواقع المحدّدة بحجمها عند تكبير الخريطة أو تصغيرها.
تدوير
اتجاه العلامة، محدد بالدرجات في اتجاه عقارب الساعة. يتغير الموضع الافتراضي إذا كانت العلامة مسطحة. يكون الموضع الافتراضي للعلامة المسطحة بمحاذاة الشمال. عندما لا تكون العلامة مسطّحة، يشير الموضع التلقائي إلى الأعلى ويكون الدوران في مواجهة العلامة دائمًا.

ينشئ المقتطف أدناه علامة بسيطة، بالإضافة إلى الرمز الافتراضي.

لغة Java


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation));

      

Kotlin


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
)

      

تخصيص لون العلامة

يمكن تخصيص لون صورة العلامة التلقائية من خلال تمرير كائن BitmapDescriptor إلى طريقة icon(). يمكنك استخدام مجموعة من الألوان المحدّدة مسبقًا في الكائن BitmapDescriptorFactory، أو ضبط لون محدّد مخصّص باستخدام طريقة BitmapDescriptorFactory.defaultMarker(float hue). التدرج هو قيمة بين 0 و360، تمثل النقاط على عجلة الألوان.

لغة Java


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));

      

Kotlin


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
)

      

تخصيص تعتيم العلامة

يمكنك التحكم في مدى تعتيم محدّد الموقع باستخدام طريقةMarkOptions.alpha(). يجب تحديد ألفا على شكل عائم بين 0.0 و1.0، حيث تكون القيمة 0 شفافة تمامًا والرقم 1 غير معتم بالكامل.

لغة Java


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(new MarkerOptions()
    .position(melbourneLocation)
    .alpha(0.7f));

      

Kotlin


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .alpha(0.7f)
)

      

تخصيص صورة العلامة

يمكنك استبدال صورة العلامة الافتراضية بصورة علامة مخصصة، والتي يُطلق عليها غالبًا اسم الرمز. يتم دائمًا ضبط الرموز المخصّصة على أنها BitmapDescriptor، ويتم تحديدها باستخدام إحدى الطرق في فئة BitmapDescriptorFactory.

fromAsset(String assetName)
إنشاء علامة مخصصة باستخدام اسم صورة نقطية في دليل مواد العرض.
fromBitmap(Bitmap image)
إنشاء علامة مخصصة من صورة نقطية.
fromFile(String fileName)
ينشئ رمزًا مخصصًا باستخدام اسم ملف صورة نقطية في وحدة التخزين الداخلية.
fromPath(String absolutePath)
إنشاء علامة مخصصة من مسار الملف المطلق لصورة نقطية.
fromResource(int resourceId)
إنشاء علامة مخصصة باستخدام رقم تعريف المورد لصورة نقطية.

ينشئ المقتطف أدناه علامة برمز مخصص.

لغة Java


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)));

      

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))
)

      

ضبط محدّد

يتم عادةً رسم رموز العلامة بالنسبة إلى الشاشة؛ ولن يؤدي تدوير الخريطة أو إمالةها أو تكبيرها أو تصغيرها إلى تغيير اتجاه العلامة. يمكنك تعيين اتجاه العلامة بحيث يكون مسطحًا على الأرض. سيتم تدوير العلامات التي يتم توجيهها بهذه الطريقة عند تدوير الخريطة، وسيتم تغيير المنظور عند إمالة الخريطة. ستحتفظ محددات المواقع بحجمها عندما يتم تكبير الخريطة أو تصغيرها.

لتغيير اتجاه العلامة، اضبط سمة flat للعلامة على true.

لغة Java


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .flat(true));

      

Kotlin


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .flat(true)
)

      

تدوير العلامة

يمكنك تدوير محدّد موقع حول نقطة الارتساء باستخدام Marker.طريقة واحدة (setRotation()). يتم قياس التدوير بالدرجات في اتجاه عقارب الساعة من الموضع الافتراضي. عندما تكون العلامة مسطحة على الخريطة، يكون الموضع الافتراضي هو الشمال. عندما لا تكون العلامة مسطحة، يكون الموضع الافتراضي يشير لأعلى ويكون التدوير هو أن العلامة تواجه الكاميرا دائمًا.

يؤدي المثال التالي إلى تدوير العلامة 90°. يؤدي تعيين نقطة الارتساء إلى 0.5,0.5 إلى تدوير العلامة حول مركزها بدلاً من قاعدتها.

لغة Java


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));

      

Kotlin


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .anchor(0.5f, 0.5f)
        .rotation(90.0f)
)

      

مؤشر العلامة z

يحدد مؤشر z ترتيب تكديس هذه العلامة، بالنسبة إلى العلامات الأخرى على الخريطة. يتم رسم محدّد ذي مؤشر z مرتفع فوق علامات تحدّد مؤشرات z منخفضة. القيمة التلقائية لفهرس z هي 0.

اضبط مؤشر z على كائن خيارات العلامة من خلال استدعاء MarkerOptions.zIndex()، كما هو موضّح في مقتطف الرمز التالي:

لغة Java


map.addMarker(new MarkerOptions()
    .position(new LatLng(10, 10))
    .title("Marker z1")
    .zIndex(1.0f));

      

Kotlin


map.addMarker(
    MarkerOptions()
        .position(LatLng(10.0, 10.0))
        .title("Marker z1")
        .zIndex(1.0f)
)

      

يمكنك الدخول إلى مؤشر z للعلامة عن طريق الاتصال بـ Marker.getZIndex()، ويمكنك تغييره من خلال الاتصال بـ Marker.setZIndex().

دائمًا ما يتم رسم العلامات فوق طبقات المربعات والتراكبات الأخرى غير المحددة (تراكبات الأرض والخطوط المتعددة والمضلعات والأشكال الأخرى) بغض النظر عن فهرس z للتراكبات الأخرى. ويتم اعتبار المحددات فعليًا في مجموعة فهرسة z منفصلة عن التراكبات الأخرى.

تعرَّف على المزيد من المعلومات عن تأثير مؤشر z على أحداث النقر أدناه.

التعامل مع أحداث محدِّد الموقع

تسمح لك واجهة برمجة تطبيقات الخرائط بالاستماع إلى أحداث العلامة والرد عليها. للاستماع إلى هذه الأحداث، يجب ضبط أداة الاستجابة المقابلة على العنصر GoogleMap الذي تشير إليه العلامات. عند وقوع الحدث على أحد العلامات على الخريطة، سيتم استدعاء استدعاء المستمع من خلال الكائن Marker المقابل الذي يتم تمريره كمعلّمة. لمقارنة هذا الكائن Marker بمرجعك الخاص بكائن Marker، عليك استخدام equals() وليس ==.

يمكنك الاستماع إلى الأحداث التالية:

أحداث النقر بالمحدِّد

يمكنك استخدام OnMarkerClickListener للاستماع إلى أحداث النقر على العلامة. لضبط أداة معالجة البيانات هذه على الخريطة، يمكنك الاتصال بالرقم GoogleMap.setOnMarkerClickListener(OnMarkerClickListener). عندما ينقر المستخدم على إحدى العلامات، سيتم استدعاء onMarkerClick(Marker) ويتم تمرير العلامة كوسيطة. تعرض هذه الطريقة قيمة منطقية تشير إلى ما إذا كنت قد استهلكت الحدث (أي تريد إيقاف السلوك التلقائي). وإذا عرضت القيمة false، سيحدث السلوك التلقائي بالإضافة إلى السلوك المخصّص. يتمثل السلوك الافتراضي لحدث النقر على العلامة في عرض نافذة المعلومات (إذا كانت متاحة) وتحريك الكاميرا بحيث يتم توسيط العلامة على الخريطة.

تأثير مؤشر z على أحداث النقر:

  • عندما ينقر المستخدم على مجموعة من العلامات، يتم تشغيل حدث النقر للعلامة ذات أعلى مؤشر z.
  • يتم تشغيل حدث واحد على الأكثر لكل نقرة. بمعنى آخر، لا يتم تمرير النقرة إلى العلامات أو التراكبات الأخرى ذات قيم مؤشر z المنخفضة.
  • يؤدي النقر على مجموعة من العلامات إلى حدوث نقرات متتالية للتنقل عبر المجموعة، مع تحديد كل منها على حدة. يمنح ترتيب الدورة الأولوية على Z-index، ثم يقترب من نقطة النقر.
  • إذا نقر المستخدم خارج نطاق المجموعة، فستعيد واجهة برمجة التطبيقات حساب المجموعة وتعيد تعيين حالة دورة النقر بحيث تبدأ من البداية.
  • يقع حدث النقر خلال مجموعات العلامات إلى أشكال وتراكبات أخرى قبل إعادة تشغيل الدورة.
  • ويتم اعتبار العلامات بشكل فعلي في مجموعة فهرسة z منفصلة عن الأشكال أو التراكبات الأخرى (الخطوط المتعددة و/أو المضلعات والدوائر و/أو التراكبات الأرضية)، بغض النظر عن فهرس z للتراكبات الأخرى. في حالة تراكب العديد من المحددات أو التراكبات أو الأشكال فوق بعضها البعض، يتم تدوير حدث النقر عبر مجموعة العلامات أولاً، ثم يتم تشغيله للتراكبات أو الأشكال الأخرى القابلة للنقر، بناءً على قيم مؤشر z.

أحداث سحب محدِّد الموقع

يمكنك استخدام OnMarkerDragListener للاستماع إلى الأحداث التي يتم سحبها على محدّد موقع. لضبط أداة معالجة البيانات هذه على الخريطة، يمكنك الاتصال بالرقم GoogleMap.setOnMarkerDragListener. لسحب محدّد موقع، يجب على المستخدم الضغط مع الاستمرار عليه. عندما يرفع المستخدم إصبعه من على الشاشة، ستظل العلامة في هذا الموضع. عندما يتم سحب محدد الموقع، يتم استدعاء onMarkerDragStart(Marker) في البداية. أثناء سحب العلامة، يتم استدعاء onMarkerDrag(Marker) باستمرار. في نهاية السحب يتم استدعاء onMarkerDragEnd(Marker). يمكنك الحصول على موضع محدّد الموقع في أي وقت عن طريق الاتصال بـ Marker.getPosition().