Aggiungere una mappa 3D all'app

Seleziona la piattaforma: Android iOS JavaScript

Una mappa 3D che mostra New York

Questa pagina illustra un esempio di come aggiungere una mappa 3D di base a un'app per Android utilizzando Maps SDK 3D per Android. Le istruzioni riportate in questa pagina presuppongono che tu abbia già completato i passaggi descritti nella pagina di configurazione e che tu disponga di quanto segue:

  • Un progetto Google Cloud con Maps SDK 3D per Android abilitato
  • Una chiave API configurata per l'utilizzo con Maps SDK 3D per Android
  • Un progetto Android Studio configurato per l'utilizzo con Maps SDK 3D per Android

Per ulteriori informazioni su questi prerequisiti, consulta la sezione Configurazione.

Parte 1: aggiorna il file di layout (activity_main.xml) per aggiungere il componente Map3DView

Il componente Map3DView è la visualizzazione che esegue il rendering della mappa 3D all'interno dell'app. I passaggi seguenti aggiungono il componente e configurano lo stato iniziale della mappa, inclusa la posizione della videocamera e gli attributi correlati:

  1. Apri il file di layout dell'attività principale, che in genere si trova in app/src/main/res/layout/activity_main.xml.

  2. Nel ConstraintLayout root (o nell'elemento di layout root), aggiungi lo spazio dei nomi XML map3d:

    xmlns:map3d="http://schemas.android.com/apk/res-auto"
    
  3. Elimina il <TextView> predefinito che mostra "Hello World!".

  4. Aggiungi il componente Map3DView al layout. Puoi personalizzare la posizione della videocamera e altri attributi:

    <?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:mode="hybrid"
        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>
    

Parte 2: aggiorna MainActivity.kt

I passaggi seguenti inizializzano il componente Map3DView aggiunto al file activity_main.xml nella Parte 1 e gestiscono gli eventi del ciclo di vita dei componenti.

Tieni presente che Maps SDK 3D per Android supporta una sola istanza Map3DView attiva alla volta. La visualizzazione simultanea di più istanze Map3DView (ad es. nello stesso layout o in attività o frammenti visibili diversi) non è supportata e può causare problemi di rendering, ad esempio schermate nere nelle visualizzazioni secondarie.

Inoltre, tutti gli oggetti Map3DView condivideranno e rifletteranno lo stesso stato della mappa (ad es. posizione della videocamera, indicatori aggiunti, poligoni e così via), che persisterà anche se un oggetto Map3DView viene eliminato (utilizzando onDestroy) e ne viene creato un altro, a meno che non venga cancellato manualmente. Ad esempio, se aggiungi indicatori a Map3DView1, poi lo elimini e crei Map3DView2, gli stessi indicatori saranno comunque presenti in Map3DView2.

Responsabilità dello sviluppatore:

  • Una visualizzazione alla volta: assicurati che in un determinato momento sia presente un solo oggetto Map3DView in una parte attiva della gerarchia di oggetti View.
  • Pulizia manuale: quando passi da un oggetto Map3DView (ad es. Map3DView1) a un altro (ad es. Map3DView2), devi chiamare onDestroy() sulla vecchia istanza (Map3DView1). Poiché lo stato della mappa sottostante è condiviso, per assicurarti che Map3DView2 inizi con uno stato nuovo o specifico, devi cancellare manualmente qualsiasi stato impostato da Map3DView1. Ciò include la rimozione di indicatori, overlay e così via e la reimpostazione della posizione della videocamera utilizzando l'oggetto GoogleMap3D ottenuto in OnMap3DViewReadyCallback.
  1. Apri il file MainActivity.kt, che in genere si trova in app/src/main/java/com/example/yourpackagename/MainActivity.kt.

  2. Aggiungi le importazioni necessarie per Maps SDK 3D per 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. Modifica la classe MainActivity per implementare OnMap3DViewReadyCallback:

    class MainActivity : AppCompatActivity(), OnMap3DViewReadyCallback {
    
  4. Dichiara le variabili per Map3DView e GoogleMap3D:

    private lateinit var map3DView: Map3DView
    private var googleMap3D: GoogleMap3D? = null
    
  5. Nel metodo onCreate, dopo setContentView(...) e il blocco ViewCompat.setOnApplyWindowInsetsListener, inizializza map3DView, chiama il metodo del ciclo di vita onCreate e richiedi la mappa in modo asincrono:

    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. Esegui l'override dei metodi onMap3DViewReady e onError. Questi callback vengono attivati quando la mappa è pronta per essere utilizzata o quando si verifica un errore durante l'inizializzazione:

    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 { ... })
    }
    
    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. Inoltra gli eventi del ciclo di vita dall'attività a Map3DView aggiungendo i seguenti override a 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()
    }
    

Parte 3: sincronizza Gradle ed esegui

Ora che hai aggiornato il layout e l'attività dell'app, puoi creare ed eseguire l'app per visualizzare la visualizzazione della mappa 3D.

  1. Per sincronizzare il progetto con Gradle, seleziona File > Sincronizza progetto con file Gradle.

  2. Per creare ed eseguire l'app su un emulatore o un dispositivo fisico, seleziona Esegui > Esegui.

Se tutto è configurato correttamente, dovresti vedere una mappa 3D visualizzata nell'app, centrata vicino alle coordinate specificate in activity_main.xml.

Stati di caricamento della mappa ed errore

Maps SDK 3D per Android visualizza automaticamente un feedback visivo integrato durante la gestione dello stato della mappa:

  • Overlay di caricamento: viene visualizzato un indicatore di avanzamento centrato quando la visualizzazione della mappa viene inizializzata per la prima volta o quando viene caricata la finestra iniziale.
  • Overlay di errore: viene visualizzata una scheda di errore con stile se si verifica un errore grave, ad esempio una chiave API non valida, un errore di rete o quando l'app viene eseguita su un dispositivo non supportato.

Puoi acquisire questi errori di inizializzazione o di caricamento a livello di programmazione eseguendo l'override di onError(error: Exception) all'interno dell' OnMap3DViewReadyCallback implementazione.

Ascolta gli eventi di clic sulla mappa

Per ascoltare gli eventi di clic sulla mappa, utilizza GoogleMap3D.setMap3DClickListener. Questo listener viene attivato quando un utente fa clic sulla mappa e fornisce la posizione e l'ID del luogo del punto su cui è stato fatto clic.

L'esempio seguente mostra come impostare un listener di clic sulla mappa:

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

Tieni presente che il gestore di clic non viene eseguito nel thread principale (o dell'interfaccia utente). Se vuoi apportare modifiche all'interfaccia utente (ad esempio mostrare un messaggio Toast), devi passare al thread principale. Per Kotlin, puoi farlo utilizzando lifecycleScope.launch(Dispatchers.Main).

Passaggi successivi

Ora che hai aggiunto una mappa 3D di base alla tua app, puoi esplorare funzionalità avanzate di Maps SDK 3D per Android, come animazioni del percorso della videocamera, indicatori 3D o poligoni.