เพิ่มแผนที่ 3 มิติลงในแอป

เลือกแพลตฟอร์ม: Android iOS JavaScript

แผนที่ 3 มิติที่แสดงนิวยอร์กซิตี้

หน้านี้จะอธิบายตัวอย่างวิธีเพิ่มแผนที่ 3 มิติพื้นฐานลงในแอป 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

คอมโพเนนต์ Map3DView คือมุมมองที่แสดงแผนที่ 3 มิติภายในแอป ขั้นตอนต่อไปนี้จะเพิ่มคอมโพเนนต์และกำหนดค่าสถานะเริ่มต้นของแผนที่ ซึ่งรวมถึงตำแหน่งกล้องและแอตทริบิวต์ที่เกี่ยวข้อง

  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:mode="hybrid"
        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 เพียงครั้งละ 1 รายการ ระบบไม่รองรับการแสดงอินสแตนซ์ Map3DView หลายรายการพร้อมกัน (เช่น ในเลย์เอาต์เดียวกันหรือกิจกรรมหรือ Fragment ที่มองเห็นได้ต่างๆ) และอาจทำให้เกิดปัญหาในการแสดงผล เช่น หน้าจอสีดำในมุมมองรอง

นอกจากนี้ Map3DView ทั้งหมดจะแชร์และแสดงสถานะแผนที่เดียวกัน (เช่น ตำแหน่งกล้อง เครื่องหมายที่เพิ่ม รูปหลายเหลี่ยม ฯลฯ) ซึ่งจะยังคงอยู่แม้ว่า Map3DView รายการหนึ่งจะถูกทำลาย (โดยใช้ onDestroy) และมีการสร้างอีกรายการหนึ่งขึ้นมา เว้นแต่จะล้างด้วยตนเอง ตัวอย่างเช่น หากคุณเพิ่มเครื่องหมายลงใน Map3DView1 แล้วทำลาย และสร้าง Map3DView2 เครื่องหมายเดียวกันนั้นจะยังคงอยู่ใน Map3DView2

ความรับผิดชอบของนักพัฒนาซอฟต์แวร์

  • มุมมองครั้งละ 1 รายการ: ตรวจสอบว่ามี Map3DView เพียงรายการเดียวในส่วนที่ใช้งานอยู่ของลำดับชั้นการแสดงผลในทุกขณะ
  • การล้างข้อมูลด้วยตนเอง: เมื่อเปลี่ยนจาก Map3DView รายการหนึ่ง (เช่น Map3DView1) ไปยังอีกรายการหนึ่ง (เช่น Map3DView2) คุณต้องเรียกใช้ onDestroy() ในอินสแตนซ์เก่า (Map3DView1) เนื่องจากสถานะแผนที่พื้นฐานมีการแชร์กัน คุณจึงมีหน้าที่รับผิดชอบในการ ล้างสถานะที่ Map3DView1 ตั้งค่าไว้ด้วยตนเองเพื่อให้ Map3DView2 เริ่มต้นด้วยสถานะใหม่หรือสถานะที่เฉพาะเจาะจง ซึ่งรวมถึงการนำเครื่องหมาย การวางซ้อน ฯลฯ ออก และการรีเซ็ตตำแหน่งกล้องโดยใช้ออบเจ็กต์ 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.cameraController.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. ส่งต่อเหตุการณ์วงจรจากกิจกรรมไปยัง 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 และเรียกใช้

เมื่ออัปเดตเลย์เอาต์และกิจกรรมของแอปแล้ว คุณก็สามารถสร้างและเรียกใช้แอปเพื่อดูมุมมองแผนที่ 3 มิติได้

  1. หากต้องการซิงค์โปรเจ็กต์กับ Gradle ให้เลือกไฟล์ > ซิงค์โปรเจ็กต์กับไฟล์ Gradle

  2. หากต้องการสร้างและเรียกใช้แอปในโปรแกรมจำลองหรืออุปกรณ์จริง ให้เลือกเรียกใช้ > เรียกใช้

หากกำหนดค่าทุกอย่างถูกต้อง คุณควรเห็นแผนที่ 3 มิติแสดงในแอป โดยอยู่กึ่งกลางใกล้กับพิกัดที่ระบุไว้ใน activity_main.xml

สถานะการโหลดแผนที่และสถานะข้อผิดพลาด

Maps 3D SDK สำหรับ Android จะแสดงความคิดเห็นด้วยภาพในตัวโดยอัตโนมัติขณะจัดการสถานะของแผนที่ ดังนี้

  • การวางซ้อนการโหลด: ตัวบ่งชี้ความคืบหน้าแบบกึ่งกลางจะแสดงขึ้นเมื่อมีการเริ่มต้นมุมมองแผนที่เป็นครั้งแรกหรือเมื่อโหลดวิวพอร์ตเริ่มต้น
  • การวางซ้อนข้อผิดพลาด: การ์ดข้อผิดพลาดที่มีสไตล์จะแสดงขึ้นหากเกิดความล้มเหลวที่สำคัญ เช่น คีย์ API ไม่ถูกต้อง ข้อผิดพลาดของเครือข่าย หรือเมื่อเรียกใช้ในอุปกรณ์ที่ไม่รองรับ

คุณสามารถบันทึกข้อผิดพลาดในการเริ่มต้นหรือการโหลดเหล่านี้แบบเป็นโปรแกรมได้โดย การแทนที่ onError(error: Exception) ภายใน OnMap3DViewReadyCallback การใช้งาน

ฟังเหตุการณ์การคลิกแผนที่

หากต้องการฟังเหตุการณ์การคลิกบนแผนที่ ให้ใช้ GoogleMap3D.setMap3DClickListener ระบบจะทริกเกอร์ Listener นี้เมื่อผู้ใช้คลิกบนแผนที่ และจะแสดงตำแหน่งและรหัสสถานที่ของจุดที่คลิก

ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าฟังก์ชันรอคลิกแผนที่

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

โปรดทราบว่าตัวจัดการการคลิกไม่ได้ทำงานในเธรดหลัก (หรือเธรด UI) หากต้องการทำการเปลี่ยนแปลง UI (เช่น แสดงข้อความ Toast) คุณต้องเปลี่ยนไปใช้เธรดหลัก สำหรับ Kotlin คุณสามารถทำได้โดยใช้ lifecycleScope.launch(Dispatchers.Main)

ขั้นตอนถัดไป

เมื่อเพิ่มแผนที่ 3 มิติพื้นฐานลงในแอปแล้ว คุณก็สามารถสำรวจฟีเจอร์ขั้นสูงเพิ่มเติมของ Maps 3D SDK สำหรับ Android ได้ เช่น แอนิเมชันเส้นทางกล้อง, เครื่องหมาย 3 มิติ หรือ รูปหลายเหลี่ยม