เพิ่มแผนที่ 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: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 ที่ทำงานอยู่ครั้งละ 1 รายการเท่านั้น ระบบไม่รองรับการแสดงอินสแตนซ์ Map3DView หลายรายการพร้อมกัน (เช่น ในเลย์เอาต์เดียวกันหรือกิจกรรมหรือ 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 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 ระบบจะทริกเกอร์ Callback เหล่านี้เมื่อแผนที่พร้อมใช้งาน หรือเมื่อเกิดข้อผิดพลาดระหว่างการเริ่มต้น

    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. ส่งต่อเหตุการณ์ในวงจรจากกิจกรรมไปยัง 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

ฟังกิจกรรมการคลิกแผนที่

หากต้องการฟังกิจกรรมการคลิกบนแผนที่ ให้เรียกใช้ setMap3DClickListener ใน GoogleMap3D เมื่อผู้ใช้คลิกแผนที่ Callback onMap3DClick จะได้รับออบเจ็กต์ Map3DClickEvent ที่ระบุ location และ placeId ของจุดที่คลิก และแสดงผล Boolean (true เพื่อระงับวิดเจ็ต UI ของ Places เริ่มต้น หรือ false เพื่อแสดง) ดูข้อมูลเพิ่มเติมได้ที่โต้ตอบกับจุดที่น่าสนใจ

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

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

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

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