المحدِّدات

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

خريطة تتضمّن عدّة علامات

تحدّد العلامات المواقع الجغرافية على الخريطة. يستخدم العلامة التلقائية رمزًا عاديًا، وهو شائع في مظهر "خرائط 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))
}

      

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

      

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

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

ربط البيانات بمحدّد موقع

يمكنك تخزين كائن بيانات عشوائي مع علامة باستخدام 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
    }
}

      

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

      

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

  • قد يوفّر تطبيقك أنواعًا مختلفة من العلامات، وتريد التعامل معها بشكل مختلف عندما ينقر عليها المستخدم. لإجراء ذلك، يمكنك تخزين 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)
)

      

Java

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.
مرئي
اضبط القيمة على false لإخفاء العلامة.
القيمة التلقائية هي true.
اتجاه اللوحة الإعلانية أو اللوحة المسطّحة
تستخدم العلامات تلقائيًا اتجاه اللوحة الإعلانية، ما يعني أنّه يتم رسمها بشكل موجّه نحو شاشة الجهاز بدلاً من سطح الخريطة. لا يؤدي تدوير الخريطة أو إمالتها أو تكبيرها/تصغيرها إلى تغيير اتجاه العلامة. يمكنك ضبط اتجاه العلامة ليكون مسطّحًا على الأرض. تدور العلامات المسطّحة عند تدوير الخريطة، وتتغير المنظور عند إمالة الخريطة. وكما هو الحال مع علامات اللوحات الإعلانية، تحتفظ العلامات المسطّحة بحجمها عند تكبير الخريطة أو تصغيرها.
تدوير
اتجاه العلامة، ويتم تحديده بالدرجات في اتجاه عقارب الساعة يتغير الموضع التلقائي إذا كانت العلامة مسطّحة. يكون الموضع التلقائي لعلامة مسطّحة محاذيًا للشمال. عندما لا يكون العلامة مسطّحة، يكون الموضع التلقائي متجهًا للأعلى ويكون الدوران بحيث تكون العلامة دائمًا مقابلة للكاميرا.

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

Kotlin

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

      

Java

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

      

Java

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

      

Java

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

      

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

      

تسطيح علامة

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

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

Kotlin

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

      

Java

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

      

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

      

فهرس 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)
)

      

Java

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

      

يمكنك الوصول إلى z-index الخاص بالعلامة عن طريق استدعاء 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().