Как добавить 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. Добавьте компонент Map3DView в файл макета (activity_main.xml)

Компонент Map3DView – это представление, которое отрисовывает 3D-карту в приложении. Чтобы добавить компонент и настроить исходное состояние карты, включая положение камеры и связанные атрибуты, выполните следующие действия:

  1. Откройте файл макета основного объекта activity. Обычно он находится в каталоге 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: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>
    

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

Ниже описано, как инициализировать компонент Map3DView, добавленный в файл activity_main.xml в части 1, и управлять событиями жизненного цикла компонента.

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

Кроме того, все объекты Map3DView будут иметь одинаковое состояние карты (например, положение камеры, добавленные маркеры, многоугольники и т. д.), которое будет сохраняться, даже если один объект Map3DView будет удален (с помощью onDestroy), а другой создан, если только оно не будет очищено вручную. Например, если вы добавите маркеры в Map3DView1, а затем удалите его и создадите Map3DView2, те же маркеры будут присутствовать в Map3DView2.

Обязанности разработчика

  • Один просмотр за раз. Убедитесь, что в активной части иерархии View одновременно находится только один объект 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 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. Измените класс 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 и onError. Эти обратные вызовы выполняются, когда карта готова к использованию или при инициализации произошла ошибка:

    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. Перенаправьте события жизненного цикла из объекта 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 и запуск

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

  1. Чтобы синхронизировать проект с Gradle, выберите File > Sync Project with Gradle Files (Файл > Синхронизировать проект с файлами Gradle).

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

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

Состояния загрузки и ошибки карты

Maps 3D SDK для Android автоматически показывает встроенные визуальные подсказки, управляя состоянием карты:

  • Оверлей загрузки. При первой инициализации карты или загрузке ее начальной области просмотра по центру отображается индикатор выполнения.
  • Наложение с ошибкой. Если произойдет критическая ошибка, например из-за недействительного ключа API, ошибки сети или при запуске на неподдерживаемом устройстве, будет показана карточка с ошибкой.

Вы можете программно отслеживать ошибки инициализации или загрузки, переопределив onError(error: Exception) в реализации OnMap3DViewReadyCallback.

Как отслеживать события кликов по карте

Чтобы отслеживать события кликов на карте, вызовите метод setMap3DClickListener для объекта GoogleMap3D. Когда пользователь нажимает на карту, обратный вызов onMap3DClick получает объект Map3DClickEvent, который предоставляет значения location и placeId для точки, на которую нажал пользователь, и возвращает логическое значение Boolean (true, чтобы скрыть стандартный виджет Places UI, или false, чтобы показать его). Подробнее о том, как взаимодействовать с интересными местами…

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

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

Дальнейшие действия

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