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 masz:

  • Projekt Google Cloud z włączonym pakietem Maps 3D SDK na Androida
  • Klucz interfejsu API skonfigurowany do używania z pakietem Maps 3D SDK na Androida
  • Projekt Android Studio skonfigurowany do używania z pakietem Maps 3D SDK na Androida

Więcej informacji o tych wymaganiach wstępnych znajdziesz w sekcji 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. Poniższe kroki umożliwiają dodanie komponentu i skonfigurowanie stanu początkowego mapy, w tym pozycji kamery i powiązanych atrybutów:

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

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

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

  4. Dodaj do układu komponent Map3DView. 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: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>
    

Część 2. Aktualizacja pliku 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 SDK Map 3D na Androida obsługuje tylko 1 aktywną instancję.Map3DView 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.

Ponadto wszystkie Map3DView będą miały i odzwierciedlały ten sam stan mapy (np. położenie kamery, dodane markery, wielokąty itp.), który będzie się utrzymywał nawet wtedy, gdy jeden z nich zostanie zniszczony (za pomocą onDestroy) i utworzony zostanie kolejny, chyba że zostanie ręcznie wyczyszczony.Map3DView Jeśli na przykład dodasz znaczniki do Map3DView1, a potem 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 aktywnej części hierarchii widoków w danym momencie znajduje się tylko 1 Map3DView.
  • Ręczne czyszczenie: podczas przełączania się z jednego elementu Map3DView (np. Map3DView1) na inny (np. Map3DView2) musisz wywołać funkcję onDestroy() w starej instancji (Map3DView1). Ponieważ podstawowy stan mapy jest udostępniany, aby mieć pewność, że element Map3DView2 zaczyna się od nowego lub określonego stanu, musisz ręcznie wyczyścić każdy stan ustawiony przez element Map3DView1. Obejmuje to usuwanie markeró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 lokalizacji app/src/main/java/com/example/yourpackagename/MainActivity.kt.

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

    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 wdrożyć OnMap3DViewReadyCallback:

    class MainActivity : AppCompatActivity(), OnMap3DViewReadyCallback {
    
  4. Zadeklaruj zmienne dla wartości Map3DViewGoogleMap3D:

    private lateinit var map3DView: Map3DView
    private var googleMap3D: GoogleMap3D? = null
    
  5. W metodzie onCreate po bloku setContentView(...)ViewCompat.setOnApplyWindowInsetsListener zainicjuj map3DView, wywołaj jego 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 metodę onMap3DViewReady. To wywołanie zwrotne jest wywoływane, gdy mapa jest gotowa do użycia:

    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. Przekaż zdarzenia cyklu życia z aktywności do Map3DView, dodając te zastąpienia do 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()
    }
    

Część 3. Synchronizacja 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 prawidłowo skonfigurowane, w aplikacji powinna się wyświetlić mapa 3D wyśrodkowana w pobliżu współrzędnych określonych w activity_main.xml.

Dalsze kroki

Po dodaniu do aplikacji podstawowej mapy 3D możesz poznać bardziej zaawansowane funkcje pakietu Maps 3D SDK na Androida, takie jak animacje ścieżki kamery, markery 3D czy wielokąty.

Nasłuchiwanie zdarzeń kliknięcia mapy

Aby nasłuchiwać zdarzeń kliknięcia na mapie, użyj GoogleMap3D.setMap3DClickListener. Ten odbiornik jest wywoływany, gdy użytkownik kliknie mapę. Podaje lokalizację i identyfikator miejsca klikniętego punktu.

Przykład poniżej pokazuje, jak ustawić detektor kliknięć mapy:

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

Pamiętaj, że funkcja obsługi kliknięć nie jest uruchamiana w wątku głównym (ani w wątku interfejsu). Jeśli chcesz wprowadzić zmiany w interfejsie (np. wyświetlić komunikat Toast), musisz przełączyć się na wątek główny. W przypadku języka Kotlin możesz to zrobić za pomocą funkcji lifecycleScope.launch(Dispatchers.Main).