Dodawanie mapy 3D do aplikacji

Wybierz platformę: Android iOS JavaScript

Mapa 3D przedstawiająca Nowy Jork

Na tej stronie znajdziesz przykład dodawania podstawowej mapy 3D do aplikacji na Androida za pomocą pakietu Maps 3D SDK na Androida. Instrukcje na tej stronie zakładają, że masz już za sobą czynności opisane na stronie Konfiguracja i dysponujesz tymi elementami:

  • projekt w chmurze Google z włączonym pakietem Maps 3D SDK na Androida,
  • klucz interfejsu API skonfigurowany do użycia z pakietem SDK Map 3D na Androida,
  • Projekt w Android Studio skonfigurowany do użycia z pakietem SDK Map 3D na Androida.

Więcej informacji o tych wymaganiach wstępnych znajdziesz w artykule Konfiguracja.

Część 1. Zaktualizuj plik układu (activity_main.xml), aby dodać komponent Map3DView

Komponent Map3DView to widok, który renderuje mapę 3D w aplikacji. Aby dodać komponent i skonfigurować początkowy stan mapy, w tym pozycję kamery i powiązane atrybuty, wykonaj te czynności:

  1. Otwórz plik układu głównej aktywności, który zwykle znajduje się w app/src/main/res/layout/activity_main.xml.

  2. W elemencie głównym ConstraintLayout (lub głównym elemencie układu) dodaj przestrzeń nazw XML map3d:

    xmlns:map3d="http://schemas.android.com/apk/res-auto"
    
  3. Usuń domyślny element <TextView>, który wyświetla „Hello World!”.

  4. Dodaj komponent Map3DView do układu. Możesz dostosować pozycję kamery i inne atrybuty:

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

Część 2. Zaktualizuj plik MainActivity.kt

Poniższe kroki inicjują komponent Map3DView dodany do pliku activity_main.xml w części 1 i zarządzają zdarzeniami cyklu życia komponentu.

Pamiętaj, że pakiet Maps 3D SDK na Androida obsługuje tylko 1 aktywną instancję Map3DView naraz. Wyświetlanie wielu instancji Map3DView jednocześnie (np. w tym samym układzie lub w różnych widocznych aktywnościach lub fragmentach) nie jest obsługiwane i może prowadzić do problemów z renderowaniem, takich jak czarne ekrany w widokach dodatkowych.

Co więcej, wszystkie obiekty Map3DView będą udostępniać i odzwierciedlać ten sam stan mapy (np. pozycję kamery, dodane znaczniki, wielokąty itp.), który będzie zachowywany, nawet jeśli jeden obiekt Map3DView zostanie zniszczony (za pomocą onDestroy), a inny zostanie utworzony, chyba że zostanie ręcznie wyczyszczony. Jeśli na przykład dodasz znaczniki do Map3DView1, a następnie zniszczysz ten obiekt i utworzysz Map3DView2, te same znaczniki będą nadal obecne w Map3DView2.

Obowiązki dewelopera:

  • Jeden widok naraz: upewnij się, że w danym momencie tylko jeden element Map3DView znajduje się w aktywnej części hierarchii widoków.
  • Ręczne czyszczenie: podczas przełączania się z jednego Map3DView (np. Map3DView1) na inny (np. Map3DView2) musisz wywołać onDestroy() w starej instancji (Map3DView1). Ponieważ stan mapy bazowej jest udostępniany, aby mieć pewność, że Map3DView2 zaczyna się od nowego lub określonego stanu, musisz ręcznie wyczyścić stan ustawiony przez Map3DView1. Obejmuje to usuwanie znaczników, nakładek itp. oraz resetowanie pozycji kamery za pomocą obiektu GoogleMap3D uzyskanego w OnMap3DViewReadyCallback.
  1. Otwórz plik MainActivity.kt, który zwykle znajduje się w app/src/main/java/com/example/yourpackagename/MainActivity.kt.

  2. Dodaj niezbędne importy pakietu SDK Map 3D na Androida:

    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. Zmodyfikuj klasę MainActivity, aby zaimplementować OnMap3DViewReadyCallback:

    class MainActivity : AppCompatActivity(), OnMap3DViewReadyCallback {
    
  4. Zadeklaruj zmienne dla Map3DView i GoogleMap3D:

    private lateinit var map3DView: Map3DView
    private var googleMap3D: GoogleMap3D? = null
    
  5. W metodzie onCreate, po setContentView(...) i bloku ViewCompat.setOnApplyWindowInsetsListener, zainicjuj map3DView, wywołaj metodę cyklu życia onCreate i asynchronicznie poproś o mapę:

    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. Zastąp metody onMap3DViewReady i onError. Te wywołania zwrotne są aktywowane, gdy mapa jest gotowa do użycia lub gdy podczas inicjowania wystąpi błąd:

    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. Przekazuj zdarzenia cyklu życia z aktywności do Map3DView, dodając do MainActivity te zastąpienia:

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

Część 3. Synchronizowanie Gradle i uruchamianie

Po zaktualizowaniu układu i aktywności aplikacji możesz ją skompilować i uruchomić, aby zobaczyć widok mapy 3D.

  1. Aby zsynchronizować projekt z Gradle, wybierz File > Sync Project with Gradle Files (Plik > Synchronizuj projekt z plikami Gradle).

  2. Aby skompilować i uruchomić aplikację w emulatorze lub na urządzeniu fizycznym, wybierz Uruchom > Uruchom.

Jeśli wszystko jest skonfigurowane prawidłowo, w aplikacji powinna wyświetlić się mapa 3D wyśrodkowana w pobliżu współrzędnych określonych w pliku activity_main.xml.

Stany wczytywania mapy i stanu błędu

Pakiet SDK Map 3D na Androida automatycznie wyświetla wbudowane informacje wizualne podczas zarządzania stanem mapy:

  • Nakładka wczytywania: gdy widok mapy jest inicjowany po raz pierwszy lub wczytywany jest jego początkowy widoczny obszar, wyświetlany jest wyśrodkowany wskaźnik postępu.
  • Nakładka błędu: jeśli wystąpi błąd krytyczny, np. nieprawidłowy klucz interfejsu API, błąd sieci lub uruchomienie na nieobsługiwanym urządzeniu, wyświetlana jest stylizowana karta błędu.

Możesz przechwytywać te błędy inicjowania lub wczytywania automatycznie, zastępując onError(error: Exception) w implementacji OnMap3DViewReadyCallback.

Nasłuchiwanie zdarzeń kliknięcia mapy

Aby nasłuchiwać zdarzeń kliknięcia na mapie, wywołaj setMap3DClickListener na GoogleMap3D. Gdy użytkownik kliknie mapę, wywołanie zwrotne onMap3DClick otrzymuje obiekt Map3DClickEvent, który zawiera parametry location i placeId klikniętego punktu, i zwraca wartość Boolean (true, aby ukryć domyślny widżet interfejsu Miejsc, lub false, aby go wyświetlić). Więcej informacji znajdziesz w artykule Interakcja z ciekawymi miejscami.

Ten przykład pokazuje, jak ustawić detektor kliknięć na mapie:

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

Dalsze kroki

Teraz, gdy masz już dodaną do aplikacji podstawową mapę 3D, możesz odkryć więcej funkcji zaawansowanych pakietu Maps 3D SDK na Androida, takich jak animacje ścieżki kamery, znaczniki 3D czy wielokąty.