আপনার অ্যাপে একটি 3D মানচিত্র যোগ করুন

প্ল্যাটফর্ম নির্বাচন করুন: অ্যান্ড্রয়েড আইওএস জাভাস্ক্রিপ্ট

নিউ ইয়র্ক শহর দেখানো একটি ত্রিমাত্রিক মানচিত্র

এই পৃষ্ঠায় অ্যান্ড্রয়েডের জন্য ম্যাপস 3D SDK ব্যবহার করে একটি অ্যান্ড্রয়েড অ্যাপে কীভাবে একটি সাধারণ 3D ম্যাপ যুক্ত করা যায়, তার একটি উদাহরণ দেখানো হয়েছে। এই পৃষ্ঠার নির্দেশাবলী ধরে নেয় যে আপনি ইতিমধ্যেই সেটআপ পৃষ্ঠার ধাপগুলি সম্পন্ন করেছেন এবং আপনার কাছে নিম্নলিখিত জিনিসগুলি রয়েছে:

  • অ্যান্ড্রয়েডের জন্য ম্যাপস ৩ডি এসডিকে সক্রিয় করা একটি গুগল ক্লাউড প্রজেক্ট
  • অ্যান্ড্রয়েডের জন্য Maps 3D SDK-এর সাথে ব্যবহারের জন্য কনফিগার করা একটি API কী।
  • অ্যান্ড্রয়েডের জন্য ম্যাপস ৩ডি এসডিকে (Maps 3D SDK for Android) দিয়ে ব্যবহারের জন্য তৈরি একটি অ্যান্ড্রয়েড স্টুডিও প্রজেক্ট।

এই পূর্বশর্তগুলো সম্পর্কে আরও তথ্যের জন্য, সেটআপ দেখুন।

পর্ব ১: Map3DView কম্পোনেন্টটি যোগ করতে লেআউট ফাইল ( activity_main.xml ) আপডেট করুন।

Map3DView কম্পোনেন্টটি হলো সেই ভিউ যা অ্যাপের মধ্যে 3D ম্যাপ রেন্ডার করে। নিচের ধাপগুলো অনুসরণ করে কম্পোনেন্টটি যুক্ত করা হয় এবং ক্যামেরার অবস্থান ও সংশ্লিষ্ট অ্যাট্রিবিউটসহ ম্যাপের প্রাথমিক অবস্থা কনফিগার করা হয়:

  1. আপনার প্রধান অ্যাক্টিভিটির লেআউট ফাইলটি খুলুন, যেটি সাধারণত app/src/main/res/layout/activity_main.xml -এ অবস্থিত।

  2. রুট ConstraintLayout এ (বা আপনার রুট লেআউট এলিমেন্টে), map3d XML নেমস্পেসটি যোগ করুন:

    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>
    

পর্ব ২: MainActivity.kt আপডেট করুন

নিম্নলিখিত ধাপগুলো পার্ট ১-এ activity_main.xml ফাইলে যোগ করা Map3DView কম্পোনেন্টটিকে ইনিশিয়ালাইজ করে এবং কম্পোনেন্টের লাইফসাইকেল ইভেন্টগুলো পরিচালনা করে।

উল্লেখ্য যে, অ্যান্ড্রয়েডের জন্য Maps 3D SDK একবারে শুধুমাত্র একটি সক্রিয় Map3DView ইনস্ট্যান্স সমর্থন করে। একই সাথে একাধিক Map3DView ইনস্ট্যান্স প্রদর্শন করা (যেমন, একই লেআউটে বা ভিন্ন ভিন্ন দৃশ্যমান অ্যাক্টিভিটি বা ফ্র্যাগমেন্টে) সমর্থিত নয় এবং এর ফলে রেন্ডারিং সংক্রান্ত সমস্যা দেখা দিতে পারে, যেমন সেকেন্ডারি ভিউগুলিতে কালো স্ক্রিন দেখা যাওয়া।

তাছাড়া, সমস্ত Map3DView একই ম্যাপের অবস্থা (যেমন ক্যামেরার অবস্থান, যোগ করা মার্কার, পলিগন ইত্যাদি) শেয়ার করবে ও প্রতিফলিত করবে, যা ম্যানুয়ালি মুছে না ফেলা পর্যন্ত একটি Map3DView ধ্বংস করে ( onDestroy ব্যবহার করে) আরেকটি তৈরি করা হলেও অপরিবর্তিত থাকবে। উদাহরণস্বরূপ, যদি আপনি Map3DView1 এ মার্কার যোগ করেন, তারপর সেটিকে ধ্বংস করে Map3DView2 তৈরি করেন, তাহলেও সেই একই মার্কারগুলো Map3DView2 এ উপস্থিত থাকবে।

ডেভেলপারের দায়িত্বসমূহ:

  • একবারে একটি ভিউ: নিশ্চিত করুন যে আপনার ভিউ হায়ারার্কির সক্রিয় অংশে যেকোনো মুহূর্তে কেবল একটি Map3DView থাকে।
  • ম্যানুয়াল পরিষ্করণ: একটি Map3DView (যেমন, Map3DView1 ) থেকে অন্যটিতে (যেমন, Map3DView2 ) পরিবর্তন করার সময়, আপনাকে অবশ্যই পুরানো ইনস্ট্যান্সটিতে ( Map3DView1 ) onDestroy() কল করতে হবে। যেহেতু অন্তর্নিহিত ম্যাপের স্টেট শেয়ার করা হয়, তাই Map3DView2 যেন একটি নতুন বা নির্দিষ্ট স্টেট দিয়ে শুরু হয় তা নিশ্চিত করার জন্য, Map3DView1 দ্বারা সেট করা যেকোনো স্টেট ম্যানুয়ালি পরিষ্কার করার দায়িত্ব আপনার। এর মধ্যে রয়েছে মার্কার, ওভারলে ইত্যাদি সরানো এবং OnMap3DViewReadyCallback এ প্রাপ্ত GoogleMap3D অবজেক্ট ব্যবহার করে ক্যামেরার অবস্থান রিসেট করা।
  1. আপনার MainActivity.kt ফাইলটি খুলুন, যেটি সাধারণত app/src/main/java/com/example/yourpackagename/MainActivity.kt -এ অবস্থিত।

  2. অ্যান্ড্রয়েডের জন্য ম্যাপস 3D SDK-এর জন্য প্রয়োজনীয় ইম্পোর্টগুলো যোগ করুন:

    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. OnMap3DViewReadyCallback ইমপ্লিমেন্ট করার জন্য MainActivity ক্লাসটি পরিবর্তন করুন:

    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. আপনার 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()
    }
    

পর্ব ৩: গ্রেডল সিঙ্ক করুন এবং রান করুন

এখন যেহেতু আপনি আপনার অ্যাপের লেআউট এবং অ্যাক্টিভিটি আপডেট করেছেন, আপনি 3D ম্যাপ ভিউটি দেখার জন্য অ্যাপটি বিল্ড ও রান করতে পারেন।

  1. আপনার প্রজেক্টকে গ্রেডলের সাথে সিঙ্ক করতে, ফাইল > সিঙ্ক প্রজেক্ট উইথ গ্রেডল ফাইলস নির্বাচন করুন।

  2. এমুলেটর বা ফিজিক্যাল ডিভাইসে আপনার অ্যাপটি বিল্ড ও রান করতে, রান > রান নির্বাচন করুন।

সবকিছু সঠিকভাবে কনফিগার করা থাকলে, আপনার অ্যাপে একটি 3D মানচিত্র প্রদর্শিত হবে, যা আপনার activity_main.xml ফাইলে নির্দিষ্ট করা স্থানাঙ্কের কাছাকাছি কেন্দ্রে অবস্থিত থাকবে।

মানচিত্র লোড এবং ত্রুটির অবস্থা

অ্যান্ড্রয়েডের জন্য Maps 3D SDK ম্যাপের অবস্থা পরিচালনা করার সময় স্বয়ংক্রিয়ভাবে অন্তর্নির্মিত ভিজ্যুয়াল ফিডব্যাক প্রদর্শন করে:

  • ওভারলে লোড হচ্ছে: ম্যাপ ভিউ প্রথমবার চালু হলে বা এর প্রাথমিক ভিউপোর্ট লোড হওয়ার সময় একটি কেন্দ্রস্থ অগ্রগতি সূচক প্রদর্শিত হয়।
  • ত্রুটি ওভারলে: কোনো গুরুতর ব্যর্থতা ঘটলে, যেমন অবৈধ এপিআই কী, নেটওয়ার্ক ত্রুটি, বা কোনো অসমর্থিত ডিভাইসে চালানোর সময়, একটি শৈলীযুক্ত ত্রুটি কার্ড প্রদর্শিত হয়।

আপনার OnMap3DViewReadyCallback ইমপ্লিমেন্টেশনের মধ্যে onError(error: Exception) ওভাররাইড করে আপনি এই ইনিশিয়ালাইজেশন বা লোডিং ত্রুটিগুলি প্রোগ্রাম্যাটিকভাবে ধরতে পারেন।

ম্যাপ ক্লিক ইভেন্টগুলির জন্য শুনুন

ম্যাপের ক্লিক ইভেন্ট শোনার জন্য, GoogleMap3D.setMap3DClickListener ব্যবহার করুন। যখন কোনো ব্যবহারকারী ম্যাপে ক্লিক করেন, তখন এই লিসেনারটি ট্রিগার হয় এবং ক্লিক করা পয়েন্টটির অবস্থান ও প্লেস আইডি প্রদান করে।

নিচের উদাহরণটিতে দেখানো হয়েছে কীভাবে একটি ম্যাপ ক্লিক লিসেনার সেট করতে হয়:

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-তে কোনো পরিবর্তন করতে চান (যেমন একটি টোস্ট মেসেজ দেখানো), তাহলে আপনাকে অবশ্যই মেইন থ্রেডে যেতে হবে। কোটলিনের ক্ষেত্রে, আপনি lifecycleScope.launch(Dispatchers.Main) ব্যবহার করে এটি করতে পারেন।

পরবর্তী পদক্ষেপ

এখন যেহেতু আপনি আপনার অ্যাপে একটি সাধারণ 3D ম্যাপ যোগ করেছেন, আপনি অ্যান্ড্রয়েডের জন্য Maps 3D SDK-এর আরও উন্নত বৈশিষ্ট্যগুলো, যেমন ক্যামেরা পাথ অ্যানিমেশন , 3D মার্কার বা পলিগন , ব্যবহার করে দেখতে পারেন।