আপনার অ্যান্ড্রয়েড অ্যাপে একটি মানচিত্র যোগ করুন (কম্পোজ সহ কোটলিন)

1. আপনি শুরু করার আগে

এই কোডল্যাব আপনাকে শেখায় কিভাবে আপনার অ্যাপের সাথে Android এর জন্য Maps SDK সংহত করতে হয় এবং বিভিন্ন ধরনের মার্কার ব্যবহার করে কলোরাডো, মার্কিন যুক্তরাষ্ট্রে পাহাড়ের একটি মানচিত্র প্রদর্শন করে এমন একটি অ্যাপ তৈরি করে এর মূল বৈশিষ্ট্যগুলি ব্যবহার করতে হয়। উপরন্তু, আপনি মানচিত্রে অন্যান্য আকার আঁকতে শিখবেন।

আপনি কোডল্যাব দিয়ে শেষ করলে এটি কেমন দেখাবে তা এখানে:

পূর্বশর্ত

আপনি কি করবেন

  • একটি Android অ্যাপে একটি GoogleMap যোগ করতে Android এর জন্য Maps SDK-এর জন্য মানচিত্র রচনা লাইব্রেরি সক্ষম করুন এবং ব্যবহার করুন
  • মার্কার যোগ করুন এবং কাস্টমাইজ করুন
  • মানচিত্রে বহুভুজ আঁকুন
  • ক্যামেরার দৃষ্টিকোণ প্রোগ্রামিকভাবে নিয়ন্ত্রণ করুন

আপনি কি প্রয়োজন হবে

2. সেট আপ করুন

নিম্নলিখিত সক্রিয়করণ পদক্ষেপের জন্য, আপনাকে Android এর জন্য মানচিত্র SDK সক্ষম করতে হবে।

Google Maps প্ল্যাটফর্ম সেট আপ করুন

আপনার যদি ইতিমধ্যেই একটি Google ক্লাউড প্ল্যাটফর্ম অ্যাকাউন্ট না থাকে এবং বিলিং সক্ষম করা একটি প্রকল্প থাকে, তাহলে অনুগ্রহ করে একটি বিলিং অ্যাকাউন্ট এবং একটি প্রকল্প তৈরি করতে Google মানচিত্র প্ল্যাটফর্মের সাথে শুরু করা নির্দেশিকাটি দেখুন৷

  1. ক্লাউড কনসোলে , প্রকল্পের ড্রপ-ডাউন মেনুতে ক্লিক করুন এবং এই কোডল্যাবের জন্য আপনি যে প্রকল্পটি ব্যবহার করতে চান সেটি নির্বাচন করুন।

  1. Google ক্লাউড মার্কেটপ্লেসে এই কোডল্যাবের জন্য প্রয়োজনীয় Google মানচিত্র প্ল্যাটফর্ম API এবং SDK সক্ষম করুন৷ এটি করতে, এই ভিডিও বা এই ডকুমেন্টেশনের ধাপগুলি অনুসরণ করুন৷
  2. ক্লাউড কনসোলের শংসাপত্র পৃষ্ঠায় একটি API কী তৈরি করুন। আপনি এই ভিডিও বা এই ডকুমেন্টেশনের ধাপগুলি অনুসরণ করতে পারেন। Google মানচিত্র প্ল্যাটফর্মের সমস্ত অনুরোধের জন্য একটি API কী প্রয়োজন৷

3. দ্রুত শুরু

যত তাড়াতাড়ি সম্ভব আপনাকে শুরু করতে, এই কোডল্যাবের সাথে আপনাকে অনুসরণ করতে সহায়তা করার জন্য এখানে কিছু স্টার্টার কোড রয়েছে৷ সমাধানে ঝাঁপিয়ে পড়তে আপনাকে স্বাগত জানাই, কিন্তু আপনি যদি এটি নিজে তৈরি করার সমস্ত ধাপ অনুসরণ করতে চান তবে পড়তে থাকুন।

  1. আপনি যদি git ইনস্টল করে থাকেন তবে সংগ্রহস্থল ক্লোন করুন।
git clone https://github.com/googlemaps-samples/codelab-maps-platform-101-compose.git

বিকল্পভাবে, আপনি সোর্স কোড ডাউনলোড করতে নিম্নলিখিত বোতামে ক্লিক করতে পারেন।

  1. কোড পাওয়ার পরে, এগিয়ে যান এবং অ্যান্ড্রয়েড স্টুডিওতে starter ডিরেক্টরির মধ্যে পাওয়া প্রকল্পটি খুলুন।

4. প্রকল্পে আপনার API কী যোগ করুন

এই বিভাগটি বর্ণনা করে কিভাবে আপনার API কী সংরক্ষণ করতে হয় যাতে এটি আপনার অ্যাপ দ্বারা নিরাপদে উল্লেখ করা যায়। আপনার সংস্করণ নিয়ন্ত্রণ সিস্টেমে আপনার API কী চেক করা উচিত নয়, তাই আমরা এটিকে secrets.properties ফাইলে সংরক্ষণ করার পরামর্শ দিই, যা আপনার প্রকল্পের মূল ডিরেক্টরির স্থানীয় অনুলিপিতে স্থাপন করা হবে। secrets.properties ফাইল সম্পর্কে আরও তথ্যের জন্য, Gradle বৈশিষ্ট্য ফাইলগুলি দেখুন।

এই কাজটি স্ট্রীমলাইন করতে, আমরা আপনাকে Android এর জন্য সিক্রেটস গ্রেডল প্লাগইন ব্যবহার করার পরামর্শ দিই।

আপনার Google মানচিত্র প্রকল্পে Android এর জন্য Secrets Gradle Plugin ইনস্টল করতে:

  1. অ্যান্ড্রয়েড স্টুডিওতে, আপনার শীর্ষ-স্তরের build.gradle.kts ফাইলটি খুলুন এবং buildscript অধীনে dependencies উপাদানে নিম্নলিখিত কোডটি যোগ করুন।
    buildscript {
        dependencies {
            classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
        }
    }
    
  2. আপনার মডিউল-স্তরের build.gradle.kts ফাইলটি খুলুন এবং plugins উপাদানটিতে নিম্নলিখিত কোডটি যোগ করুন।
    plugins {
        // ...
        id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    }
    
  3. আপনার মডিউল-স্তরের build.gradle.kts ফাইলে, নিশ্চিত করুন যে targetSdk এবং compileSdk কমপক্ষে 34-এ সেট করা আছে।
  4. ফাইলটি সংরক্ষণ করুন এবং Gradle এর সাথে আপনার প্রকল্প সিঙ্ক করুন
  5. আপনার শীর্ষ-স্তরের ডিরেক্টরিতে secrets.properties ফাইলটি খুলুন এবং তারপরে নিম্নলিখিত কোডটি যোগ করুন। আপনার API কী দিয়ে YOUR_API_KEY প্রতিস্থাপন করুন। এই ফাইলে আপনার কী সংরক্ষণ করুন কারণ secrets.properties একটি সংস্করণ নিয়ন্ত্রণ সিস্টেমে চেক করা থেকে বাদ দেওয়া হয়েছে৷
    MAPS_API_KEY=YOUR_API_KEY
    
  6. ফাইলটি সংরক্ষণ করুন।
  7. আপনার শীর্ষ-স্তরের ডিরেক্টরিতে local.defaults.properties ফাইল তৈরি করুন, secrets.properties ফাইলের মতো একই ফোল্ডার, এবং তারপরে নিম্নলিখিত কোডটি যোগ করুন।
        MAPS_API_KEY=DEFAULT_API_KEY
    
    এই ফাইলটির উদ্দেশ্য হল API কীটির জন্য একটি ব্যাকআপ অবস্থান প্রদান করা যদি secrets.properties ফাইলটি না পাওয়া যায় যাতে বিল্ডগুলি ব্যর্থ না হয়৷ এটি ঘটবে যখন আপনি একটি সংস্করণ নিয়ন্ত্রণ সিস্টেম থেকে অ্যাপটি ক্লোন করবেন এবং আপনি এখনও আপনার API কী প্রদান করার জন্য স্থানীয়ভাবে একটি secrets.properties ফাইল তৈরি করেননি৷
  8. ফাইলটি সংরক্ষণ করুন।
  9. আপনার AndroidManifest.xml ফাইলে, com.google.android.geo.API_KEY এ যান এবং android:value বৈশিষ্ট্য আপডেট করুন। যদি <meta-data> ট্যাগটি বিদ্যমান না থাকে, তাহলে এটিকে <application> ট্যাগের একটি চাইল্ড হিসেবে তৈরি করুন।
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${MAPS_API_KEY}" />
    
  10. অ্যান্ড্রয়েড স্টুডিওতে, আপনার মডিউল-স্তরের build.gradle.kts ফাইল খুলুন এবং secrets সম্পত্তি সম্পাদনা করুন। secrets সম্পত্তি বিদ্যমান না থাকলে, এটি যোগ করুন। secrets.propertiespropertiesFileName সেট করতে প্লাগইনের বৈশিষ্ট্য সম্পাদনা করুন, defaultPropertiesFileName to local.defaults.properties সেট করুন এবং অন্য কোনো বৈশিষ্ট্য সেট করুন।
    secrets {
        // Optionally specify a different file name containing your secrets.
        // The plugin defaults to "local.properties"
        propertiesFileName = "secrets.properties"
    
        // A properties file containing default secret values. This file can be
        // checked in version control.
        defaultPropertiesFileName = "local.defaults.properties"
    }
    

5. Google Maps যোগ করুন

এই বিভাগে, আপনি একটি Google মানচিত্র যুক্ত করবেন যাতে আপনি অ্যাপটি চালু করার সময় এটি লোড হয়।

মানচিত্র রচনা নির্ভরতা যোগ করুন

এখন যেহেতু আপনার API কী অ্যাপের ভিতরে অ্যাক্সেস করা যেতে পারে, পরবর্তী ধাপ হল আপনার অ্যাপের build.gradle.kts ফাইলে Android নির্ভরতার জন্য Maps SDK যোগ করা। জেটপ্যাক কম্পোজের সাথে তৈরি করতে, ম্যাপ কম্পোজ লাইব্রেরি ব্যবহার করুন যা কম্পোজযোগ্য ফাংশন এবং ডেটা টাইপ হিসাবে Android এর জন্য Maps SDK-এর উপাদানগুলি প্রদান করে৷

build.gradle.kts

অ্যাপ স্তরে build.gradle.kts ফাইলটি Android নির্ভরতার জন্য নন-কম্পোজ মানচিত্র SDK প্রতিস্থাপন করুন:

dependencies {
    // ...

    // Google Maps SDK -- these are here for the data model.  Remove these dependencies and replace
    // with the compose versions.
    implementation("com.google.android.gms:play-services-maps:18.2.0")
    // KTX for the Maps SDK for Android library
    implementation("com.google.maps.android:maps-ktx:5.0.0")
    // KTX for the Maps SDK for Android Utility Library
    implementation("com.google.maps.android:maps-utils-ktx:5.0.0")
}

তাদের সংমিশ্রণযোগ্য অংশগুলির সাথে:

dependencies {
    // ...

    // Google Maps Compose library
    val mapsComposeVersion = "4.4.1"
    implementation("com.google.maps.android:maps-compose:$mapsComposeVersion")
    // Google Maps Compose utility library
    implementation("com.google.maps.android:maps-compose-utils:$mapsComposeVersion")
    // Google Maps Compose widgets library
    implementation("com.google.maps.android:maps-compose-widgets:$mapsComposeVersion")
}

একটি গুগল ম্যাপ কম্পোজযোগ্য যোগ করুন

MountainMap.kt এ, MapMountain কম্পোজেবলের মধ্যে Box কম্পোজেবল নেস্টের ভিতরে GoogleMap কম্পোজেবল যোগ করুন।

import com.google.maps.android.compose.GoogleMap
import com.google.maps.android.compose.GoogleMapComposable
// ...

@Composable
fun MountainMap(
    paddingValues: PaddingValues,
    viewState: MountainsScreenViewState.MountainList,
    eventFlow: Flow<MountainsScreenEvent>,
    selectedMarkerType: MarkerType,
) {
    var isMapLoaded by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(paddingValues)
    ) {
        // Add GoogleMap here
        GoogleMap(
            modifier = Modifier.fillMaxSize(),
            onMapLoaded = { isMapLoaded = true }
        )

        // ...
    }
}

এখন অ্যাপটি তৈরি করুন এবং চালান। দেখো! আপনি কুখ্যাত নাল দ্বীপকে কেন্দ্র করে একটি মানচিত্র দেখতে পাবেন, যা অক্ষাংশ শূন্য এবং দ্রাঘিমাংশ শূন্য নামেও পরিচিত। পরবর্তীতে, আপনি শিখবেন কিভাবে মানচিত্রটিকে আপনি যে অবস্থানে এবং জুম স্তরে রাখতে চান, কিন্তু আপাতত আপনার প্রথম বিজয় উদযাপন করুন!

6. ক্লাউড-ভিত্তিক মানচিত্র স্টাইলিং

আপনি ক্লাউড-ভিত্তিক মানচিত্র স্টাইলিং ব্যবহার করে আপনার মানচিত্রের শৈলী কাস্টমাইজ করতে পারেন৷

একটি মানচিত্র আইডি তৈরি করুন

আপনি যদি এটির সাথে সম্পর্কিত একটি মানচিত্র শৈলী সহ একটি মানচিত্র আইডি তৈরি না করে থাকেন তবে নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করতে মানচিত্র আইডি নির্দেশিকাটি দেখুন:

  1. একটি মানচিত্র আইডি তৈরি করুন।
  2. একটি মানচিত্র শৈলীতে একটি মানচিত্র ID সংযুক্ত করুন৷

আপনার অ্যাপে ম্যাপ আইডি যোগ করুন

আপনার তৈরি করা ম্যাপ আইডিটি ব্যবহার করতে, আপনার GoogleMap কম্পোজেবলকে ইনস্ট্যান্ট করার সময়, GoogleMapOptions অবজেক্ট তৈরি করার সময় ম্যাপ আইডিটি ব্যবহার করুন যা কনস্ট্রাক্টরে googleMapOptionsFactory প্যারামিটারে বরাদ্দ করা হয়।

GoogleMap(
    // ...
    googleMapOptionsFactory = {
        GoogleMapOptions().mapId("MyMapId")
    }
)

একবার আপনি এটি সম্পূর্ণ করলে, এগিয়ে যান এবং আপনার নির্বাচিত স্টাইলে আপনার মানচিত্র দেখতে অ্যাপটি চালান!

7. মার্কার ডেটা লোড করুন

অ্যাপটির প্রধান কাজ হল স্থানীয় স্টোরেজ থেকে পাহাড়ের একটি সংগ্রহ লোড করা এবং সেই পাহাড়গুলিকে GoogleMap এ প্রদর্শন করা। এই ধাপে, আপনি পর্বত ডেটা লোড করার জন্য এবং UI-তে উপস্থাপন করার জন্য প্রদত্ত পরিকাঠামোর একটি সফর করবেন।

পর্বত

Mountain ডেটা ক্লাস প্রতিটি পর্বত সম্পর্কে সমস্ত ডেটা ধারণ করে।

data class Mountain(
    val id: Int,
    val name: String,
    val location: LatLng,
    val elevation: Meters,
)

উল্লেখ্য যে পর্বতগুলি পরবর্তীতে তাদের উচ্চতার উপর ভিত্তি করে বিভক্ত হবে। কমপক্ষে 14,000 ফুট উঁচু পর্বতগুলিকে চৌদ্দশত বলা হয়। স্টার্টার কোডে একটি এক্সটেনশন ফাংশন রয়েছে যা আপনার জন্য পরীক্ষা করুন।

/**
 * Extension function to determine whether a mountain is a "14er", i.e., has an elevation greater
 * than 14,000 feet (~4267 meters).
 */
fun Mountain.is14er() = elevation >= 14_000.feet

MountainsScreenViewState

MountainsScreenViewState ক্লাস ভিউ রেন্ডার করার জন্য প্রয়োজনীয় সমস্ত ডেটা ধারণ করে। পর্বত তালিকা লোড করা শেষ হয়েছে কিনা তার উপর নির্ভর করে এটি হয় Loading বা MountainList অবস্থায় হতে পারে।

/**
 * Sealed class representing the state of the mountain map view.
 */
sealed class MountainsScreenViewState {
  data object Loading : MountainsScreenViewState()
  data class MountainList(
    // List of the mountains to display
    val mountains: List<Mountain>,

    // Bounding box that contains all of the mountains
    val boundingBox: LatLngBounds,

    // Switch indicating whether all the mountains or just the 14ers
    val showingAllPeaks: Boolean = false,
  ) : MountainsScreenViewState()
}

প্রদত্ত ক্লাস: MountainsRepository এবং MountainsViewModel

স্টার্টার প্রকল্পে, ক্লাস MountainsRepository আপনার জন্য প্রদান করা হয়েছে। এই ক্লাসটি পর্বত স্থানগুলির একটি তালিকা পড়ে যা একটি GPS Exchange Format , বা GPX ফাইল, top_peaks.gpx সংরক্ষণ করা হয়। mountainsRepository.loadMountains() কল করা একটি StateFlow<List<Mountain>> প্রদান করে।

Mountains Repository

class MountainsRepository(@ApplicationContext val context: Context) {
  private val _mountains = MutableStateFlow(emptyList<Mountain>())
  val mountains: StateFlow<List<Mountain>> = _mountains
  private var loaded = false

  /**
   * Loads the list of mountains from the list of mountains from the raw resource.
   */
  suspend fun loadMountains(): StateFlow<List<Mountain>> {
    if (!loaded) {
      loaded = true
      _mountains.value = withContext(Dispatchers.IO) {
        context.resources.openRawResource(R.raw.top_peaks).use { inputStream ->
          readMountains(inputStream)
        }
      }
    }
    return mountains
  }

  /**
   * Reads the [Waypoint]s from the given [inputStream] and returns a list of [Mountain]s.
   */
  private fun readMountains(inputStream: InputStream) =
    readWaypoints(inputStream).mapIndexed { index, waypoint ->
      waypoint.toMountain(index)
    }.toList()

  // ...
}

MountainsViewModel

MountainsViewModel হল একটি ViewModel ক্লাস যা পাহাড়ের সংগ্রহগুলিকে লোড করে এবং সেই সংগ্রহগুলির পাশাপাশি UI রাজ্যের অন্যান্য অংশগুলি mountainsScreenViewState এর মাধ্যমে প্রকাশ করে৷ mountainsScreenViewState হল একটি হট StateFlow যা UI একটি পরিবর্তনযোগ্য অবস্থা হিসেবে collectAsState এক্সটেনশন ফাংশন ব্যবহার করে পর্যবেক্ষণ করতে পারে।

সাউন্ড আর্কিটেকচারাল নীতি অনুসরণ করে, MountainsViewModel অ্যাপের সমস্ত অবস্থা ধারণ করে। UI onEvent পদ্ধতি ব্যবহার করে ভিউ মডেলে ব্যবহারকারীর ইন্টারঅ্যাকশন পাঠায়।

@HiltViewModel
class MountainsViewModel
@Inject
constructor(
  mountainsRepository: MountainsRepository
) : ViewModel() {
  private val _eventChannel = Channel<MountainsScreenEvent>()

  // Event channel to send events to the UI
  internal fun getEventChannel() = _eventChannel.receiveAsFlow()

  // Whether or not to show all of the high peaks
  private var showAllMountains = MutableStateFlow(false)

  val mountainsScreenViewState =
    mountainsRepository.mountains.combine(showAllMountains) { allMountains, showAllMountains ->
      if (allMountains.isEmpty()) {
        MountainsScreenViewState.Loading
      } else {
        val filteredMountains =
          if (showAllMountains) allMountains else allMountains.filter { it.is14er() }
        val boundingBox = filteredMountains.map { it.location }.toLatLngBounds()
        MountainsScreenViewState.MountainList(
          mountains = filteredMountains,
          boundingBox = boundingBox,
          showingAllPeaks = showAllMountains,
        )
      }
    }.stateIn(
      scope = viewModelScope,
      started = SharingStarted.WhileSubscribed(5000),
      initialValue = MountainsScreenViewState.Loading
    )

  init {
    // Load the full set of mountains
    viewModelScope.launch {
      mountainsRepository.loadMountains()
    }
  }

  // Handle user events
  fun onEvent(event: MountainsViewModelEvent) {
    when (event) {
      OnZoomAll -> onZoomAll()
      OnToggleAllPeaks -> toggleAllPeaks()
    }
  }

  private fun onZoomAll() {
    sendScreenEvent(MountainsScreenEvent.OnZoomAll)
  }

  private fun toggleAllPeaks() {
    showAllMountains.value = !showAllMountains.value
  }

  // Send events back to the UI via the event channel
  private fun sendScreenEvent(event: MountainsScreenEvent) {
    viewModelScope.launch { _eventChannel.send(event) }
  }
}

আপনি যদি এই ক্লাসগুলির বাস্তবায়ন সম্পর্কে আগ্রহী হন তবে আপনি GitHub-এ সেগুলি অ্যাক্সেস করতে পারেন বা Android স্টুডিওতে MountainsRepository এবং MountainsViewModel ক্লাসগুলি খুলতে পারেন৷

ভিউ মডেল ব্যবহার করুন

ভিউ মডেলটি viewState পেতে MainActivity ব্যবহৃত হয়। আপনি এই কোডল্যাবে পরে মার্কার রেন্ডার করতে viewState ব্যবহার করবেন। মনে রাখবেন এই কোডটি ইতিমধ্যেই স্টার্টার প্রকল্পে অন্তর্ভুক্ত করা হয়েছে এবং শুধুমাত্র রেফারেন্সের জন্য এখানে দেখানো হয়েছে।

val viewModel: MountainsViewModel by viewModels()
val screenViewState = viewModel.mountainsScreenViewState.collectAsState()
val viewState = screenViewState.value

8. ক্যামেরার অবস্থান

একটি GoogleMap ডিফল্ট কেন্দ্র অক্ষাংশ শূন্য, দ্রাঘিমাংশ শূন্য. আপনি যে মার্কারগুলিকে রেন্ডার করবেন সেগুলি মার্কিন যুক্তরাষ্ট্রের কলোরাডো রাজ্যে অবস্থিত৷ ভিউ মডেল দ্বারা প্রদত্ত viewState একটি LatLngBounds উপস্থাপন করে যাতে সমস্ত মার্কার থাকে।

MountainMap.kt এ বাউন্ডিং বাক্সের কেন্দ্রে শুরু করা একটি CameraPositionState তৈরি করুন। আপনি এইমাত্র তৈরি করা cameraPositionState ভেরিয়েবলে GoogleMap এর cameraPositionState প্যারামিটার সেট করুন।

fun MountainMap(
    // ...
) {
    // ...
    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(viewState.boundingBox.center, 5f)
    }

    GoogleMap(
        // ...
        cameraPositionState = cameraPositionState,
    )
}

এখন কোডটি চালান এবং কলোরাডোতে মানচিত্র কেন্দ্রটি দেখুন।

মার্কার বিস্তৃতিতে জুম করুন

মার্কারগুলিতে মানচিত্রটিকে সত্যিই ফোকাস করতে MountainMap.kt ফাইলের শেষে zoomAll ফাংশন যোগ করুন। মনে রাখবেন যে এই ফাংশনটির একটি CoroutineScope প্রয়োজন কারণ ক্যামেরাটিকে একটি নতুন অবস্থানে অ্যানিমেট করা একটি অ্যাসিঙ্ক্রোনাস অপারেশন যা সম্পূর্ণ হতে সময় নেয়৷

fun zoomAll(
    scope: CoroutineScope,
    cameraPositionState: CameraPositionState,
    boundingBox: LatLngBounds
) {
    scope.launch {
        cameraPositionState.animate(
            update = CameraUpdateFactory.newLatLngBounds(boundingBox, 64),
            durationMs = 1000
        )
    }
}

এরপরে, যখনই মার্কার সংগ্রহের চারপাশের সীমা পরিবর্তিত হয় বা ব্যবহারকারী যখন TopApp বারে জুম এক্সটেন্ট বোতামে ক্লিক করেন তখন zoomAll ফাংশন চালু করতে কোড যোগ করুন। লক্ষ্য করুন জুম এক্সটেন্ট বোতামটি ভিউ মডেলে ইভেন্টগুলি পাঠাতে ইতিমধ্যেই তারযুক্ত। আপনাকে শুধুমাত্র ভিউ মডেল থেকে সেই ইভেন্টগুলি সংগ্রহ করতে হবে এবং প্রতিক্রিয়া হিসাবে zoomAll ফাংশনটি কল করতে হবে।

এক্সটেনশন বোতাম

fun MountainMap(
    // ...
) {
    // ...
    val scope = rememberCoroutineScope()

    LaunchedEffect(key1 = viewState.boundingBox) {
        zoomAll(scope, cameraPositionState, viewState.boundingBox)
    }

    LaunchedEffect(true) {
        eventFlow.collect { event ->
            when (event) {
                MountainsScreenEvent.OnZoomAll -> {
                    zoomAll(scope, cameraPositionState, viewState.boundingBox)
                }
            }
        }
    }
}

এখন আপনি যখন অ্যাপটি চালাবেন, তখন মানচিত্রটি যেখানে মার্কারগুলি যাবে সেখানে ফোকাস করা শুরু হবে৷ আপনি জুমকে পুনঃস্থাপন এবং পরিবর্তন করতে পারেন এবং জুম এক্সটেনস বোতামে ক্লিক করলে মার্কার এলাকার চারপাশে মানচিত্রটিকে পুনরায় ফোকাস করা হবে। যে এগিয়ে অগ্রগতি! কিন্তু মানচিত্রে সত্যিই কিছু দেখতে হবে. এবং পরবর্তী ধাপে আপনি এটিই করবেন!

9. মৌলিক মার্কার

এই ধাপে, আপনি মানচিত্রের সাথে মার্কার যোগ করুন যা আপনি মানচিত্রে হাইলাইট করতে চান এমন আগ্রহের পয়েন্টগুলিকে প্রতিনিধিত্ব করে৷ আপনি স্টার্টার প্রকল্পে দেওয়া পর্বতগুলির তালিকা ব্যবহার করবেন এবং এই স্থানগুলিকে মানচিত্রে চিহ্নিতকারী হিসাবে যুক্ত করবেন।

GoogleMap এ একটি বিষয়বস্তু ব্লক যোগ করে শুরু করুন। একাধিক মার্কারের ধরন থাকবে, তাই প্রতিটি টাইপের শাখায় একটি when বিবৃতি যোগ করুন এবং আপনি প্রতিটি ধাপে ধাপে ধাপে বাস্তবায়ন করবেন।

GoogleMap(
    // ...
) {
    when (selectedMarkerType) {
        MarkerType.Basic -> {
            BasicMarkersMapContent(
                mountains = viewState.mountains,
            )
        }

        MarkerType.Advanced -> {
            AdvancedMarkersMapContent(
                mountains = viewState.mountains,
            )
        }

        MarkerType.Clustered -> {
            ClusteringMarkersMapContent(
                mountains = viewState.mountains,
            )
        }
    }
}

মার্কার যোগ করুন

@GoogleMapComposable সাথে BasicMarkersMapContent টীকা করুন। মনে রাখবেন যে আপনি GoogleMap সামগ্রী ব্লকে @GoogleMapComposable ফাংশন ব্যবহার করতে সীমাবদ্ধ। mountains বস্তুর Mountain বস্তুর একটি তালিকা আছে। আপনি Mountain অবজেক্ট থেকে অবস্থান, নাম এবং উচ্চতা ব্যবহার করে সেই তালিকায় প্রতিটি পর্বতের জন্য একটি মার্কার যোগ করবেন। অবস্থানটি Marker স্টেট প্যারামিটার সেট করতে ব্যবহৃত হয় যা ঘুরে, মার্কারের অবস্থান নিয়ন্ত্রণ করে।

// ...
import com.google.android.gms.maps.model.Marker
import com.google.maps.android.compose.GoogleMapComposable
import com.google.maps.android.compose.Marker
import com.google.maps.android.compose.rememberMarkerState

@Composable
@GoogleMapComposable
fun BasicMarkersMapContent(
    mountains: List<Mountain>,
    onMountainClick: (Marker) -> Boolean = { false }
) {
    mountains.forEach { mountain ->
        Marker(
            state = rememberMarkerState(position = mountain.location),
            title = mountain.name,
            snippet = mountain.elevation.toElevationString(),
            tag = mountain,
            onClick = { marker ->
                onMountainClick(marker)
                false
            },
            zIndex = if (mountain.is14er()) 5f else 2f
        )
    }
}

এগিয়ে যান এবং অ্যাপটি চালান আপনি এইমাত্র যোগ করা মার্কারগুলি দেখতে পাবেন!

মার্কার কাস্টমাইজ করুন

মার্কারগুলির জন্য বেশ কয়েকটি কাস্টমাইজেশন বিকল্প রয়েছে যা আপনি এইমাত্র যোগ করেছেন যাতে তাদের আলাদা হতে এবং ব্যবহারকারীদের কাছে দরকারী তথ্য পৌঁছে দিতে সহায়তা করে৷ এই টাস্কে, আপনি প্রতিটি মার্কারের ইমেজ কাস্টমাইজ করে এর মধ্যে কয়েকটি অন্বেষণ করবেন।

স্টার্টার প্রজেক্টে একটি হেল্পার ফাংশন রয়েছে, vectorToBitmap , একটি @DrawableResource থেকে BitmapDescriptor তৈরি করতে।

স্টার্টার কোডে একটি পর্বত আইকন রয়েছে, baseline_filter_hdr_24.xml , যা আপনি মার্কারগুলিকে কাস্টমাইজ করতে ব্যবহার করবেন৷

vectorToBitmap ফাংশন মানচিত্র লাইব্রেরির সাথে ব্যবহারের জন্য একটি ভেক্টরকে অঙ্কনযোগ্য BitmapDescriptor রূপান্তর করে। আইকনের রঙগুলি একটি BitmapParameters উদাহরণ ব্যবহার করে সেট করা হয়।

data class BitmapParameters(
    @DrawableRes val id: Int,
    @ColorInt val iconColor: Int,
    @ColorInt val backgroundColor: Int? = null,
    val backgroundAlpha: Int = 168,
    val padding: Int = 16,
)

fun vectorToBitmap(context: Context, parameters: BitmapParameters): BitmapDescriptor {
    // ...
}

দুটি কাস্টমাইজড BitmapDescriptor তৈরি করতে vectorToBitmap ফাংশনটি ব্যবহার করুন; একটি চৌদ্দ বছরের জন্য এবং একটি নিয়মিত পাহাড়ের জন্য। তারপর আইকন সেট করতে Marker composable এর icon প্যারামিটার ব্যবহার করুন। এছাড়াও, আইকনের সাথে সম্পর্কিত অ্যাঙ্কর অবস্থান পরিবর্তন করতে anchor প্যারামিটার সেট করুন। কেন্দ্র ব্যবহার করা এই বৃত্তাকার আইকনগুলির জন্য আরও ভাল কাজ করে।

@Composable
@GoogleMapComposable
fun BasicMarkersMapContent(
    // ...
) {
    // Create mountainIcon and fourteenerIcon
    val mountainIcon = vectorToBitmap(
        LocalContext.current,
        BitmapParameters(
            id = R.drawable.baseline_filter_hdr_24,
            iconColor = MaterialTheme.colorScheme.secondary.toArgb(),
            backgroundColor = MaterialTheme.colorScheme.secondaryContainer.toArgb(),
        )
    )

    val fourteenerIcon = vectorToBitmap(
        LocalContext.current,
        BitmapParameters(
            id = R.drawable.baseline_filter_hdr_24,
            iconColor = MaterialTheme.colorScheme.onPrimary.toArgb(),
            backgroundColor = MaterialTheme.colorScheme.primary.toArgb(),
        )
    )

    mountains.forEach { mountain ->
        val icon = if (mountain.is14er()) fourteenerIcon else mountainIcon
        Marker(
            // ...
            anchor = Offset(0.5f, 0.5f),
            icon = icon,
        )
    }
}

অ্যাপটি চালান এবং কাস্টমাইজড মার্কারগুলিতে বিস্মিত হন। পাহাড়ের সম্পূর্ণ সেট দেখতে Show all সুইচটি টগল করুন। পাহাড়ের উপর নির্ভর করে বিভিন্ন মার্কার থাকবে একটি চৌদ্দশত।

10. উন্নত মার্কার

AdvancedMarker গুলি মৌলিক Markers অতিরিক্ত বৈশিষ্ট্য যোগ করে। এই ধাপে, আপনি সংঘর্ষের আচরণ সেট করবেন এবং পিন শৈলী কনফিগার করবেন।

AdvancedMarkersMapContent ফাংশনে @GoogleMapComposable যোগ করুন। প্রতিটির জন্য একটি AdvancedMarker যোগ করে mountains উপর লুপ করুন।

@Composable
@GoogleMapComposable
fun AdvancedMarkersMapContent(
    mountains: List<Mountain>,
    onMountainClick: (Marker) -> Boolean = { false },
) {
    mountains.forEach { mountain ->
        AdvancedMarker(
            state = rememberMarkerState(position = mountain.location),
            title = mountain.name,
            snippet = mountain.elevation.toElevationString(),
            collisionBehavior = AdvancedMarkerOptions.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL,
            onClick = { marker ->
                onMountainClick(marker)
                false
            }
        )
    }
}

collisionBehavior প্যারামিটারটি লক্ষ্য করুন। এই প্যারামিটারটিকে REQUIRED_AND_HIDES_OPTIONAL এ সেট করার মাধ্যমে, আপনার মার্কার যেকোনো নিম্ন অগ্রাধিকার মার্কারকে প্রতিস্থাপন করবে। আপনি একটি উন্নত মার্কার তুলনায় একটি মৌলিক মার্কার জুম দ্বারা এটি দেখতে পারেন. বেসিক মার্কারে সম্ভবত আপনার মার্কার এবং মার্কার উভয়ই বেস মানচিত্রে একই অবস্থানে স্থাপন করা হবে। উন্নত মার্কার নিম্ন অগ্রাধিকার চিহ্নিতকারীকে লুকিয়ে রাখবে।

অ্যাডভান্সড মার্কার দেখতে অ্যাপটি চালান। নীচের নেভিগেশন সারিতে Advanced markers ট্যাবটি নির্বাচন করতে ভুলবেন না।

কাস্টমাইজড AdvancedMarkers

আইকনগুলি চৌদ্দ বছরের এবং অন্যান্য পর্বতের মধ্যে পার্থক্য করার জন্য প্রাথমিক এবং মাধ্যমিক রঙের স্কিম ব্যবহার করে। দুটি BitmapDescriptor s তৈরি করতে vectorToBitmap ফাংশন ব্যবহার করুন; একটি চৌদ্দ বছরের জন্য এবং একটি অন্য পর্বতদের জন্য। প্রতিটি ধরনের জন্য একটি কাস্টম pinConfig তৈরি করতে সেই আইকনগুলি ব্যবহার করুন। অবশেষে, is14er() ফাংশনের উপর ভিত্তি করে সংশ্লিষ্ট AdvancedMarker এ পিনটি প্রয়োগ করুন।

@Composable
@GoogleMapComposable
fun AdvancedMarkersMapContent(
    mountains: List<Mountain>,
    onMountainClick: (Marker) -> Boolean = { false },
) {
    val mountainIcon = vectorToBitmap(
        LocalContext.current,
        BitmapParameters(
            id = R.drawable.baseline_filter_hdr_24,
            iconColor = MaterialTheme.colorScheme.onSecondary.toArgb(),
        )
    )

    val mountainPin = with(PinConfig.builder()) {
        setGlyph(PinConfig.Glyph(mountainIcon))
        setBackgroundColor(MaterialTheme.colorScheme.secondary.toArgb())
        setBorderColor(MaterialTheme.colorScheme.onSecondary.toArgb())
        build()
    }

    val fourteenerIcon = vectorToBitmap(
        LocalContext.current,
        BitmapParameters(
            id = R.drawable.baseline_filter_hdr_24,
            iconColor = MaterialTheme.colorScheme.onPrimary.toArgb(),
        )
    )

    val fourteenerPin = with(PinConfig.builder()) {
        setGlyph(PinConfig.Glyph(fourteenerIcon))
        setBackgroundColor(MaterialTheme.colorScheme.primary.toArgb())
        setBorderColor(MaterialTheme.colorScheme.onPrimary.toArgb())
        build()
    }

    mountains.forEach { mountain ->
        val pin = if (mountain.is14er()) fourteenerPin else mountainPin
        AdvancedMarker(
            state = rememberMarkerState(position = mountain.location),
            title = mountain.name,
            snippet = mountain.elevation.toElevationString(),
            collisionBehavior = AdvancedMarkerOptions.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL,
            pinConfig = pin,
            onClick = { marker ->
                onMountainClick(marker)
                false
            }
        )
    }
}

11. ক্লাস্টার মার্কার

এই ধাপে, আপনি জুম-ভিত্তিক আইটেম গ্রুপিং যোগ করতে Clustering কম্পোজেবল ব্যবহার করবেন।

Clustering কম্পোজেবলের জন্য ClusterItem s এর সংগ্রহ প্রয়োজন। MountainClusterItem ClusterItem ইন্টারফেস প্রয়োগ করে। ClusteringMarkersMapContent.kt ফাইলে এই ক্লাসটি যুক্ত করুন।

data class MountainClusterItem(
    val mountain: Mountain,
    val snippetString: String
) : ClusterItem {
    override fun getPosition() = mountain.location
    override fun getTitle() = mountain.name
    override fun getSnippet() = snippetString
    override fun getZIndex() = 0f
}

এখন পাহাড়ের তালিকা থেকে MountainClusterItem s তৈরি করতে কোড যোগ করুন। নোট করুন এই কোডটি তাদের লোকেলের উপর ভিত্তি করে ব্যবহারকারীর জন্য উপযুক্ত প্রদর্শন ইউনিটে রূপান্তর করতে একটি UnitsConverter ব্যবহার করে। এটি একটি CompositionLocal ব্যবহার করে MainActivity এ সেট আপ করা হয়েছে

@OptIn(MapsComposeExperimentalApi::class)
@Composable
@GoogleMapComposable
fun ClusteringMarkersMapContent(
    mountains: List<Mountain>,
    // ...
) {
    val unitsConverter = LocalUnitsConverter.current
    val resources = LocalContext.current.resources

    val mountainClusterItems by remember(mountains) {
        mutableStateOf(
            mountains.map { mountain ->
                MountainClusterItem(
                    mountain = mountain,
                    snippetString = unitsConverter.toElevationString(resources, mountain.elevation)
                )
            }
        )
    }

    Clustering(
        items = mountainClusterItems,
    )
}

এবং সেই কোডের সাথে, মার্কারগুলি জুম-স্তরের উপর ভিত্তি করে ক্লাস্টার করা হয়। সুন্দর এবং পরিপাটি!

ক্লাস্টার কাস্টমাইজ করুন

অন্যান্য মার্কার প্রকারের মতো, ক্লাস্টারযুক্ত মার্কারগুলি কাস্টমাইজযোগ্য। Clustering কম্পোজেবলের clusterItemContent প্যারামিটার একটি নন-ক্লাস্টারড আইটেম রেন্ডার করার জন্য একটি কাস্টম কম্পোজেবল ব্লক সেট করে। মার্কার তৈরি করতে একটি @Composable ফাংশন প্রয়োগ করুন। SingleMountain ফাংশন একটি কাস্টমাইজড ব্যাকগ্রাউন্ড কালার স্কিম সহ একটি সংমিশ্রণযোগ্য উপাদান 3 Icon রেন্ডার করে।

ClusteringMarkersMapContent.kt এ, একটি মার্কারের রঙের স্কিম সংজ্ঞায়িত করে একটি ডেটা ক্লাস তৈরি করুন:

data class IconColor(val iconColor: Color, val backgroundColor: Color, val borderColor: Color)

এছাড়াও, ClusteringMarkersMapContent.kt এ একটি প্রদত্ত রঙের স্কিমের জন্য একটি আইকন রেন্ডার করার জন্য একটি সংমিশ্রণযোগ্য ফাংশন তৈরি করুন:

@Composable
private fun SingleMountain(
    colors: IconColor,
) {
    Icon(
        painterResource(id = R.drawable.baseline_filter_hdr_24),
        tint = colors.iconColor,
        contentDescription = "",
        modifier = Modifier
            .size(32.dp)
            .padding(1.dp)
            .drawBehind {
                drawCircle(color = colors.backgroundColor, style = Fill)
                drawCircle(color = colors.borderColor, style = Stroke(width = 3f))
            }
            .padding(4.dp)
    )
}

এখন চৌদ্দ বছরের জন্য একটি রঙের স্কিম তৈরি করুন এবং অন্যান্য পর্বতের জন্য আরেকটি রঙের স্কিম তৈরি করুন। clusterItemContent ব্লকে, প্রদত্ত পর্বতটি চৌদ্দটি কিনা তার উপর ভিত্তি করে রঙের স্কিমটি নির্বাচন করুন।

fun ClusteringMarkersMapContent(
    mountains: List<Mountain>,
    // ...
) {
  // ...

  val backgroundAlpha = 0.6f

  val fourteenerColors = IconColor(
      iconColor = MaterialTheme.colorScheme.onPrimary,
      backgroundColor = MaterialTheme.colorScheme.primary.copy(alpha = backgroundAlpha),
      borderColor = MaterialTheme.colorScheme.primary
  )

  val otherColors = IconColor(
      iconColor = MaterialTheme.colorScheme.secondary,
      backgroundColor = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = backgroundAlpha),
      borderColor = MaterialTheme.colorScheme.secondary
  )

  // ...
  Clustering(
      items = mountainClusterItems,
      clusterItemContent = { mountainItem ->
          val colors = if (mountainItem.mountain.is14er()) {
              fourteenerColors
          } else {
              otherColors
          }
          SingleMountain(colors)
      },
  )
}

এখন, পৃথক আইটেমগুলির কাস্টমাইজড সংস্করণ দেখতে অ্যাপটি চালান।

12. মানচিত্রে আঁকুন

আপনি ইতিমধ্যে মানচিত্রে আঁকার একটি উপায় অন্বেষণ করেছেন (মার্কার যোগ করে), Android এর জন্য Maps SDK ম্যাপে দরকারী তথ্য প্রদর্শন করার জন্য আপনি আঁকতে পারেন এমন আরও অনেক উপায় সমর্থন করে৷

উদাহরণস্বরূপ, আপনি যদি মানচিত্রে রুট এবং এলাকাগুলিকে উপস্থাপন করতে চান, তাহলে আপনি Polyline এবং Polygon ব্যবহার করতে পারেন এইগুলি মানচিত্রে প্রদর্শন করতে। অথবা, আপনি যদি মাটির পৃষ্ঠে একটি চিত্র ঠিক করতে চান, আপনি একটি GroundOverlay ব্যবহার করতে পারেন।

এই কাজটিতে, আপনি শিখবেন কিভাবে আকৃতি আঁকতে হয়, বিশেষ করে কলোরাডো রাজ্যের চারপাশে একটি রূপরেখা। কলোরাডো সীমানাকে 37°N এবং 41°N অক্ষাংশ এবং 102°03'W এবং 109°03'W এর মধ্যে সংজ্ঞায়িত করা হয়েছে। এটি রূপরেখা অঙ্কনকে বেশ সহজবোধ্য করে তোলে।

স্টার্টার কোডে ডিগ্রী-মিনিট-সেকেন্ড নোটেশন থেকে দশমিক ডিগ্রীতে রূপান্তর করার জন্য একটি DMS ক্লাস অন্তর্ভুক্ত রয়েছে।

enum class Direction(val sign: Int) {
    NORTH(1),
    EAST(1),
    SOUTH(-1),
    WEST(-1)
}

/**
 * Degrees, minutes, seconds utility class
 */
data class DMS(
    val direction: Direction,
    val degrees: Double,
    val minutes: Double = 0.0,
    val seconds: Double = 0.0,
)

fun DMS.toDecimalDegrees(): Double =
    (degrees + (minutes / 60) + (seconds / 3600)) * direction.sign

ডিএমএস ক্লাসের সাহায্যে, আপনি চার কোণার LatLng অবস্থান সংজ্ঞায়িত করে এবং একটি Polygon হিসাবে রেন্ডার করে কলোরাডোর সীমানা আঁকতে পারেন। MountainMap.kt এ নিম্নলিখিত কোড যোগ করুন

@Composable
@GoogleMapComposable
fun ColoradoPolygon() {
    val north = 41.0
    val south = 37.0
    val east = DMS(WEST, 102.0, 3.0).toDecimalDegrees()
    val west = DMS(WEST, 109.0, 3.0).toDecimalDegrees()

    val locations = listOf(
        LatLng(north, east),
        LatLng(south, east),
        LatLng(south, west),
        LatLng(north, west),
    )

    Polygon(
        points = locations,
        strokeColor = MaterialTheme.colorScheme.tertiary,
        strokeWidth = 3F,
        fillColor = MaterialTheme.colorScheme.tertiaryContainer.copy(alpha = 0.3f),
    )
}

এখন GoogleMap কন্টেন্ট ব্লকের ভিতরে ColoradoPolyon() কল করুন।

@Composable
fun MountainMap(
    // ...
) {
   Box(
    // ...
    ) {
        GoogleMap(
            // ...
        ) {
            ColoradoPolygon()
        }
    }
}

এখন অ্যাপটি কলোরাডো রাজ্যের রূপরেখা দেয় যখন এটি একটি সূক্ষ্ম পূরণ করে।

13. একটি KML স্তর এবং স্কেল বার যোগ করুন

এই চূড়ান্ত বিভাগে আপনি মোটামুটিভাবে বিভিন্ন পর্বতশ্রেণীর রূপরেখা দেবেন এবং মানচিত্রে একটি স্কেল বার যুক্ত করবেন।

পর্বতশ্রেণীর রূপরেখা দাও

পূর্বে, আপনি কলোরাডোর চারপাশে একটি রূপরেখা আঁকেন। এখানে আপনি মানচিত্রে আরো জটিল আকার যোগ করতে যাচ্ছেন। স্টার্টার কোডে একটি কীহোল মার্কআপ ল্যাঙ্গুয়েজ বা KML ফাইল রয়েছে যা মোটামুটিভাবে গুরুত্বপূর্ণ পর্বতমালার রূপরেখা দেয়। অ্যান্ড্রয়েড ইউটিলিটি লাইব্রেরির জন্য মানচিত্র SDK-এ মানচিত্রে একটি KML স্তর যুক্ত করার জন্য একটি ফাংশন রয়েছে৷ MountainMap.ktwhen ব্লকের পরে GoogleMap সামগ্রী ব্লকে একটি MapEffect কল যোগ করুন। MapEffect ফাংশন একটি GoogleMap অবজেক্টের সাথে বলা হয়। এটি অ-কম্পোজযোগ্য API এবং লাইব্রেরির মধ্যে একটি দরকারী সেতু হিসাবে কাজ করতে পারে যার জন্য একটি GoogleMap অবজেক্ট প্রয়োজন।

  fun MountainMap(
    // ...
) {
    var isMapLoaded by remember { mutableStateOf(false) }
    val context = LocalContext.current

    GoogleMap(
      // ...
    ) {
      // ...

      when (selectedMarkerType) {
        // ...
      }

      // This code belongs inside the GoogleMap content block, but outside of
      // the 'when' statement
      MapEffect(key1 = true) {map ->
          val layer = KmlLayer(map, R.raw.mountain_ranges, context)
          layer.addLayerToMap()
      }
    }

একটি মানচিত্র স্কেল যোগ করুন

আপনার চূড়ান্ত কাজ হিসাবে, আপনি মানচিত্রে একটি স্কেল যোগ করবেন। ScaleBar একটি কম্পোজযোগ্য স্কেল প্রয়োগ করে যা মানচিত্রে যোগ করা যেতে পারে। উল্লেখ্য, ScaleBar একটি নয়

@GoogleMapComposable এবং তাই GoogleMap সামগ্রীতে যোগ করা যাবে না। আপনি পরিবর্তে মানচিত্র ধারণ করা Box এটি যোগ করুন।

Box(
  // ...
) {
    GoogleMap(
      // ...
    ) {
        // ...
    }

    ScaleBar(
        modifier = Modifier
            .padding(top = 5.dp, end = 15.dp)
            .align(Alignment.TopEnd),
        cameraPositionState = cameraPositionState
    )
    // ...
}

সম্পূর্ণরূপে বাস্তবায়িত কোডল্যাব দেখতে অ্যাপটি চালান।

14. সমাধান কোড পান

সমাপ্ত কোডল্যাবের জন্য কোড ডাউনলোড করতে, আপনি এই কমান্ডগুলি ব্যবহার করতে পারেন:

  1. আপনি যদি git ইনস্টল করে থাকেন তবে সংগ্রহস্থল ক্লোন করুন।
$ git clone https://github.com/googlemaps-samples/codelab-maps-platform-101-compose.git

বিকল্পভাবে, আপনি সোর্স কোড ডাউনলোড করতে নিম্নলিখিত বোতামে ক্লিক করতে পারেন।

  1. কোড পাওয়ার পরে, এগিয়ে যান এবং অ্যান্ড্রয়েড স্টুডিওতে solution ডিরেক্টরিতে পাওয়া প্রকল্পটি খুলুন।

15. অভিনন্দন

অভিনন্দন! আপনি অনেক কন্টেন্ট কভার করেছেন এবং আশা করি আপনি Android এর জন্য Maps SDK-এ দেওয়া মূল বৈশিষ্ট্যগুলি সম্পর্কে আরও ভালভাবে বুঝতে পেরেছেন।

আরও জানুন

  • Android এর জন্য Maps SDK - আপনার Android অ্যাপের জন্য গতিশীল, ইন্টারেক্টিভ, কাস্টমাইজ করা মানচিত্র, অবস্থান এবং ভূ-স্থানিক অভিজ্ঞতা তৈরি করুন।
  • মানচিত্র রচনা লাইব্রেরি - ওপেন সোর্স কম্পোজযোগ্য ফাংশন এবং ডেটা প্রকারের একটি সেট যা আপনি জেটপ্যাক রচনার সাথে আপনার অ্যাপ তৈরি করতে ব্যবহার করতে পারেন৷
  • android-maps-compose - GitHub-এ নমুনা কোড এই কোডল্যাবে আচ্ছাদিত সমস্ত বৈশিষ্ট্য প্রদর্শন করে এবং আরও অনেক কিছু।
  • Google মানচিত্র প্ল্যাটফর্মের সাথে অ্যান্ড্রয়েড অ্যাপ তৈরির জন্য আরও কোটলিন কোডল্যাব