1. शुरू करने से पहले
ऐब्स्ट्रैक्ट
इस कोडलैब में, आपको यह सिखाया जाएगा कि Android पर ऑगमेंटेड रिएलिटी (एआर) में आस-पास की जगहों को दिखाने के लिए, Google Maps Platform से मिले डेटा का इस्तेमाल कैसे करें.
ज़रूरी शर्तें
- Android Studio का इस्तेमाल करके, Android डेवलपमेंट की बुनियादी जानकारी
- Kotlin की जानकारी
आपको क्या सीखने को मिलेगा
- डिवाइस के कैमरे और जगह की जानकारी को ऐक्सेस करने के लिए, उपयोगकर्ता से अनुमति मांगें.
- डिवाइस की जगह की जानकारी के आस-पास की जगहों की जानकारी पाने के लिए, Places API के साथ इंटिग्रेट करें.
- हॉरिजॉन्टल प्लेन वाली सतहों का पता लगाने के लिए, ARCore के साथ इंटिग्रेट करें. इससे वर्चुअल ऑब्जेक्ट को Sceneform का इस्तेमाल करके, 3D स्पेस में ऐंकर और प्लेस किया जा सकता है.
- SensorManager का इस्तेमाल करके, डिवाइस की जगह की जानकारी इकट्ठा करें. साथ ही, Maps SDK for Android Utility Library का इस्तेमाल करके, वर्चुअल ऑब्जेक्ट को सही हेडिंग पर रखें.
आपको इन चीज़ों की ज़रूरत होगी
- Android Studio 2020.3.1 या इसके बाद का वर्शन
- OpenGL ES 3.0 या इसके बाद के वर्शन के साथ काम करने वाली डेवलपमेंट मशीन
- ARCore की सुविधा के साथ काम करने वाला डिवाइस या ARCore की सुविधा के साथ काम करने वाला Android Emulator. इसके बारे में अगले चरण में बताया गया है
2. सेट अप करें
Android Studio
इस कोडलैब में Android 10.0 (एपीआई लेवल 29) का इस्तेमाल किया गया है. इसके लिए, आपके पास Android Studio में Google Play services इंस्टॉल होना ज़रूरी है. इन दोनों डिपेंडेंसी को इंस्टॉल करने के लिए, यह तरीका अपनाएं:
- एसडीके मैनेजर पर जाएं. इसे ऐक्सेस करने के लिए, Tools > SDK Manager पर क्लिक करें.
- देखें कि Android 10.0 इंस्टॉल है या नहीं. अगर ऐसा नहीं है, तो Android 10.0 (Q) के बगल में मौजूद चेकबॉक्स को चुनकर इसे इंस्टॉल करें. इसके बाद, ठीक है पर क्लिक करें. आखिर में, दिखने वाले डायलॉग बॉक्स में फिर से ठीक है पर क्लिक करें.
- आखिर में, Google Play services इंस्टॉल करें. इसके लिए, एसडीके टूल टैब पर जाएं. इसके बाद, Google Play services के बगल में मौजूद चेकबॉक्स को चुनें. इसके बाद, ठीक है पर क्लिक करें. इसके बाद, दिखने वाले डायलॉग में ठीक है को फिर से चुनें**.**
ज़रूरी एपीआई
इस कोडलैब के लिए, यहां दिए गए सेक्शन के तीसरे चरण में जाकर Android के लिए Maps SDK और Places API चालू करें.
Google Maps Platform का इस्तेमाल शुरू करना
अगर आपने पहले कभी Google Maps Platform का इस्तेमाल नहीं किया है, तो Google Maps Platform का इस्तेमाल शुरू करने से जुड़ी गाइड पढ़ें या Google Maps Platform का इस्तेमाल शुरू करने से जुड़ी प्लेलिस्ट देखें. इसके बाद, यहां दिया गया तरीका अपनाएं:
- बिलिंग खाता बनाएं.
- प्रोजेक्ट बनाएं.
- Google Maps Platform API और SDK टूल चालू करें. इनकी सूची पिछले सेक्शन में दी गई है.
- एपीआई पासकोड जनरेट करें.
ज़रूरी नहीं है: Android Emulator
अगर आपके पास ARCore की सुविधा वाला डिवाइस नहीं है, तो Android Emulator का इस्तेमाल करके, एआर सीन को सिम्युलेट किया जा सकता है. साथ ही, अपने डिवाइस की जगह की जानकारी को फ़र्ज़ी बनाया जा सकता है. इस अभ्यास में Sceneform का इस्तेमाल किया जाएगा. इसलिए, आपको यह भी पक्का करना होगा कि आपने "Sceneform के साथ काम करने के लिए, एम्युलेटर को कॉन्फ़िगर करें" में दिए गए चरणों का पालन किया हो.
3. तुरंत शुरू करना
इस कोडलैब को जल्द से जल्द शुरू करने के लिए, यहां कुछ शुरुआती कोड दिए गए हैं. आपके पास सीधे समाधान पर जाने का विकल्प है. हालांकि, अगर आपको सभी चरण देखने हैं, तो पढ़ते रहें.
अगर आपने git
इंस्टॉल किया है, तो रिपॉज़िटरी को क्लोन किया जा सकता है.
git clone https://github.com/googlecodelabs/display-nearby-places-ar-android.git
इसके अलावा, सोर्स कोड को डाउनलोड करने के लिए, यहां दिए गए बटन पर क्लिक करें.
कोड मिलने के बाद, starter
डायरेक्ट्री में मौजूद प्रोजेक्ट खोलें.
4. प्रोजेक्ट अवलोकन
पिछले चरण में डाउनलोड किए गए कोड को एक्सप्लोर करें. इस रिपॉज़िटरी में, आपको app
नाम का एक मॉड्यूल दिखेगा. इसमें com.google.codelabs.findnearbyplacesar
पैकेज शामिल है.
AndroidManifest.xml
इस कोडलैब में ज़रूरी सुविधाओं का इस्तेमाल करने के लिए, AndroidManifest.xml
फ़ाइल में ये एट्रिब्यूट तय किए गए हैं:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Sceneform requires OpenGL ES 3.0 or later. -->
<uses-feature
android:glEsVersion="0x00030000"
android:required="true" />
<!-- Indicates that app requires ARCore ("AR Required"). Ensures the app is visible only in the Google Play Store on devices that support ARCore. For "AR Optional" apps remove this line. -->
<uses-feature android:name="android.hardware.camera.ar" />
uses-permission
के लिए, यह बताया गया है कि इन सुविधाओं का इस्तेमाल करने से पहले, उपयोगकर्ता को कौनसी अनुमतियां देनी होंगी. इसके बारे में यहां बताया गया है:
android.permission.INTERNET
—इससे आपका ऐप्लिकेशन, नेटवर्क ऑपरेशन कर सकता है और इंटरनेट पर डेटा फ़ेच कर सकता है. जैसे, Places API के ज़रिए जगहों की जानकारी.android.permission.CAMERA
—कैमरे का ऐक्सेस ज़रूरी है, ताकि डिवाइस के कैमरे का इस्तेमाल करके ऑगमेंटेड रिएलिटी में ऑब्जेक्ट दिखाए जा सकें.android.permission.ACCESS_FINE_LOCATION
—जगह की जानकारी का ऐक्सेस ज़रूरी है, ताकि डिवाइस की जगह की जानकारी के हिसाब से आस-पास की जगहों का पता लगाया जा सके.
uses-feature
के लिए, यह बताया गया है कि इस ऐप्लिकेशन को कौनसी हार्डवेयर सुविधाएं चाहिए. इसके लिए, ये सुविधाएं बताई गई हैं:
- OpenGL ES वर्शन 3.0 ज़रूरी है.
- इसके लिए, ARCore की सुविधा वाला डिवाइस होना ज़रूरी है.
इसके अलावा, ऐप्लिकेशन ऑब्जेक्ट में ये मेटाडेटा टैग जोड़े जाते हैं:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
Indicates that this app requires Google Play Services for AR ("AR Required") and causes
the Google Play Store to download and install Google Play Services for AR along with
the app. For an "AR Optional" app, specify "optional" instead of "required".
-->
<meta-data
android:name="com.google.ar.core"
android:value="required" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<!-- Additional elements here -->
</application>
पहली मेटा-डेटा एंट्री से यह पता चलता है कि इस ऐप्लिकेशन को चलाने के लिए ARCore ज़रूरी है. वहीं, दूसरी एंट्री से यह पता चलता है कि Maps SDK for Android को Google Maps Platform API पासकोड कैसे दिया जाता है.
build.gradle
build.gradle
में, ये अतिरिक्त डिपेंडेंसी बताई गई हैं:
dependencies {
// Maps & Location
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.maps.android:maps-utils-ktx:1.7.0'
// ARCore
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.15.0"
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.7.1"
implementation "com.squareup.retrofit2:converter-gson:2.7.1"
}
यहां हर डिपेंडेंसी के बारे में कम शब्दों में जानकारी दी गई है:
- ग्रुप आईडी
com.google.android.gms
वाली लाइब्रेरी, जैसे किplay-services-location
औरplay-services-maps
का इस्तेमाल, डिवाइस की जगह की जानकारी को ऐक्सेस करने और Google Maps से जुड़ी सुविधाओं को ऐक्सेस करने के लिए किया जाता है. com.google.maps.android:maps-utils-ktx
, Maps SDK for Android Utility Library के लिए Kotlin एक्सटेंशन (KTX) लाइब्रेरी है. इस लाइब्रेरी में इस फ़ंक्शन का इस्तेमाल, वर्चुअल ऑब्जेक्ट को असल जगह पर रखने के लिए किया जाएगा.com.google.ar.sceneform.ux:sceneform-ux
, Sceneform लाइब्रेरी है. इसकी मदद से, आपको OpenGL के बारे में जाने बिना ही, असली जैसे दिखने वाले 3D सीन रेंडर करने की सुविधा मिलेगी.- ग्रुप आईडी
com.squareup.retrofit2
में मौजूद डिपेंडेंसी, Retrofit डिपेंडेंसी हैं. इनकी मदद से, Places API के साथ इंटरैक्ट करने के लिए, एचटीटीपी क्लाइंट को तुरंत लिखा जा सकता है.
प्रोजेक्ट का स्ट्रक्चर
यहां आपको ये पैकेज और फ़ाइलें मिलेंगी:
- **api—**इस पैकेज में ऐसी क्लास होती हैं जिनका इस्तेमाल, Retrofit का इस्तेमाल करके Places API से इंटरैक्ट करने के लिए किया जाता है.
- **ar—**इस पैकेज में ARCore से जुड़ी सभी फ़ाइलें होती हैं.
- **मॉडल—**इस पैकेज में एक डेटा क्लास
Place
शामिल है. इसका इस्तेमाल, Places API से मिले किसी एक प्लेस की जानकारी को कैप्सूल करने के लिए किया जाता है. - MainActivity.kt—यह आपके ऐप्लिकेशन में मौजूद एक
Activity
है. यह मैप और कैमरे का व्यू दिखाएगा.
5. सीन सेट अप करना
ऑगमेंटेड रिएलिटी (एआर) वाले कॉम्पोनेंट से शुरू करके, ऐप्लिकेशन के मुख्य कॉम्पोनेंट के बारे में जानें.
MainActivity
में एक SupportMapFragment
होता है, जो मैप ऑब्जेक्ट को दिखाने का काम करता है. साथ ही, इसमें ArFragment
—PlacesArFragment
—की एक सबक्लास होती है, जो ऑगमेंटेड रिएलिटी सीन को दिखाने का काम करती है.
ऑगमेंटेड रिएलिटी (एआर) सेटअप करना
ऑगमेंटेड रिएलिटी सीन दिखाने के अलावा, PlacesArFragment
उपयोगकर्ता से कैमरे की अनुमति का अनुरोध भी करेगा. ऐसा तब होगा, जब उपयोगकर्ता ने पहले से अनुमति न दी हो. getAdditionalPermissions
तरीके को बदलकर भी अतिरिक्त अनुमतियों का अनुरोध किया जा सकता है. आपको जगह की जानकारी इस्तेमाल करने की अनुमति भी देनी होगी. इसलिए, इस बात की जानकारी दें और getAdditionalPermissions
तरीके को बदलें:
class PlacesArFragment : ArFragment() {
override fun getAdditionalPermissions(): Array<String> =
listOf(Manifest.permission.ACCESS_FINE_LOCATION)
.toTypedArray()
}
इसे चलाएं
Android Studio में, starter
डायरेक्ट्री में मौजूद स्केलेटन कोड खोलें. अगर टूलबार से चलाएं > 'ऐप्लिकेशन' चलाएं पर क्लिक करके, ऐप्लिकेशन को अपने डिवाइस या एम्युलेटर पर डिप्लॉय किया जाता है, तो आपको सबसे पहले जगह की जानकारी और कैमरे की अनुमति चालू करने के लिए कहा जाएगा. आगे बढ़ें और अनुमति दें पर क्लिक करें. इसके बाद, आपको कैमरे का व्यू और मैप का व्यू एक साथ इस तरह दिखना चाहिए:
हवाई जहाज़ों का पता लगाना
अपने कैमरे से आस-पास की चीज़ों को देखने पर, आपको हॉरिज़ॉन्टल सतहों पर कुछ सफ़ेद बिंदु दिख सकते हैं. ये बिंदु, इस इमेज में कारपेट पर मौजूद सफ़ेद बिंदुओं की तरह होते हैं.
ये सफ़ेद बिंदु, ARCore के दिशा-निर्देश हैं. इनसे पता चलता है कि किसी हॉरिज़ॉन्टल प्लेन का पता चल गया है. इन प्लेन की मदद से, "ऐंकर" बनाया जा सकता है. इससे वर्चुअल ऑब्जेक्ट को असली जगह पर रखा जा सकता है.
ARCore और यह आपके आस-पास के माहौल को कैसे समझता है, इस बारे में ज़्यादा जानने के लिए, इसके बुनियादी सिद्धांतों के बारे में पढ़ें.
6. आस-पास की जगहें पाना
इसके बाद, आपको डिवाइस की मौजूदा जगह की जानकारी को ऐक्सेस करके दिखाना होगा. इसके बाद, Places API का इस्तेमाल करके, आस-पास की जगहों की जानकारी फ़ेच करनी होगी.
Maps सेटअप करना
Google Maps Platform API कुंजी
आपने Places API से क्वेरी करने और Maps SDK for Android का इस्तेमाल करने के लिए, Google Maps Platform API पासकोड बनाया था. gradle.properties
फ़ाइल खोलें और "YOUR API KEY HERE"
स्ट्रिंग को अपनी बनाई गई API (एपीआई) कुंजी से बदलें.
मैप पर डिवाइस की जगह की जानकारी दिखाना
एपीआई पासकोड जोड़ने के बाद, मैप पर एक हेल्पर जोड़ें. इससे उपयोगकर्ताओं को यह समझने में मदद मिलेगी कि वे मैप में कहां हैं. इसके लिए, setUpMaps
तरीके पर जाएं. इसके बाद, setUpMaps
कॉल में, googleMap.isMyLocationEnabled
को true.
पर सेट करें. ऐसा करने से, मैप पर नीले रंग का बिंदु दिखेगा.mapFragment.getMapAsync
private fun setUpMaps() {
mapFragment.getMapAsync { googleMap ->
googleMap.isMyLocationEnabled = true
// ...
}
}
मौजूदा जगह की जानकारी पाना
डिवाइस की जगह की जानकारी पाने के लिए, आपको FusedLocationProviderClient
क्लास का इस्तेमाल करना होगा. इसका इंस्टेंस पाने का काम, MainActivity
के onCreate
तरीके में पहले ही किया जा चुका है. इस ऑब्जेक्ट का इस्तेमाल करने के लिए, getCurrentLocation
तरीके को भरें. यह एक लैम्ब्डा आर्ग्युमेंट स्वीकार करता है, ताकि इस तरीके को कॉल करने वाले व्यक्ति को जगह की जानकारी दी जा सके.
इस तरीके को पूरा करने के लिए, FusedLocationProviderClient
ऑब्जेक्ट की lastLocation
प्रॉपर्टी को ऐक्सेस किया जा सकता है. इसके बाद, addOnSuccessListener
को इस तरह जोड़ा जा सकता है:
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
currentLocation = location
onSuccess(location)
}.addOnFailureListener {
Log.e(TAG, "Could not get location")
}
getCurrentLocation
तरीके को setUpMaps
तरीके में दिए गए getMapAsync
में मौजूद लैम्ब्डा से कॉल किया जाता है. इसी तरीके से आस-पास की जगहों की जानकारी फ़ेच की जाती है.
जगहों के नेटवर्क पर कॉल शुरू करना
getNearbyPlaces
तरीके के कॉल में, ध्यान दें कि placesServices.nearbyPlaces
तरीके में ये पैरामीटर पास किए जाते हैं—एपीआई पासकोड, डिवाइस की जगह की जानकारी, मीटर में रेडियस (जो 2 कि॰मी॰ पर सेट है), और जगह का टाइप (फ़िलहाल, park
पर सेट है).
val apiKey = "YOUR API KEY"
placesService.nearbyPlaces(
apiKey = apiKey,
location = "${location.latitude},${location.longitude}",
radiusInMeters = 2000,
placeType = "park"
)
नेटवर्क कॉल पूरा करने के लिए, उस एपीआई कुंजी को पास करें जिसे आपने gradle.properties
फ़ाइल में तय किया है. कोड का यह स्निपेट, आपकी build.gradle
फ़ाइल में android > defaultConfig कॉन्फ़िगरेशन में तय किया गया है:
android {
defaultConfig {
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
}
}
इससे स्ट्रिंग रिसॉर्स की वैल्यू google_maps_key
, बिल्ड टाइम पर उपलब्ध हो जाएगी.
नेटवर्क कॉल पूरा करने के लिए, getString
ऑब्जेक्ट पर Context
के ज़रिए इस स्ट्रिंग रिसॉर्स को पढ़ा जा सकता है.
val apiKey = this.getString(R.string.google_maps_key)
7. एआर में जगहें
अब तक आपने ये काम किए हैं:
- ऐप्लिकेशन को पहली बार चलाने पर, उपयोगकर्ता से कैमरा और जगह की जानकारी ऐक्सेस करने की अनुमतियों का अनुरोध किया गया हो
- हॉरिजॉन्टल प्लेन को ट्रैक करना शुरू करने के लिए, ARCore सेट अप करना
- अपने एपीआई पासकोड की मदद से Maps SDK टूल सेट अप करना
- डिवाइस की मौजूदा जगह की जानकारी मिली
- Places API का इस्तेमाल करके, आस-पास की जगहों (खास तौर पर पार्क) की जानकारी फ़ेच की गई
इस गतिविधि को पूरा करने के लिए, आपको उन जगहों को ऑगमेंटेड रिएलिटी में दिखाना होगा जिनकी जानकारी फ़ेच की जा रही है.
सीन को समझना
ARCore, डिवाइस के कैमरे से असली दुनिया के सीन को समझ पाता है. इसके लिए, वह हर इमेज फ़्रेम में दिलचस्प और अलग-अलग पॉइंट का पता लगाता है. इन पॉइंट को फ़ीचर पॉइंट कहा जाता है. जब ये फ़ीचर पॉइंट क्लस्टर किए जाते हैं और एक ही हॉरिज़ॉन्टल प्लेन पर मौजूद होते हैं, जैसे कि टेबल और फ़्लोर, तो ARCore इस सुविधा को ऐप्लिकेशन के लिए हॉरिज़ॉन्टल प्लेन के तौर पर उपलब्ध करा सकता है.
जैसा कि आपने पहले देखा, जब किसी प्लैन का पता चल जाता है, तो ARCore उपयोगकर्ता को सफ़ेद बिंदु दिखाकर गाइड करता है.
ऐंकर जोड़ना
किसी प्लैन का पता चलने के बाद, आपके पास ऐंकर नाम का ऑब्जेक्ट अटैच करने का विकल्प होता है. ऐंकर की मदद से, वर्चुअल ऑब्जेक्ट रखे जा सकते हैं. साथ ही, यह पक्का किया जा सकता है कि वे ऑब्जेक्ट, स्पेस में एक ही जगह पर दिखें. विमान का पता चलने के बाद, कोड में बदलाव करके उसे अटैच करें.
setUpAr
में, OnTapArPlaneListener
को PlacesArFragment
से अटैच किया गया है. एआर सीन में किसी प्लैन पर टैप करने पर, यह लिसनर शुरू हो जाता है. इस कॉल में, आपको श्रोता के तौर पर दिए गए HitResult
से Anchor
और AnchorNode
बनाने हैं. इसके लिए, यह तरीका अपनाएं:
arFragment.setOnTapArPlaneListener { hitResult, _, _ ->
val anchor = hitResult.createAnchor()
anchorNode = AnchorNode(anchor)
anchorNode?.setParent(arFragment.arSceneView.scene)
addPlaces(anchorNode!!)
}
AnchorNode
में, सीन में मौजूद चाइल्ड नोड ऑब्जेक्ट—PlaceNode
इंस्टेंस अटैच किए जाएंगे. इन्हें addPlaces
तरीके से हैंडल किया जाता है.
इसे चलाएं
ऊपर दिए गए बदलावों के साथ ऐप्लिकेशन चलाने पर, अपने आस-पास तब तक देखें, जब तक किसी हवाई जहाज़ का पता न चल जाए. आगे बढ़ें और उन सफ़ेद बिंदुओं पर टैप करें जो किसी हवाई जहाज़ को दिखाते हैं. ऐसा करने पर, अब आपको अपने आस-पास के सभी पार्कों के लिए, मैप पर मार्कर दिखने चाहिए. हालांकि, अगर आप ध्यान से देखेंगे, तो आपको पता चलेगा कि वर्चुअल ऑब्जेक्ट, बनाए गए ऐंकर पर चिपके हुए हैं. उन्हें स्पेस में उन पार्कों की जगह के हिसाब से नहीं रखा गया है.
आखिरी चरण में, डिवाइस पर Maps SDK for Android Utility Library और SensorManager का इस्तेमाल करके, इस समस्या को ठीक करें.
8. जगहों को पोज़िशन करना
ऑगमेंटेड रिएलिटी में वर्चुअल जगह के आइकॉन को सटीक हेडिंग में रखने के लिए, आपको दो तरह की जानकारी की ज़रूरत होगी:
- जहां उत्तर दिशा है
- उत्तर और हर जगह के बीच का ऐंगल
उत्तर दिशा का पता लगाना
डिवाइस पर मौजूद पोज़िशन सेंसर (जियोमैग्नेटिक और एक्सलरोमीटर) का इस्तेमाल करके, उत्तर दिशा का पता लगाया जा सकता है. इन दोनों सेंसर का इस्तेमाल करके, डिवाइस की जगह की जानकारी रीयल-टाइम में इकट्ठा की जा सकती है. पोजीशन सेंसर के बारे में ज़्यादा जानने के लिए, डिवाइस का ओरिएंटेशन कैलकुलेट करना लेख पढ़ें.
इन सेंसर को ऐक्सेस करने के लिए, आपको SensorManager
हासिल करना होगा. इसके बाद, उन सेंसर पर SensorEventListener
रजिस्टर करना होगा. MainActivity
के लाइफ़साइकल के तरीकों में, ये चरण पहले से ही पूरे किए जा चुके हैं:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
sensorManager = getSystemService()!!
// ...
}
override fun onResume() {
super.onResume()
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also {
sensorManager.registerListener(
this,
it,
SensorManager.SENSOR_DELAY_NORMAL
)
}
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also {
sensorManager.registerListener(
this,
it,
SensorManager.SENSOR_DELAY_NORMAL
)
}
}
override fun onPause() {
super.onPause()
sensorManager.unregisterListener(this)
}
onSensorChanged
तरीके में, एक SensorEvent
ऑब्जेक्ट दिया जाता है. इसमें किसी सेंसर के डेटा के बारे में जानकारी होती है, जो समय के साथ बदलती रहती है. आगे बढ़ें और उस तरीके में यह कोड जोड़ें:
override fun onSensorChanged(event: SensorEvent?) {
if (event == null) {
return
}
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
} else if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
}
// Update rotation matrix, which is needed to update orientation angles.
SensorManager.getRotationMatrix(
rotationMatrix,
null,
accelerometerReading,
magnetometerReading
)
SensorManager.getOrientation(rotationMatrix, orientationAngles)
}
ऊपर दिया गया कोड, सेंसर टाइप की जांच करता है. इसके बाद, टाइप के आधार पर, सेंसर की सही रीडिंग (एक्सलरोमीटर या मैग्नेटोमीटर की रीडिंग) को अपडेट करता है. सेंसर की इन रीडिंग का इस्तेमाल करके, अब यह पता लगाया जा सकता है कि डिवाइस के हिसाब से उत्तर दिशा कितने डिग्री पर है. यानी, orientationAngles[0]
की वैल्यू का पता लगाया जा सकता है.
स्फ़ेरिकल हेडिंग
उत्तर दिशा का पता लगाने के बाद, अगला चरण उत्तर दिशा और हर जगह के बीच के कोण का पता लगाना है. इसके बाद, उस जानकारी का इस्तेमाल करके, ऑगमेंटेड रिएलिटी में जगहों को सही हेडिंग में रखना है.
हेडिंग का हिसाब लगाने के लिए, Maps SDK for Android की यूटिलिटी लाइब्रेरी का इस्तेमाल करें. इसमें स्फ़ेरिकल ज्योमेट्री की मदद से, दूरी और हेडिंग का हिसाब लगाने के लिए कुछ हेल्पर फ़ंक्शन शामिल होते हैं. ज़्यादा जानकारी के लिए, लाइब्रेरी की यह खास जानकारी पढ़ें.
इसके बाद, यूटिलिटी लाइब्रेरी में मौजूद sphericalHeading
तरीके का इस्तेमाल किया जाएगा. यह दो LatLng
ऑब्जेक्ट के बीच हेडिंग/बियरिंग का हिसाब लगाता है. यह जानकारी, Place.kt
में तय किए गए getPositionVector
तरीके के लिए ज़रूरी है. यह तरीका आखिर में एक Vector3
ऑब्जेक्ट दिखाता है. इसका इस्तेमाल हर PlaceNode
, एआर स्पेस में अपनी जगह की जानकारी के तौर पर करेगा.
उस तरीके में हेडिंग की परिभाषा को इससे बदलें:
val heading = latLng.sphericalHeading(placeLatLng)
ऐसा करने पर, आपको इस तरह की परिभाषा मिलेगी:
fun Place.getPositionVector(azimuth: Float, latLng: LatLng): Vector3 {
val placeLatLng = this.geometry.location.latLng
val heading = latLng.sphericalHeading(placeLatLng)
val r = -2f
val x = r * sin(azimuth + heading).toFloat()
val y = 1f
val z = r * cos(azimuth + heading).toFloat()
return Vector3(x, y, z)
}
लोकल पोज़िशन
एआर में जगहों को सही तरीके से ओरिएंट करने का आखिरी चरण यह है कि सीन में PlaceNode
ऑब्जेक्ट जोड़ते समय, getPositionVector
के नतीजे का इस्तेमाल किया जाए. आगे बढ़ें और MainActivity
में addPlaces
पर जाएं. यह उस लाइन के ठीक नीचे होता है जहां हर placeNode
पर पैरंट सेट किया जाता है (placeNode.setParent(anchorNode)
के ठीक नीचे). placeNode
के localPosition
को getPositionVector
को कॉल करने के नतीजे पर सेट करें. जैसे:
val placeNode = PlaceNode(this, place)
placeNode.setParent(anchorNode)
placeNode.localPosition = place.getPositionVector(orientationAngles[0], currentLocation.latLng)
डिफ़ॉल्ट रूप से, getPositionVector
तरीके से नोड की y दूरी को 1 मीटर पर सेट किया जाता है. यह getPositionVector
तरीके में बताई गई y
वैल्यू के मुताबिक होता है. अगर आपको इस दूरी को 2 मीटर पर सेट करना है, तो ज़रूरत के मुताबिक वैल्यू में बदलाव करें.
इस बदलाव के बाद, जोड़े गए PlaceNode
ऑब्जेक्ट अब सही हेडिंग में दिखने चाहिए. अब ऐप्लिकेशन को चलाकर देखें कि क्या नतीजे मिलते हैं!
9. बधाई हो
यहां तक पहुंचने के लिए बधाई!