Adicionar um mapa 3D ao seu app

Selecione a plataforma: Android iOS JavaScript

Um mapa 3D mostrando a cidade de Nova York

Nesta página, mostramos um exemplo de como adicionar um mapa 3D básico a um app Android usando o SDK do Maps 3D para Android. As instruções nesta página pressupõem que você já concluiu as etapas na página Configuração e tem o seguinte:

  • Um projeto na nuvem do Google Cloud com o SDK do Maps 3D para Android ativado.
  • Uma chave de API configurada para uso com o SDK do Maps 3D para Android.
  • Um projeto do Android Studio configurado para uso com o SDK do Maps 3D para Android.

Para mais informações sobre esses pré-requisitos, consulte Configuração.

Parte 1: atualizar o arquivo de layout (activity_main.xml) para adicionar o componente Map3DView

O componente Map3DView é a visualização que renderiza o mapa 3D no app. As etapas a seguir adicionam o componente e configuram o estado inicial do mapa, incluindo a posição da câmera e os atributos relacionados:

  1. Abra o arquivo de layout da atividade principal, que geralmente está localizado em app/src/main/res/layout/activity_main.xml.

  2. No ConstraintLayout raiz (ou no elemento de layout raiz), adicione o namespace XML map3d:

    xmlns:map3d="http://schemas.android.com/apk/res-auto"
    
  3. Exclua o <TextView> padrão que mostra "Hello World!".

  4. Adicione o componente Map3DView ao layout. É possível personalizar a posição da câmera e outros atributos:

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

Parte 2: atualizar o arquivo MainActivity.kt

As etapas a seguir inicializam o componente Map3DView adicionado ao arquivo activity_main.xml na Parte 1 e gerenciam os eventos de ciclo de vida do componente.

O SDK do Maps 3D para Android só aceita uma instância ativa de Map3DView por vez. Não é possível mostrar várias instâncias de Map3DView simultaneamente (por exemplo, no mesmo layout ou em diferentes atividades ou fragmentos visíveis). Isso pode causar problemas de renderização, como telas pretas em visualizações secundárias.

Além disso, todos os Map3DView vão compartilhar e refletir o mesmo estado do mapa (por exemplo, posição da câmera, marcadores adicionados, polígonos etc.), que vai persistir mesmo que um Map3DView seja destruído (usando onDestroy) e outro seja criado, a menos que seja limpo manualmente. Por exemplo, se você adicionar marcadores a Map3DView1, destruí-lo e criar Map3DView2, esses mesmos marcadores ainda estarão presentes em Map3DView2.

Responsabilidades do Desenvolvedor:

  • Uma visualização por vez:garanta que apenas um Map3DView esteja em uma parte ativa da hierarquia de visualização em qualquer momento.
  • Limpeza manual:ao alternar de um Map3DView (por exemplo, Map3DView1) para outro (por exemplo, Map3DView2), é necessário chamar onDestroy() na instância antiga (Map3DView1). Como o estado do mapa subjacente é compartilhado, para garantir que Map3DView2 comece com um estado novo ou específico, você precisa limpar manualmente qualquer estado definido por Map3DView1. Isso inclui remover marcadores, sobreposições etc. e redefinir a posição da câmera usando o objeto GoogleMap3D recebido no OnMap3DViewReadyCallback.
  1. Abra o arquivo MainActivity.kt, que geralmente está localizado em app/src/main/java/com/example/yourpackagename/MainActivity.kt.

  2. Adicione as importações necessárias para o SDK do Maps 3D para 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. Modifique a classe MainActivity para implementar OnMap3DViewReadyCallback:

    class MainActivity : AppCompatActivity(), OnMap3DViewReadyCallback {
    
  4. Declare variáveis para Map3DView e GoogleMap3D:

    private lateinit var map3DView: Map3DView
    private var googleMap3D: GoogleMap3D? = null
    
  5. No método onCreate, após setContentView(...) e o bloco ViewCompat.setOnApplyWindowInsetsListener, inicialize o map3DView, chame o método de ciclo de vida onCreate e solicite o mapa de forma assíncrona:

    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. Modifique os métodos onMap3DViewReady e onError. Esses callbacks são acionados quando o mapa está pronto para ser usado ou quando ocorre um erro durante a inicialização:

    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. Encaminhe eventos de ciclo de vida da sua atividade para o Map3DView adicionando as seguintes substituições ao 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: sincronizar o Gradle e executar

Agora que você atualizou o layout e a atividade do app, crie e execute o app para ver a visualização em 3D do mapa.

  1. Para sincronizar o projeto com o Gradle, selecione File > Sync Project with Gradle Files.

  2. Para criar e executar o app em um emulador ou dispositivo físico, selecione Run > Run.

Se tudo estiver configurado corretamente, um mapa 3D vai aparecer no app, centralizado perto das coordenadas especificadas no activity_main.xml.

Estados de carregamento e erro do mapa

O SDK do Maps 3D para Android mostra automaticamente um feedback visual integrado ao gerenciar o estado do mapa:

  • Sobreposição de carregamento:um indicador de progresso centralizado é exibido quando a visualização do mapa é inicializada pela primeira vez ou quando a janela de visualização inicial é carregada.
  • Sobreposição de erro:um card de erro estilizado é exibido se ocorrer uma falha crítica, como uma chave de API inválida, um erro de rede ou quando o app é executado em um dispositivo incompatível.

É possível capturar esses erros de inicialização ou carregamento de forma programática substituindo onError(error: Exception) na implementação de OnMap3DViewReadyCallback.

Detectar eventos de clique no mapa

Para detectar eventos de clique no mapa, chame setMap3DClickListener em GoogleMap3D. Quando um usuário clica no mapa, o callback onMap3DClick recebe um objeto Map3DClickEvent que fornece a location e a placeId do ponto clicado e retorna um Boolean (true para suprimir o widget de interface padrão do Places ou false para mostrá-lo). Para mais informações, consulte Interagir com pontos de interesse.

O exemplo a seguir mostra como definir um listener de cliques no mapa:

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

Próximas etapas

Agora que você adicionou um mapa 3D básico ao seu app, pode conhecer recursos mais avançados do SDK do Maps 3D para Android, como animações de trajeto da câmera, marcadores 3D ou polígonos.