הוספת מפה תלת-ממדית לאפליקציה

בחירת פלטפורמה: Android iOS JavaScript

מפה תלת-ממדית שמציגה את העיר ניו יורק

בדף הזה מוסבר איך להוסיף מפת תלת-ממד בסיסית לאפליקציית Android באמצעות Maps 3D SDK ל-Android. ההוראות בדף הזה מבוססות על ההנחה שכבר ביצעתם את השלבים בדף הגדרה, ושיש לכם:

  • פרויקט ב-Google Cloud עם Maps 3D SDK ל-Android מופעל
  • מפתח API שהוגדר לשימוש עם Maps 3D SDK ל-Android
  • פרויקט Android Studio שהוגדר לשימוש עם Maps 3D SDK ל-Android

למידע נוסף על הדרישות המוקדמות האלה, ראו הגדרה.

חלק 1: עדכון קובץ הפריסה (activity_main.xml) כדי להוסיף את הרכיב Map3DView

הרכיב Map3DView הוא התצוגה שמעבדת את המפה התלת-ממדית באפליקציה. בשלבים הבאים מוסיפים את הרכיב ומגדירים את המצב הראשוני של המפה, כולל מיקום המצלמה והמאפיינים הקשורים:

  1. פותחים את קובץ הפריסה של הפעילות הראשית, שבדרך כלל נמצא במיקום app/src/main/res/layout/activity_main.xml.

  2. ב-root ConstraintLayout (או ברכיב פריסת הבסיס), מוסיפים את מרחב השמות של ה-XML:‏ map3d

    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:mapMode="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, ומנהלים את האירועים במחזור החיים של הרכיב.

חשוב לזכור ש-Maps 3D SDK ל-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. מוסיפים את הייבוא הנדרש ל-Maps 3D SDK ל-Android:

    import android.util.Log
    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 ו-onError. הקריאות החוזרות האלה מופעלות כשהמפה מוכנה לשימוש, או כשמתרחשת שגיאה במהלך האתחול:

    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.flyTo(camera { ... })
    }
    
    override fun onError(error: Exception) {
        // Handle the error gracefully here (for example, show an error dialog or log the error).
        Log.e("MainActivity", "Error loading 3D map", error)
    }
    
  7. כדי להעביר אירועים במחזור חיים מה-Activity אל 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, בוחרים באפשרות File > Sync Project with Gradle Files (קובץ > סנכרון הפרויקט עם קובצי Gradle).

  2. כדי ליצור ולהריץ את האפליקציה באמולטור או במכשיר פיזי, לוחצים על Run > Run.

אם הכול מוגדר כמו שצריך, אמורה להופיע באפליקציה מפה תלת-ממדית, שמרכזה קרוב לקואורדינטות שצוינו ב-activity_main.xml.

מצבי טעינה ושגיאה של המפה

‫Maps 3D SDK ל-Android מציג באופן אוטומטי משוב חזותי מובנה בזמן ניהול מצב המפה:

  • שכבת-על של טעינה: אינדיקטור התקדמות ממורכז מוצג כשתצוגת המפה מאותחלת בפעם הראשונה או כשהיא טוענת את אזור התצוגה הראשוני שלה.
  • שכבת-על של שגיאה: כרטיס שגיאה מעוצב מוצג אם מתרחשת תקלה קריטית, כמו מפתח API לא חוקי, שגיאה בחיבור לרשת או הפעלה במכשיר לא נתמך.

כדי לתעד את שגיאות האתחול או הטעינה האלה באופן פרוגרמטי, צריך לשנות את onError(error: Exception) בהטמעה של OnMap3DViewReadyCallback.

האזנה לאירועים מסוג קליק במפה

כדי להאזין לאירועים מסוג קליק במפה, צריך להפעיל את setMap3DClickListener ב- GoogleMap3D. כשמשתמש לוחץ על המפה, פונקציית ה-callback‏ onMap3DClick מקבלת אובייקט Map3DClickEvent שמספק את הערכים location ו-placeId של הנקודה שנלחצה, ומחזירה ערך Boolean (true כדי להסתיר את ווידג'ט ממשק המשתמש של Places שמוגדר כברירת מחדל, או false כדי להציג אותו). מידע נוסף זמין במאמר אינטראקציה עם נקודות עניין.

בדוגמה הבאה מוסבר איך להגדיר רכיב click listener במפה:

googleMap3D.setMap3DClickListener { event: Map3DClickEvent ->
    Log.d(
        "MainActivity",
        "Clicked at ${event.location}, placeId: ${event.placeId}"
    )
    false
}

השלבים הבאים

עכשיו, אחרי שהוספתם מפה תלת-ממדית בסיסית לאפליקציה, אתם יכולים לנסות תכונות מתקדמות יותר של Maps 3D SDK ל-Android, כמו אנימציות של נתיב המצלמה, סמנים תלת-ממדיים או פוליגונים.