إضافة خريطة ثلاثية الأبعاد إلى تطبيقك

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

خريطة ثلاثية الأبعاد تعرض مدينة نيويورك

توضّح هذه الصفحة مثالاً على كيفية إضافة خريطة ثلاثية الأبعاد أساسية إلى تطبيق Android باستخدام حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" الثلاثية الأبعاد لأجهزة Android. تفترض التعليمات الواردة في هذه الصفحة أنّك أكملت الخطوات الواردة في صفحة الإعداد وأنّ لديك ما يلي:

  • مشروع على Google Cloud تم تفعيل حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" الثلاثية الأبعاد لأجهزة Android فيه
  • مفتاح واجهة برمجة تطبيقات تم إعداده لاستخدامه مع حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" الثلاثية الأبعاد لأجهزة Android
  • مشروع في "استوديو Android" تم إعداده لاستخدامه مع حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" الثلاثية الأبعاد لأجهزة Android

لمزيد من المعلومات حول هذه المتطلبات الأساسية، يُرجى الاطّلاع على صفحة الإعداد.

الجزء 1: تعديل ملف التنسيق (activity_main.xml) لإضافة مكوّن Map3DView

مكوّن Map3DView هو طريقة العرض التي تعرض الخريطة الثلاثية الأبعاد داخل التطبيق. تضيف الخطوات التالية المكوّن وتضبط الحالة الأولية للخريطة، بما في ذلك موضع الكاميرا والسمات ذات الصلة:

  1. افتح ملف تنسيق النشاط الرئيسي، الذي يكون عادةً في app/src/main/res/layout/activity_main.xml.

  2. في العنصر الجذري ConstraintLayout (أو عنصر التنسيق الجذري)، أضِف مساحة الاسم map3d بتنسيق XML:

    xmlns:map3d="http://schemas.android.com/apk/res-auto"
    
  3. احذف العنصر <TextView> التلقائي الذي يعرض "Hello World!".

  4. أضِف مكوّن Map3DView إلى التنسيق. يمكنك تخصيص موضع الكاميرا والسمات الأخرى:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:map3d="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/main"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:context=".MainActivity">
    
      <com.google.android.gms.maps3d.Map3DView
        android:id="@+id/map3dView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        map3d:mode="hybrid"
        map3d:centerLat="38.544012"
        map3d:centerLng="-107.670428"
        map3d:centerAlt="2427.6"
        map3d:heading="310"
        map3d:tilt="63"
        map3d:range="8266"
        map3d:roll="0"
        map3d:minAltitude="0"
        map3d:maxAltitude="1000000"
        map3d:minHeading="0"
        map3d:maxHeading="360"
        map3d:minTilt="0"
        map3d:maxTilt="90"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

الجزء 2: تعديل ملف MainActivity.kt

توضّح الخطوات التالية كيفية تهيئة مكوّن Map3DView الذي تمّت إضافته إلى ملف activity_main.xml في الجزء 1 وإدارة أحداث دورة حياة المكوّن.

يُرجى العِلم أنّ حزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" الثلاثية الأبعاد لأجهزة Android لا تتيح سوى مثيل Map3DView نشط واحد في كل مرة. لا يُسمح بعرض عدّة مثيلات من Map3DView في الوقت نفسه (على سبيل المثال، في التنسيق نفسه أو في أنشطة أو أجزاء مرئية مختلفة)، وقد يؤدي ذلك إلى مشاكل في العرض، مثل ظهور شاشات سوداء في طرق العرض الثانوية.

علاوةً على ذلك، ستتشارك جميع مثيلات Map3DView حالة الخريطة نفسها وتعرضها (على سبيل المثال، موضع الكاميرا والعلامات المضافة والمضلّعات وما إلى ذلك)، وستظل هذه الحالة محفوظة حتى إذا تم تدمير أحد مثيلات Map3DView (باستخدام onDestroy) وإنشاء مثيل آخر، ما لم تتم إزالة الحالة يدويًا. على سبيل المثال، إذا أضفت علامات إلى Map3DView1، ثمّ دمّرتها وأنشأت Map3DView2، ستظلّ هذه العلامات نفسها ظاهرة على Map3DView2.

مسؤوليات المطوّر:

  • عرض واحد في كل مرة: تأكَّد من أنّ هناك مثيلاً واحدًا فقط من Map3DView في جزء نشط من هيكلية طرق العرض في أيّ لحظة.
  • التنظيف اليدوي: عند الانتقال من مثيل Map3DView (مثل Map3DView1) إلى آخر (مثل Map3DView2)، عليك استدعاء onDestroy() على المثيل القديم (Map3DView1). بما أنّ حالة الخريطة الأساسية مشترَكة، لضمان بدء Map3DView2 بحالة جديدة أو محدّدة، عليك إزالة أيّ حالة تم ضبطها من قِبل Map3DView1 يدويًا. ويشمل ذلك إزالة العلامات والتراكبات وما إلى ذلك، وإعادة ضبط موضع الكاميرا باستخدام عنصر GoogleMap3D الذي تم الحصول عليه في OnMap3DViewReadyCallback.
  1. افتح ملف MainActivity.kt، الذي يكون عادةً في app/src/main/java/com/example/yourpackagename/MainActivity.kt.

  2. أضِف عمليات الاستيراد اللازمة لحزمة تطوير البرامج بالاستناد إلى بيانات "خرائط Google" الثلاثية الأبعاد لأجهزة Android:

    import com.google.android.gms.maps3d.GoogleMap3D
    import com.google.android.gms.maps3d.Map3DView
    import com.google.android.gms.maps3d.OnMap3DViewReadyCallback
    
  3. عدِّل فئة MainActivity لتنفيذ OnMap3DViewReadyCallback:

    class MainActivity : AppCompatActivity(), OnMap3DViewReadyCallback {
    
  4. اعلن عن متغيّرات لـ Map3DView وGoogleMap3D:

    private lateinit var map3DView: Map3DView
    private var googleMap3D: GoogleMap3D? = null
    
  5. في طريقة onCreate، بعد setContentView(...) وكتلة ViewCompat.setOnApplyWindowInsetsListener، ابدأ map3DView، واستدعِ طريقة دورة الحياة onCreate، واطلب الخريطة بشكل غير متزامن:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    
        map3DView = findViewById(R.id.map3dView)
        map3DView.onCreate(savedInstanceState)
        map3DView.getMap3DViewAsync(this)
    }
    
  6. ألغِ طريقة onMap3DViewReady. يتم تفعيل معاودة الاتصال هذه عندما تكون الخريطة جاهزة للاستخدام:

    override fun onMap3DViewReady(googleMap3D: GoogleMap3D) {
        // Interact with the googleMap3D object here
        this.googleMap3D = googleMap3D
        // You can now make calls to the googleMap3D object, e.g.,
        // googleMap3D.cameraController.flyTo(camera { ... })
    }
    
  7. أرسِل أحداث دورة الحياة من النشاط إلى Map3DView عن طريق إضافة عمليات الإلغاء التالية إلى MainActivity:

    override fun onStart() {
        super.onStart()
        map3DView.onStart()
    }
    
    override fun onResume() {
        super.onResume()
        map3DView.onResume()
    }
    
    override fun onPause() {
        map3DView.onPause()
        super.onPause()
    }
    
    override fun onStop() {
        map3DView.onStop()
        super.onStop()
    }
    
    override fun onDestroy() {
        map3DView.onDestroy()
        super.onDestroy()
    }
    
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        map3DView.onSaveInstanceState(outState)
    }
    
    override fun onLowMemory() {
        super.onLowMemory()
        map3DView.onLowMemory()
    }
    

الجزء 3: مزامنة Gradle وتشغيل التطبيق

بعد تعديل تنسيق التطبيق والنشاط، يمكنك إنشاء التطبيق وتشغيله للاطّلاع على طريقة عرض الخريطة الثلاثية الأبعاد.

  1. لمزامنة مشروعك مع Gradle، انقر على ملف > مزامنة المشروع مع ملفات Gradle.

  2. لإنشاء تطبيقك وتشغيله على محاكي أو جهاز فعلي، انقر على تشغيل > تشغيل.

إذا تم ضبط كل شيء بشكلٍ صحيح، من المفترض أن تظهر خريطة ثلاثية الأبعاد في تطبيقك، متوسّطة بالقرب من الإحداثيات المحدّدة في activity_main.xml.

الخطوات التالية

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

الاستماع إلى أحداث النقر على الخريطة

للاستماع إلى أحداث النقر على الخريطة، استخدِم GoogleMap3D.setMap3DClickListener. يتم تفعيل أداة الاستماع هذه عندما ينقر أحد المستخدِمين على الخريطة، وتوفّر الموقع الجغرافي والمعرّف الجغرافي للنقطة التي تم النقر عليها.

يوضّح المثال التالي كيفية ضبط متتبِّع النقرات على الخريطة:

googleMap3D.setMap3DClickListener { location, placeId ->
    lifecycleScope.launch(Dispatchers.Main) {
        if (placeId != null) {
            Toast.makeText(this@MainActivity, "Clicked on place with ID: $placeId", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this@MainActivity, "Clicked on location: $location", Toast.LENGTH_SHORT).show()
        }
    }
}

يُرجى العِلم أنّ معالج النقرات لا يتم تشغيله على سلسلة التعليمات الرئيسية (أو سلسلة تعليمات واجهة المستخدم). إذا أردت إجراء تغييرات على واجهة المستخدم (مثل عرض رسالة Toast)، عليك الانتقال إلى سلسلة التعليمات الرئيسية. بالنسبة إلى Kotlin، يمكنك إجراء ذلك باستخدام lifecycleScope.launch(Dispatchers.Main).