Добавьте 3D-карту в свое приложение,Добавьте 3D-карту в свое приложение

Выберите платформу: Android iOS JavaScript

Трехмерная карта Нью-Йорка.

На этой странице представлен пример добавления простой 3D-карты в 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

The Map3DView component is the view that renders the 3D map within the app. The following steps add the component and configure the initial state of the map, including the camera position and related attributes:

  1. Откройте файл макета вашей основной активности, который обычно находится по адресу app/src/main/res/layout/activity_main.xml .

  2. В корневой 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: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>
    

Часть 2: Обновление файла MainActivity.kt

Следующие шаги инициализируют компонент Map3DView , добавленный в файл activity_main.xml в Части 1, и управляют событиями жизненного цикла компонента.

Обратите внимание, что Maps 3D SDK для Android поддерживает только один активный экземпляр Map3DView одновременно . Отображение нескольких экземпляров Map3DView одновременно (например, в одном макете или в разных видимых Activity или Fragment) не поддерживается и может привести к проблемам с рендерингом, таким как черные экраны на дополнительных представлениях.

Более того, все 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 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 . Этот коллбэк срабатывает, когда карта готова к использованию:

    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. Для пересылки событий жизненного цикла из вашей 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, выберите Файл > Синхронизировать проект с файлами Gradle.

  2. Чтобы собрать и запустить приложение на эмуляторе или физическом устройстве, выберите «Запуск» > «Запуск» .

Если все настроено правильно, в вашем приложении должна отобразиться трехмерная карта, центрированная вблизи координат, указанных в файле activity_main.xml .

Следующие шаги

Теперь, когда вы добавили в свое приложение базовую 3D-карту, вы можете изучить более продвинутые функции SDK Maps 3D для Android, такие как анимация траектории камеры , 3D-маркеры или полигоны .

Отслеживайте события кликов по карте.

Для отслеживания событий клика по карте используйте GoogleMap3D.setMap3DClickListener . Этот обработчик срабатывает, когда пользователь щелкает по карте, и предоставляет местоположение и ID точки, по которой был произведен клик.

В следующем примере показано, как настроить обработчик кликов по карте:

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

Обратите внимание, что обработчик кликов не выполняется в основном потоке (или потоке пользовательского интерфейса). Если вы хотите внести изменения в пользовательский интерфейс (например, отобразить всплывающее сообщение), вам необходимо переключиться в основной поток. В Kotlin это можно сделать с помощью lifecycleScope.launch(Dispatchers.Main) .