Thêm bản đồ 3D vào ứng dụng

Chọn nền tảng: Android iOS JavaScript

Bản đồ 3D cho thấy Thành phố New York

Trang này trình bày ví dụ về cách thêm bản đồ 3D cơ bản vào ứng dụng Android bằng SDK Maps 3D dành cho Android. Hướng dẫn trên trang này giả định rằng bạn đã hoàn tất các bước trong trang Thiết lập và có những nội dung sau:

  • Một dự án Google Cloud đã bật SDK Maps 3D dành cho Android
  • Một khoá API được định cấu hình để sử dụng với SDK Maps 3D dành cho Android
  • Một dự án Android Studio được thiết lập để sử dụng với SDK Maps 3D dành cho Android

Để biết thêm thông tin về các điều kiện tiên quyết này, hãy xem Thiết lập.

Phần 1: Cập nhật tệp bố cục (activity_main.xml) để thêm thành phần Map3DView

Thành phần Map3DView là khung hiển thị kết xuất bản đồ 3D trong ứng dụng. Các bước sau đây sẽ thêm thành phần và định cấu hình trạng thái ban đầu của bản đồ, bao gồm vị trí máy ảnh và các thuộc tính liên quan:

  1. Mở tệp bố cục của hoạt động chính, thường nằm tại app/src/main/res/layout/activity_main.xml.

  2. Trong ConstraintLayout gốc (hoặc phần tử bố cục gốc), hãy thêm không gian tên XML map3d:

    xmlns:map3d="http://schemas.android.com/apk/res-auto"
    
  3. Xoá <TextView> mặc định hiển thị "Hello World!".

  4. Thêm thành phần Map3DView vào bố cục. Bạn có thể tuỳ chỉnh vị trí máy ảnh và các thuộc tính khác:

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

Phần 2: Cập nhật MainActivity.kt

Các bước sau đây sẽ khởi chạy thành phần Map3DView được thêm vào tệp activity_main.xml trong Phần 1 và quản lý các sự kiện trong vòng đời của thành phần.

Xin lưu ý rằng SDK Maps 3D dành cho Android chỉ hỗ trợ một thực thể Map3DView đang hoạt động tại một thời điểm. Hệ thống không hỗ trợ việc hiển thị nhiều thực thể Map3DView cùng lúc (ví dụ: trong cùng một bố cục hoặc các Hoạt động hoặc Mảnh hiển thị khác nhau) và có thể dẫn đến các vấn đề về kết xuất, chẳng hạn như màn hình đen trên các khung hiển thị phụ.

Ngoài ra, tất cả Map3DView sẽ chia sẻ và phản ánh cùng một trạng thái bản đồ (ví dụ: vị trí máy ảnh, điểm đánh dấu đã thêm, đa giác, v.v.). Trạng thái này sẽ tồn tại ngay cả khi một Map3DView bị huỷ (sử dụng onDestroy) và một Map3DView khác được tạo, trừ phi bạn xoá theo cách thủ công. Ví dụ: nếu bạn thêm điểm đánh dấu vào Map3DView1, sau đó hủy bỏ điểm đánh dấu đó và tạo Map3DView2, thì các điểm đánh dấu đó vẫn sẽ xuất hiện trên Map3DView2.

Trách nhiệm của nhà phát triển:

  • Mỗi lần một khung hiển thị: Đảm bảo chỉ có một Map3DView trong một phần đang hoạt động của hệ phân cấp view tại bất kỳ thời điểm nào.
  • Dọn dẹp thủ công: Khi chuyển từ một Map3DView (ví dụ: Map3DView1) sang một Map3DView khác (ví dụ: Map3DView2), bạn phải gọi onDestroy() trên thực thể cũ (Map3DView1). Vì trạng thái bản đồ cơ bản được chia sẻ, nên để đảm bảo Map3DView2 bắt đầu với một trạng thái mới hoặc cụ thể, bạn có trách nhiệm xoá theo cách thủ công mọi trạng thái do Map3DView1 đặt. Điều này bao gồm việc xoá điểm đánh dấu, lớp phủ, v.v. và đặt lại vị trí máy ảnh bằng đối tượng GoogleMap3D thu được trong OnMap3DViewReadyCallback.
  1. Mở tệp MainActivity.kt, thường nằm tại app/src/main/java/com/example/yourpackagename/MainActivity.kt.

  2. Thêm các lệnh nhập cần thiết cho SDK Maps 3D dành cho Android:

    import com.google.android.gms.maps3d.GoogleMap3D
    import com.google.android.gms.maps3d.Map3DView
    import com.google.android.gms.maps3d.OnMap3DViewReadyCallback
    
  3. Sửa đổi lớp MainActivity để triển khai OnMap3DViewReadyCallback:

    class MainActivity : AppCompatActivity(), OnMap3DViewReadyCallback {
    
  4. Khai báo các biến cho Map3DViewGoogleMap3D:

    private lateinit var map3DView: Map3DView
    private var googleMap3D: GoogleMap3D? = null
    
  5. Trong phương thức onCreate, sau setContentView(...) và khối ViewCompat.setOnApplyWindowInsetsListener, hãy khởi chạy map3DView, gọi phương thức vòng đời onCreate và yêu cầu bản đồ không đồng bộ:

    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. Ghi đè phương thức onMap3DViewReady. Phương thức gọi lại này được kích hoạt khi bản đồ đã sẵn sàng để sử dụng:

    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. Chuyển tiếp các sự kiện trong vòng đời từ Hoạt động sang Map3DView bằng cách thêm các phương thức ghi đè sau vào 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()
    }
    

Phần 3: Đồng bộ hoá Gradle và Chạy

Giờ đây, bạn đã cập nhật bố cục và hoạt động của ứng dụng, bạn có thể tạo và chạy ứng dụng để xem khung hiển thị bản đồ 3D.

  1. Để đồng bộ hoá dự án với Gradle, hãy chọn File > Sync Project with Gradle Files (Tệp > Đồng bộ hoá dự án với các tệp Gradle).

  2. Để tạo và chạy ứng dụng trên trình mô phỏng hoặc thiết bị thực tế, hãy chọn Run > Run (Chạy > Chạy).

Nếu mọi thứ được định cấu hình chính xác, bạn sẽ thấy một bản đồ 3D xuất hiện trong ứng dụng của mình, tập trung gần các toạ độ được chỉ định trong activity_main.xml.

Các bước tiếp theo

Giờ đây, bạn đã thêm bản đồ 3D cơ bản vào ứng dụng của mình, bạn có thể khám phá các tính năng nâng cao hơn của SDK Maps 3D dành cho Android, chẳng hạn như ảnh động đường dẫn máy ảnh, điểm đánh dấu 3D, hoặc đa giác.

Theo dõi các sự kiện nhấp vào bản đồ

Để theo dõi các sự kiện nhấp vào bản đồ, hãy sử dụng GoogleMap3D.setMap3DClickListener. Trình nghe này được kích hoạt khi người dùng nhấp vào bản đồ và cung cấp vị trí cũng như mã địa điểm của điểm đã nhấp.

Ví dụ sau đây cho thấy cách thiết lập trình theo dõi lượt nhấp bản đồ:

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

Xin lưu ý rằng trình xử lý lượt nhấp không chạy trên luồng Chính (hoặc luồng giao diện người dùng). Nếu bạn muốn thay đổi giao diện người dùng (chẳng hạn như hiển thị thông báo Toast), bạn phải chuyển sang luồng Chính. Đối với Kotlin, bạn có thể thực hiện việc này bằng cách sử dụng lifecycleScope.launch(Dispatchers.Main).