SwiftUI की मदद से अपना पहला 3D मैप बनाना

1. शुरू करने से पहले

इस कोडलैब में, iOS के लिए Maps 3D SDK टूल का इस्तेमाल करके, SwiftUI में 3D मैप ऐप्लिकेशन बनाने का तरीका बताया गया है.

सैन फ़्रांसिस्को का 3D मैप दिखाने वाला ऐप्लिकेशन

आपको इनके बारे में जानकारी मिलेगी:

  • जगहें देखने और मैप पर फ़्लाइट की सुविधा का इस्तेमाल करने के लिए, कैमरे को कंट्रोल करने का तरीका.
  • मार्कर और मॉडल जोड़ने का तरीका
  • लाइनें और पॉलीगॉन बनाने का तरीका
  • जगह के मार्कर पर उपयोगकर्ता के क्लिक को मैनेज करने का तरीका.

ज़रूरी शर्तें

  • बिलिंग की सुविधा वाला Google Console प्रोजेक्ट
  • एपीआई पासकोड, जिसे iOS के लिए Maps 3D SDK पर इस्तेमाल करने की अनुमति दी जा सकती है.
  • SwiftUI की मदद से iOS ऐप्लिकेशन डेवलप करने की बुनियादी जानकारी.

आपको क्या करना होगा

  • Xcode सेट अप करना और Swift Package Manager का इस्तेमाल करके SDK टूल इंपोर्ट करना
  • एपीआई पासकोड का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन को कॉन्फ़िगर करना
  • अपने ऐप्लिकेशन में बुनियादी 3D मैप जोड़ना
  • कैमरे को कंट्रोल करके, किसी खास जगह पर जाने के लिए फ़्लाइट मोड चालू करना
  • अपने मैप में मार्कर, लाइनें, पॉलीगॉन, और मॉडल जोड़ना

आपको किन चीज़ों की ज़रूरत होगी

  • Xcode 15 या इसके बाद का वर्शन.

2. सेट अप करें

इस सुविधा को चालू करने के लिए, आपको iOS के लिए Maps 3D SDK टूल को चालू करना होगा.

Google Maps Platform सेट अप करना

अगर आपके पास Google Cloud Platform खाता और बिलिंग की सुविधा वाला प्रोजेक्ट नहीं है, तो बिलिंग की सुविधा वाला खाता और प्रोजेक्ट बनाएं. ऐसा करने का तरीका जानने के लिए, कृपया Google Maps Platform का इस्तेमाल शुरू करना देखें.

  1. Cloud Console में, प्रोजेक्ट वाले ड्रॉप-डाउन मेन्यू पर क्लिक करें. इसके बाद, उस प्रोजेक्ट को चुनें जिसे इस कोडलैब के लिए इस्तेमाल करना है.

  1. इस कोडलैब के लिए ज़रूरी Google Maps Platform API और एसडीके को Google Cloud Marketplace में जाकर चालू करें. ऐसा करने के लिए, इस वीडियो या दस्तावेज़ में बताया गया तरीका अपनाएं.
  2. Cloud Console के क्रेडेंशियल पेज पर जाकर, एक एपीआई पासकोड जनरेट करें. ऐसा करने के लिए, इस वीडियो या दस्तावेज़ में बताया गया तरीका अपनाएं. Google Maps Platform का इस्तेमाल करने के लिए, एपीआई पासकोड ज़रूरी है.

iOS के लिए Maps 3D SDK टूल चालू करना

iOS के लिए Maps 3D SDK ढूंढने के लिए, कंसोल में Google Maps Platform > एपीआई और सेवाएं मेन्यू लिंक का इस्तेमाल करें.

चुने गए प्रोजेक्ट पर एपीआई चालू करने के लिए, 'चालू करें' पर क्लिक करें.

Google Console में Maps 3D SDK टूल चालू करना

3. SwiftUI का इस्तेमाल करके बुनियादी ऐप्लिकेशन बनाना

ध्यान दें: GitHub पर codelab के सैंपल ऐप्लिकेशन के रेपो में, हर चरण के लिए समाधान का कोड देखा जा सकता है .

Xcode में नया ऐप्लिकेशन बनाएं.

इस चरण का कोड, GitHub पर GoogleMaps3DDemo फ़ोल्डर में देखा जा सकता है.

Xcode खोलें और नया ऐप्लिकेशन बनाएं. SwiftUI का इस्तेमाल करें.

अपने ऐप्लिकेशन को GoogleMaps3DDemo नाम दें और पैकेज का नाम com.example.GoogleMaps3DDemo रखें.

अपने प्रोजेक्ट में GoogleMaps3D लाइब्रेरी इंपोर्ट करना

Swift Package Manager का इस्तेमाल करके, अपने प्रोजेक्ट में SDK टूल जोड़ें.

अपने Xcode प्रोजेक्ट या फ़ाइल फ़ोल्डर में, फ़ाइल > पैकेज की डिपेंडेंसी जोड़ें पर जाएं. यूआरएल के तौर पर https://github.com/googlemaps/ios-maps-3d-sdk डालें. पैकेज को शामिल करने के लिए, Enter दबाएं और "पैकेज जोड़ें" पर क्लिक करें.

'पैकेज के प्रॉडक्ट चुनें' विंडो में जाकर, पुष्टि करें कि GoogleMaps3D को आपके तय किए गए मुख्य टारगेट में जोड़ा जाएगा. इसके बाद, 'पैकेज जोड़ें' पर क्लिक करें.

इंस्टॉलेशन की पुष्टि करने के लिए, अपने टारगेट के 'सामान्य' पैनल पर जाएं. आपको फ़्रेमवर्क, लाइब्रेरी, और एम्बेड किए गए कॉन्टेंट में, इंस्टॉल किए गए पैकेज दिखेंगे. पैकेज और उसके वर्शन की पुष्टि करने के लिए, Project Navigator के 'पैकेज की डिपेंडेंसी' सेक्शन को भी देखा जा सकता है.

अपनी एपीआई कुंजी जोड़ना

एपीआई पासकोड को ऐप्लिकेशन में हार्ड कोड किया जा सकता है, लेकिन यह अच्छा तरीका नहीं है. कॉन्फ़िगरेशन फ़ाइल जोड़ने से, अपनी एपीआई कुंजी को गुप्त रखा जा सकता है. साथ ही, उसे सोर्स कंट्रोल में शामिल करने से भी बचा जा सकता है.

प्रोजेक्ट के रूट फ़ोल्डर में नई कॉन्फ़िगरेशन फ़ाइल बनाएं

पक्का करें कि Xcode में, आपको प्रोजेक्ट एक्सप्लोरर विंडो दिख रही हो. प्रोजेक्ट रूट पर राइट क्लिक करें और "टेंप्लेट से नई फ़ाइल" चुनें. जब तक आपको "कॉन्फ़िगरेशन सेटिंग फ़ाइल" न दिखे, तब तक स्क्रोल करें. इसे चुनें और "आगे बढ़ें" पर क्लिक करें. फ़ाइल को Config.xcconfig नाम दें और पक्का करें कि प्रोजेक्ट का रूट फ़ोल्डर चुना गया हो. फ़ाइल बनाने के लिए, "बनाएं" पर क्लिक करें.

एडिटर में, कॉन्फ़िगरेशन फ़ाइल में यह लाइन जोड़ें: MAPS_API_KEY = YOUR_API_KEY

YOUR_API_KEY को अपनी एपीआई पासकोड से बदलें.

इस सेटिंग को Info.plist में जोड़ें.

ऐसा करने के लिए, प्रोजेक्ट का रूट चुनें और "जानकारी" टैब पर क्लिक करें.

MAPS_API_KEY नाम की नई प्रॉपर्टी जोड़ें और उसकी वैल्यू $(MAPS_API_KEY) रखें.

सैंपल ऐप्लिकेशन कोड में Info.plist फ़ाइल होती है, जिसमें इस प्रॉपर्टी की जानकारी होती है.

मैप जोड़ना

GoogleMaps3DDemoApp.swift नाम की फ़ाइल खोलें. यह आपके ऐप्लिकेशन का एंट्री पॉइंट और मुख्य नेविगेशन है.

यह ContentView() को कॉल करता है, जो 'नमस्ते दुनिया' मैसेज दिखाता है.

एडिटर में ContentView.swift खोलें.

GoogleMaps3D के लिए import स्टेटमेंट जोड़ें.

var body: some View {} कोड ब्लॉक में मौजूद कोड मिटाएं. body के अंदर एक नया Map() तय करें.

Map को शुरू करने के लिए, कम से कम MapMode कॉन्फ़िगरेशन की ज़रूरत होती है. इसकी दो संभावित वैल्यू होती हैं:

  • .hybrid - सड़कों और लेबल वाली सैटलाइट इमेज या
  • .satellite - सिर्फ़ सैटलाइट इमेज.

.hybrid को चुनें.

आपकी ContentView.swift फ़ाइल इस तरह दिखनी चाहिए.

import GoogleMaps3D
import SwiftUI

@main
struct ContentView: View {
    var body: some View {
      Map(mode: .hybrid)
    }
}

अपना एपीआई पासकोड सेट करें.

मैप शुरू होने से पहले, एपीआई कुंजी सेट होनी चाहिए.

ऐसा करने के लिए, किसी भी View के init() इवेंट हैंडलर में Map.apiKey सेट करें. इसमें कोई मैप होना चाहिए. ContentView() को कॉल करने से पहले, इसे GoogleMaps3DDemoApp.swift में भी सेट किया जा सकता है.

GoogleMaps3DDemoApp.swift में, WindowGroup के onAppear इवेंट हैंडलर में Map.apiKey सेट करें.

कॉन्फ़िगरेशन फ़ाइल से अपनी एपीआई कुंजी फ़ेच करना

अपनी कॉन्फ़िगरेशन फ़ाइल में बनाई गई MAPS_API_KEY सेटिंग को ऐक्सेस करने के लिए, Bundle.main.infoDictionary का इस्तेमाल करें.

import GoogleMaps3D
import SwiftUI

@main
struct GoogleMaps3DDemoApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
    .onAppear {
      guard let infoDictionary: [String: Any] = Bundle.main.infoDictionary else {
        fatalError("Info.plist not found")
      }
      guard let apiKey: String = infoDictionary["MAPS_API_KEY"] as? String else {
        fatalError("MAPS_API_KEY not set in Info.plist")
      }
      Map.apiKey = apiKey
    }
  }
}

अपने ऐप्लिकेशन को बिल्ड और चलाकर देखें कि वह सही तरीके से लोड हो रहा है या नहीं. आपको ग्लोब का मैप दिखेगा.

धरती को दिखाने वाला 3D मैप

4. मैप व्यू को कंट्रोल करने के लिए कैमरे का इस्तेमाल करना

कैमरे की स्थिति का ऑब्जेक्ट बनाना

3D मैप व्यू को Camera क्लास से कंट्रोल किया जाता है. इस चरण में, आपको मैप व्यू को पसंद के मुताबिक बनाने के लिए, जगह, ऊंचाई, हेडिंग, झुकाव, रोल, और रेंज तय करने का तरीका पता चलेगा.

सैन फ़्रांसिस्को का 3D मैप व्यू

कैमरे की सेटिंग सेव करने के लिए, Helpers क्लास बनाना

MapHelpers.swift नाम की एक नई खाली फ़ाइल जोड़ें. अपनी नई फ़ाइल में, GoogleMaps3D इंपोर्ट करें और Camera क्लास में कोई एक्सटेंशन जोड़ें. sanFrancisco नाम का वैरिएबल जोड़ें. इस वैरिएबल को नए Camera ऑब्जेक्ट के तौर पर शुरू करें. कैमरे को latitude: 37.39, longitude: -122.08 पर ले जाएं.

import GoogleMaps3D

extension Camera {
 public static var sanFrancisco: Camera = .init(latitude: 37.39, longitude: -122.08)
}

अपने ऐप्लिकेशन में नया व्यू जोड़ना

CameraDemo.swift नाम की एक नई फ़ाइल बनाएं. फ़ाइल में, नए SwiftUI व्यू की बुनियादी आउटलाइन जोड़ें.

Camera टाइप का camera नाम वाला @State वैरिएबल जोड़ें. इसे उस sanFrancisco कैमरे से शुरू करें जिसे आपने अभी तय किया है.

@State का इस्तेमाल करके, मैप को कैमरे की स्थिति से जोड़ा जा सकता है और इसका इस्तेमाल सटीक जानकारी के सोर्स के तौर पर किया जा सकता है.

@State var camera: Camera = .sanFrancisco

camera प्रॉपर्टी को शामिल करने के लिए, Map() फ़ंक्शन कॉल को बदलें. अपने कैमरे @State ऑब्जेक्ट (.sanFrancisco) में camera प्रॉपर्टी को शुरू करने के लिए, कैमरे की स्थिति को बांधने वाली $camera का इस्तेमाल करें.

import SwiftUI
import GoogleMaps3D

struct CameraDemo: View {
  @State var camera: Camera = .sanFrancisco
  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid)
    }
  }
}

अपने ऐप्लिकेशन में बुनियादी नेविगेशन यूज़र इंटरफ़ेस (यूआई) जोड़ना

ऐप्लिकेशन के मुख्य एंट्री पॉइंट, GoogleMaps3DDemoApp.swift में NavigationView जोड़ें.

इससे उपयोगकर्ता, डेमो की सूची देख पाएंगे और हर डेमो को खोलने के लिए उस पर क्लिक कर पाएंगे.

नया NavigationView जोड़ने के लिए, GoogleMaps3DDemoApp.swift में बदलाव करें.

दो NavigationLink एलान वाला List जोड़ें.

पहला NavigationLink, Text ब्यौरे Basic Map के साथ ContentView() खोलना चाहिए.

दूसरा NavigationLink, CameraDemo() खोल देगा.

...
      NavigationView {
        List {
          NavigationLink(destination: ContentView()) {
            Text("Basic Map")
          }
          NavigationLink(destination: CameraDemo()) {
            Text("Camera Demo")
          }
        }
      }
...

Xcode की झलक जोड़ना

झलक, Xcode की एक बेहतरीन सुविधा है. इसकी मदद से, ऐप्लिकेशन में बदलाव करते समय उसे देखा और उससे इंटरैक्ट किया जा सकता है.

झलक जोड़ने के लिए, CameraDemo.swift खोलें. struct के बाहर #Preview {} कोड ब्लॉक जोड़ें.

#Preview {
 CameraDemo()
}

Xcode में, झलक वाला पैनल खोलें या रीफ़्रेश करें. मैप पर सैन फ़्रांसिस्को दिखना चाहिए.

कस्टम 3D व्यू सेट अप करना

कैमरे को कंट्रोल करने के लिए, अतिरिक्त पैरामीटर तय किए जा सकते हैं:

  • heading: कैमरे को जिस दिशा में ले जाना है उसके लिए, उत्तर से डिग्री में बियरिंग.
  • tilt: डिग्री में झुकाव का कोण, जहां 0 सीधे ऊपर की ओर है और 90 क्षैतिज रूप से दिख रहा है.
  • roll: कैमरे के वर्टिकल प्लेन के आस-पास रोल का कोण, डिग्री में
  • range: अक्षांश और देशांतर की जगह से कैमरे की दूरी मीटर में
  • altitude: समुद्र तल से कैमरे की ऊंचाई

अगर आपने इनमें से कोई भी अतिरिक्त पैरामीटर नहीं दिया है, तो डिफ़ॉल्ट वैल्यू का इस्तेमाल किया जाएगा.

कैमरे के व्यू में ज़्यादा 3D डेटा दिखाने के लिए, शुरुआती पैरामीटर को सेट करके, ज़्यादा नज़दीक और तिरछा व्यू दिखाएं.

altitude, heading, tilt, roll, और range की वैल्यू शामिल करने के लिए, MapHelpers.swift में तय किए गए Camera में बदलाव करें

public static var sanFrancisco: Camera = .init(
  latitude: 37.7845812,
  longitude: -122.3660241,
  altitude: 585,
  heading: 288.0,
  tilt: 75.0,
  roll: 0.0,
  range: 100)

नया 3D व्यू देखने और एक्सप्लोर करने के लिए, ऐप्लिकेशन बनाएं और चलाएं.

5. कैमरे के बुनियादी ऐनिमेशन

अब तक, आपने कैमरे का इस्तेमाल करके, टिल्ट, ऊंचाई, हेडिंग, और रेंज के साथ किसी एक जगह की जानकारी दी है. इस चरण में, आपको इन प्रॉपर्टी को शुरुआती सेटिंग से नई सेटिंग में ऐनिमेट करके, कैमरे के व्यू को मूव करने का तरीका पता चलेगा.

सिएटल का 3D मैप

किसी जगह पर फ़्लाइट की जानकारी

कैमरे को शुरुआती जगह से नई जगह पर ले जाने के लिए, Map.flyCameraTo() तरीके का इस्तेमाल किया जाएगा.

flyCameraTo() का तरीका कई पैरामीटर लेता है:

  • Camera, जो आखिरी जगह की जानकारी देता है.
  • duration: ऐनिमेशन कितनी देर चलेगा, सेकंड में.
  • trigger: ऐसा ऑब्जेक्ट जिसकी स्थिति बदलने पर ऐनिमेशन ट्रिगर होगा.
  • completion: ऐनिमेशन पूरा होने पर लागू होने वाला कोड.

टिकट बुक करने के लिए कोई जगह चुनना

अपनी MapHelpers.swift फ़ाइल खोलें.

सिऐटल दिखाने के लिए, नया कैमरा ऑब्जेक्ट तय करें.

public static var seattle: Camera = .init(latitude:
47.6210296,longitude: -122.3496903, heading: 149.0, tilt: 77.0, roll: 0.0, range: 4000)

ऐनिमेशन को ट्रिगर करने के लिए बटन जोड़ें.

अपना CameraDemo.swift खोलें. struct के अंदर एक नया बूलियन वैरिएबल बनाएं.

इसे animate नाम दें और शुरुआती वैल्यू false रखें.

@State private var animate: Bool = false

VStack के नीचे Button जोड़ें. Button, मैप ऐनिमेशन शुरू करेगा.

Button को कोई सही Text दें, जैसे कि "फ़्लाइट शुरू करें".

import SwiftUI
import GoogleMaps3D

struct CameraDemo: View {
  @State var camera:Camera = .sanFrancisco
  @State private var animate: Bool = false

  var body: some View {
    VStack{
      Map(camera: $camera, mode: .hybrid)
      Button("Start Flying") {
      }
    }
  }
}

बटन क्लोज़र में, animate वैरिएबल की स्थिति को टॉगल करने के लिए कोड जोड़ें.

      Button("Start Flying") {
        animate.toggle()
      }

ऐनिमेशन शुरू करें.

animate वैरिएबल की स्थिति बदलने पर, flyCameraTo() ऐनिमेशन को ट्रिगर करने के लिए कोड जोड़ें.

  var body: some View {
    VStack{
      Map(camera: $camera, mode: .hybrid)
        .flyCameraTo(
          .seattle,
          duration: 5,
          trigger: animate,
          completion: {  }
        )
      Button("Start Flying") {
        animate.toggle()
      }
    }
  }

किसी जगह के आस-पास फ़्लाइट की सुविधा

किसी जगह के आस-पास उड़ने के लिए, Map.flyCameraAround() तरीके का इस्तेमाल किया जा सकता है. इस तरीके में कई पैरामीटर होते हैं:

  • जगह और व्यू की जानकारी देने वाला Camera.
  • duration सेकंड में.
  • rounds: ऐनिमेशन को दोहराने की संख्या.
  • trigger: ऐसा ऑब्जेक्ट जिसे निगरानी में रखा जा सकता है और जो ऐनिमेशन को ट्रिगर करेगा.
  • callback: ऐनिमेशन चलने पर लागू होने वाला कोड.

flyAround नाम का एक नया @State वैरिएबल तय करें. इसकी शुरुआती वैल्यू false है.

इसके बाद, flyCameraTo() मेथड कॉल के तुरंत बाद flyCameraAround() को कॉल जोड़ें.

फ़्लाय अरेंड की अवधि ज़्यादा होनी चाहिए, ताकि व्यू आसानी से बदल सके.

flyCameraTo() पूरा होने पर, ट्रिगर ऑब्जेक्ट की स्थिति बदलकर, flyCameraAround() ऐनिमेशन को ट्रिगर करना न भूलें.

आपका कोड कुछ ऐसा दिखेगा.

import SwiftUI
import GoogleMaps3D

struct CameraDemo: View {
  @State var camera:Camera = .sanFrancisco
  @State private var animate: Bool = false
  @State private var flyAround: Bool = false

  var body: some View {
    VStack{
      Map(camera: $camera, mode: .hybrid)
        .flyCameraTo(
          .seattle,
          duration: 5,
          trigger: animate,
          completion: { flyAround = true }
        )
        .flyCameraAround(
          .seattle,
          duration: 15,
          rounds: 0.5,
          trigger: flyAround,
          callback: {  }
        )
      Button("Start Flying") {
        animate.toggle()
      }
    }
  }
}

#Preview {
  CameraDemo()
}

ऐप्लिकेशन की झलक देखें या उसे चलाकर देखें कि flyCameraTo() ऐनिमेशन पूरा होने के बाद, कैमरा डेस्टिनेशन के आस-पास फ़्लाय करता है या नहीं.

6. अपने मैप में मार्कर जोड़ें.

इस चरण में, आपको मैप पर मार्कर पिन बनाने का तरीका पता चलेगा.

आपको एक Marker ऑब्जेक्ट बनाना होगा और उसे अपने मैप में जोड़ना होगा. SDK, मार्कर के लिए डिफ़ॉल्ट आइकॉन का इस्तेमाल करेगा. आखिर में, मार्कर के दिखने के तरीके में बदलाव करने के लिए, मार्कर की ऊंचाई और अन्य प्रॉपर्टी में बदलाव करें.

3D मैप, जिसमें मैप मार्कर दिख रहा है

मार्कर के डेमो के लिए, नया SwiftUI व्यू बनाएं.

अपने प्रोजेक्ट में नई Swift फ़ाइल जोड़ें. इसे MarkerDemo.swift नाम दें.

SwiftUI व्यू की आउटलाइन जोड़ें और मैप को वैसे ही शुरू करें जैसे आपने CameraDemo में किया था.

import SwiftUI
import GoogleMaps3D

struct MarkerDemo: View {
  @State var camera: Camera = .sanFrancisco
  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid)
    }
  }
}

मार्कर ऑब्जेक्ट को शुरू करना

mapMarker नाम का नया मार्कर वैरिएबल बनाएं. MarkerDemo.swift में struct कोड ब्लॉक के सबसे ऊपर.

परिभाषा को camera एलान के नीचे वाली लाइन पर डालें. यह सैंपल कोड, सभी उपलब्ध प्रॉपर्टी को शुरू करता है.

  @State var mapMarker: Marker = .init(
    position: .init(
      latitude: 37.8044862,
      longitude: -122.4301493,
      altitude: 0.0),
    altitudeMode: .absolute,
    collisionBehavior: .required,
    extruded: false,
    drawsWhenOccluded: true,
    sizePreserved: true,
    zIndex: 0,
    label: "Test"
  )

मार्कर को अपने मैप पर जोड़ें.

मार्कर बनाने के लिए, उसे उस क्लोज़र में जोड़ें जिसे मैप बनाते समय बनाया जाता है.

struct MarkerDemo: View {
  @State var camera: Camera = .sanFrancisco
  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid) {
        mapMarker
      }
    }
  }
}

GoogleMaps3DDemoApp.swift में एक नया NavigationLink जोड़ें. इसका डेस्टिनेशन MarkerDemo() और Text होना चाहिए. साथ ही, इसे "मार्कर डेमो" के तौर पर सेट करें.

...
      NavigationView {
        List {
          NavigationLink(destination: Map()) {
            Text("Basic Map")
          }
          NavigationLink(destination: CameraDemo()) {
            Text("Camera Demo")
          }
          NavigationLink(destination: MarkerDemo()) {
            Text("Marker Demo")
          }
        }
      }
...

अपने ऐप्लिकेशन की झलक देखना और उसे चलाना

मार्कर देखने के लिए, झलक को रीफ़्रेश करें या अपना ऐप्लिकेशन चलाएं.

एक्सट्रूडेड मार्कर

altitude और altitudeMode का इस्तेमाल करके, मार्कर को ज़मीन या 3D मेश के ऊपर रखा जा सकता है.

MarkerDemo.swift में मौजूद mapMarker एलान को extrudedMarker नाम के नए Marker वैरिएबल में कॉपी करें.

altitude के लिए कोई ऐसी वैल्यू सेट करें जो शून्य से ज़्यादा हो. 50 वैल्यू सेट करना काफ़ी है.

altitudeMode को .relativeToMesh पर सेट करें और extruded को true पर सेट करें. मार्कर को किसी स्काईस्क्रेपर के ऊपर रखने के लिए, यहां दिए गए कोड स्निपेट में latitude और longitude का इस्तेमाल करें.

  @State var extrudedMarker: Marker = .init(
    position: .init(
      latitude: 37.78980534,
      longitude:  -122.3969349,
      altitude: 50.0),
    altitudeMode: .relativeToMesh,
    collisionBehavior: .required,
    extruded: true,
    drawsWhenOccluded: true,
    sizePreserved: true,
    zIndex: 0,
    label: "Extruded"
  )

ऐप्लिकेशन को फिर से चलाएं या उसकी झलक देखें. मार्कर, 3D इमारत के ऊपर दिखना चाहिए.

7. अपने मैप में कोई मॉडल जोड़ें.

Model को उसी तरह जोड़ा जा सकता है जिस तरह Marker को जोड़ा जाता है. आपको एक मॉडल फ़ाइल की ज़रूरत होगी, जिसे यूआरएल से ऐक्सेस किया जा सके या अपने प्रोजेक्ट में लोकल फ़ाइल के तौर पर जोड़ा जा सके. इस चरण के लिए, हम एक लोकल फ़ाइल का इस्तेमाल करेंगे. इस कोडलैब के लिए, GitHub रिपॉज़िटरी से यह फ़ाइल डाउनलोड की जा सकती है.

सैन फ़्रांसिस्को का 3D मैप, जिसमें हॉट एयर बलून का मॉडल भी दिख रहा है

अपने प्रोजेक्ट में मॉडल फ़ाइल जोड़ना

अपने Xcode प्रोजेक्ट में Models नाम का नया फ़ोल्डर बनाएं.

GitHub के सैंपल ऐप्लिकेशन रिपॉज़िटरी से मॉडल डाउनलोड करें. इसे अपने प्रोजेक्ट में जोड़ने के लिए, Xcode प्रोजेक्ट व्यू में नए फ़ोल्डर में खींचें और छोड़ें.

पक्का करें कि आपने टारगेट को अपने ऐप्लिकेशन के मुख्य टारगेट के तौर पर सेट किया हो.

अपने प्रोजेक्ट के लिए, बिल्ड के चरण > बंडल के संसाधनों को कॉपी करें सेटिंग देखें. मॉडल फ़ाइल, बंडल में कॉपी किए गए संसाधनों की सूची में होनी चाहिए. अगर यह वहां नहीं है, तो उसे जोड़ने के लिए "+" पर क्लिक करें.

मॉडल को अपने ऐप्लिकेशन में जोड़ें.

ModelDemo.swift नाम की एक नई SwiftUI फ़ाइल बनाएं.

पिछले चरणों की तरह ही, SwiftUI और GoogleMaps3D के लिए import स्टेटमेंट जोड़ें.

अपने body में, VStack के अंदर Map का एलान करें.

import SwiftUI
import GoogleMaps3D

struct ModelDemo: View {
  @State var camera: Camera = .sanFrancisco
  
  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid) {
        
      }
    }
  }
}

अपने बंडल से मॉडल का पाथ पाएं. इसके लिए, कोड को struct के बाहर जोड़ें.

private let fileUrl = Bundle.main.url(forResource: "balloon", withExtension: "glb")

स्ट्रक्चर में अपने मॉडल के लिए कोई वैरिएबल तय करें.

अगर fileUrl की वैल्यू सबमिट नहीं की जाती है, तो डिफ़ॉल्ट वैल्यू सबमिट करें.

  @State var balloonModel: Model = .init(
    position: .init(
      latitude: 37.791376,
      longitude: -122.397571,
      altitude: 300.0),
    url: URL(fileURLWithPath: fileUrl?.relativePath ?? ""),
    altitudeMode: .absolute,
    scale: .init(x: 5, y: 5, z: 5),
    orientation: .init(heading: 0, tilt: 0, roll: 0)
  )

3. मॉडल को अपने मैप के साथ इस्तेमाल करें.

Marker जोड़ने की तरह ही, Map एलान में अपने Model का रेफ़रंस दें.

  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid) {
        balloonModel
      }
    }
  }

अपने ऐप्लिकेशन की झलक देखना और उसे चलाना

GoogleMaps3DDemoApp.swift में नया NavigationLink जोड़ें. इसका डेस्टिनेशन ModelDemo() और Text "मॉडल डेमो" होना चाहिए.

...
          NavigationLink(destination: ModelDemo()) {
            Text("Model Demo")
          }
...

मॉडल देखने के लिए, झलक को रीफ़्रेश करें या अपना ऐप्लिकेशन चलाएं.

8. अपने मैप पर लाइन और पॉलीगॉन बनाएं.

इस चरण में, आपको अपने 3D मैप में लाइनें और पॉलीगॉन आकार जोड़ने का तरीका पता चलेगा.

आसानी के लिए, आकारों को LatLngAltitude ऑब्जेक्ट के ऐरे के तौर पर तय किया जाएगा. किसी असल ऐप्लिकेशन में, डेटा को किसी फ़ाइल, एपीआई कॉल या डेटाबेस से लोड किया जा सकता है.

सैन फ़्रांसिस्को का 3D मैप, जिसमें दो पॉलीगॉन और एक पॉलीलाइन दिख रही है

शेप का डेटा मैनेज करने के लिए, कुछ शेप ऑब्जेक्ट बनाएं.

MapHelpers.swift में एक नई Camera डेफ़िनिशन जोड़ें, जो सैन फ़्रांसिस्को के बाज़ार की जानकारी दिखाती हो.

  public static var downtownSanFrancisco: Camera = .init(latitude: 37.7905, longitude: -122.3989, heading: 25, tilt: 71, range: 2500) 

अपने प्रोजेक्ट में ShapesDemo.swift नाम की नई फ़ाइल जोड़ें. ShapesDemo नाम का ऐसा struct जोड़ें जो View प्रोटोकॉल लागू करता हो. साथ ही, उसमें body जोड़ें.

struct ShapesDemo: View {
  @State var camera: Camera = .downtownSanFrancisco

  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid) {

      }
    }
  }
}

शेप डेटा को मैनेज करने के लिए, Polyline और Polygon क्लास का इस्तेमाल किया जाएगा. ShapesDemo.swift खोलें और उन्हें struct में जोड़ने के लिए, यह तरीका अपनाएं.

var polyline: Polyline = .init(coordinates: [
    LatLngAltitude(latitude: 37.80515638571346, longitude: -122.4032569467164, altitude: 0),
    LatLngAltitude(latitude: 37.80337073509504, longitude: -122.4012878349353, altitude: 0),
    LatLngAltitude(latitude: 37.79925208843463, longitude: -122.3976697250461, altitude: 0),
    LatLngAltitude(latitude: 37.7989102378512, longitude: -122.3983408725656, altitude: 0),
    LatLngAltitude(latitude: 37.79887832784348, longitude: -122.3987094864192, altitude: 0),
    LatLngAltitude(latitude: 37.79786443410338, longitude: -122.4066878788802, altitude: 0),
    LatLngAltitude(latitude: 37.79549248916587, longitude: -122.4032992702785, altitude: 0),
    LatLngAltitude(latitude: 37.78861484290265, longitude: -122.4019489189814, altitude: 0),
    LatLngAltitude(latitude: 37.78618687561075, longitude: -122.398969592545, altitude: 0),
    LatLngAltitude(latitude: 37.7892310309145, longitude: -122.3951458683092, altitude: 0),
    LatLngAltitude(latitude: 37.7916358762409, longitude: -122.3981969390652, altitude: 0)
  ])
  .stroke(GoogleMaps3D.Polyline.StrokeStyle(
    strokeColor: UIColor(red: 0.09803921568627451, green: 0.403921568627451, blue: 0.8235294117647058, alpha: 1),
    strokeWidth: 10.0,
    outerColor: .white,
    outerWidth: 0.2
    ))
  .contour(GoogleMaps3D.Polyline.ContourStyle(isGeodesic: true))

  var originPolygon: Polygon = .init(outerCoordinates: [
    LatLngAltitude(latitude: 37.79165766856578, longitude:  -122.3983762901255, altitude: 300),
    LatLngAltitude(latitude: 37.7915324439261, longitude:  -122.3982171091383, altitude: 300),
    LatLngAltitude(latitude: 37.79166617650914, longitude:  -122.3980478493319, altitude: 300),
    LatLngAltitude(latitude: 37.79178986470217, longitude:  -122.3982041104199, altitude: 300),
    LatLngAltitude(latitude: 37.79165766856578, longitude:  -122.3983762901255, altitude: 300 )
  ],
  altitudeMode: .relativeToGround)
  .style(GoogleMaps3D.Polygon.StyleOptions(fillColor:.green, extruded: true) )

  var destinationPolygon: Polygon = .init(outerCoordinates: [
      LatLngAltitude(latitude: 37.80515661739527, longitude:  -122.4034307490334, altitude: 300),
      LatLngAltitude(latitude: 37.80503794515428, longitude:  -122.4032633416024, altitude: 300),
      LatLngAltitude(latitude: 37.80517850164195, longitude:  -122.4031056058006, altitude: 300),
      LatLngAltitude(latitude: 37.80529346901115, longitude:  -122.4032622466595, altitude: 300),
      LatLngAltitude(latitude: 37.80515661739527, longitude:  -122.4034307490334, altitude: 300 )
  ],
  altitudeMode: .relativeToGround)
  .style(GoogleMaps3D.Polygon.StyleOptions(fillColor:.red, extruded: true) )

इस्तेमाल किए गए इनिशलाइज़ेशन पैरामीटर पर ध्यान दें.

  • altitudeMode: .relativeToGround का इस्तेमाल, पॉलीगॉन को ज़मीन से ऊपर किसी खास ऊंचाई पर एक्सट्रूज़न करने के लिए किया जाता है.
  • altitudeMode: .clampToGround का इस्तेमाल, पॉलीलाइन को धरती की सतह के आकार के हिसाब से बनाने के लिए किया जाता है.
  • .init() को कॉल करने के बाद, styleOptions() के लिए मेथड कॉल को चेन करके, Polygon ऑब्जेक्ट पर स्टाइल सेट किए जाते हैं

मैप में आकार जोड़ना

पिछले चरणों की तरह ही, आकार सीधे तौर पर Map क्लोज़र में जोड़े जा सकते हैं. VStack के अंदर अपना Map बनाएं.

...
  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid) {
        polyline
        originPolygon
        destinationPolygon
      }
    }
  }
...

अपने ऐप्लिकेशन की झलक देखना और उसे चलाना

झलक दिखाने वाला कोड जोड़ें और Xcode में झलक दिखाने वाले पैनल में अपने ऐप्लिकेशन की जांच करें.

#Preview {
  ShapesDemo()
}

अपना ऐप्लिकेशन चलाने के लिए, GoogleMaps3DDemoApp.swift में नया NavigationLink जोड़ें. इससे नया डेमो व्यू खुलेगा.

...
          NavigationLink(destination: ShapesDemo()) {
            Text("Shapes Demo")
          }
...

अपना ऐप्लिकेशन चलाएं और जोड़े गए आकार एक्सप्लोर करें.

9. जगह मार्कर पर टैप करने से जुड़े इवेंट मैनेज करना

इस चरण में, आपको जगह के मार्कर पर उपयोगकर्ता के टैप का जवाब देने का तरीका पता चलेगा.

मैप पर, प्लेस आईडी वाली पॉप-अप विंडो दिख रही है

ध्यान दें: मैप पर जगह के मार्कर देखने के लिए, आपको MapMode को .hybrid पर सेट करना होगा.

टैप को मैनेज करने के लिए, Map.onPlaceTap तरीका लागू करना ज़रूरी है.

onPlaceTap इवेंट, PlaceTapInfo ऑब्जेक्ट उपलब्ध कराता है. इससे, टैप किए गए प्लेस मार्कर का प्लेस आईडी पाया जा सकता है.

Places SDK टूल या Places API का इस्तेमाल करके, जगह के आईडी की मदद से ज़्यादा जानकारी देखी जा सकती है.

नया Swift व्यू जोड़ना

PlaceTapDemo.swift नाम की नई Swift फ़ाइल में, यह कोड जोड़ें.

import GoogleMaps3D
import SwiftUI

struct PlaceTapDemo: View {
  @State var camera: Camera = .sanFrancisco
  @State var isPresented = false
  @State var tapInfo: PlaceTapInfo?

  var body: some View {
    Map(camera: $camera, mode: .hybrid)
      .onPlaceTap { tapInfo in
        self.tapInfo = tapInfo
        isPresented.toggle()
      }
      .alert(
        "Place tapped - \(tapInfo?.placeId ?? "nil")",
        isPresented: $isPresented,
        actions: { Button("OK") {} }
      )
  }
}
#Preview {
  PlaceTapDemo()
}

अपने ऐप्लिकेशन की झलक देखना और उसे चलाना

ऐप्लिकेशन की झलक देखने के लिए, झलक दिखाने वाला पैनल खोलें.

ऐप्लिकेशन चलाने के लिए, GoogleMaps3DDemoApp.swift में नया NavigationLink जोड़ें.

...
          NavigationLink(destination: PlaceTapDemo()) {
            Text("Place Tap Demo")
          }
...

10. (ज़रूरी नहीं) आगे बढ़ें

बेहतर कैमरे के ऐनिमेशन

कुछ इस्तेमाल के उदाहरणों में, जगहों या कैमरे की स्थितियों के क्रम या सूची के साथ आसानी से ऐनिमेशन करना ज़रूरी होता है. उदाहरण के लिए, फ़्लाइट सिम्युलेटर या किसी ट्रैक पर साइकल चलाने या दौड़ने की गतिविधि को फिर से चलाना.

इस चरण में, आपको किसी फ़ाइल से जगहों की सूची लोड करने और क्रम से हर जगह को ऐनिमेट करने का तरीका पता चलेगा.

इंसब्रुक के एप्रोच का 3D मैप व्यू

ऐसी फ़ाइल लोड करें जिसमें जगहों का क्रम शामिल हो.

GitHub के सैंपल ऐप्लिकेशन की रिपॉज़िटरी से flightpath.json डाउनलोड करें.

अपने Xcode प्रोजेक्ट में JSON नाम का नया फ़ोल्डर बनाएं.

Xcode में, flightpath.json को अपने JSON फ़ोल्डर में खींचें और छोड़ें.

टारगेट को अपने ऐप्लिकेशन का मुख्य टारगेट के तौर पर सेट करें. देखें कि आपके प्रोजेक्ट की 'कॉपी बंडल संसाधन' सेटिंग में यह फ़ाइल शामिल है या नहीं.

अपने ऐप्लिकेशन में FlightPathData.swift और FlightDataLoader.swift नाम की दो नई Swift फ़ाइलें बनाएं.

नीचे दिया गया कोड अपने ऐप्लिकेशन में कॉपी करें. यह कोड स्ट्रक्चर और क्लास बनाता है, जो "flighpath.json" नाम की लोकल फ़ाइल को पढ़ता है और उसे JSON के तौर पर डिकोड करता है.

FlightPathData और FlightPathLocation स्ट्रक्चर, JSON फ़ाइल में मौजूद डेटा स्ट्रक्चर को Swift ऑब्जेक्ट के तौर पर दिखाते हैं.

FlightDataLoader क्लास, फ़ाइल से डेटा पढ़ती है और उसे डिकोड करती है. यह ObservableObject प्रोटोकॉल का इस्तेमाल करता है, ताकि आपका ऐप्लिकेशन अपने डेटा में हुए बदलावों को देख सके.

पार्स किए गए डेटा को पब्लिश की गई प्रॉपर्टी के ज़रिए दिखाया जाता है.

FlightPaths.swift

import GoogleMaps3D

struct FlightPathData: Decodable {
  let flight: [FlightPathLocation]
}

struct FlightPathLocation: Decodable {
  let timestamp: Int64
  let latitude: Double
  let longitude: Double
  let altitude: Double
  let bearing: Double
  let speed: Double
}

FlightDataLoader.swift

import Foundation

public class FlightDataLoader : ObservableObject {

  @Published var flightPathData: FlightPathData = FlightPathData(flight:[])
  @Published var isLoaded: Bool = false

  public init() {
    load("flightpath.json")
  }
  
  public func load(_ path: String) {
    if let url = Bundle.main.url(forResource: path, withExtension: nil){
      if let data = try? Data(contentsOf: url){
        let jsondecoder = JSONDecoder()
        do{
          let result = try jsondecoder.decode(FlightPathData.self, from: data)
          flightPathData = result
          isLoaded = true
        }
        catch {
          print("Error trying to load or parse the JSON file.")
        }
      }
    }
  }
}

हर जगह के साथ कैमरे को ऐनिमेट करना

सिलसिलेवार चरणों के बीच कैमरे को ऐनिमेट करने के लिए, KeyframeAnimator का इस्तेमाल करें.

हर Keyframe को CubicKeyframe के तौर पर बनाया जाएगा, ताकि कैमरे की स्थिति में होने वाले बदलावों को आसानी से ऐनिमेशन के तौर पर दिखाया जा सके.

flyCameraTo() का इस्तेमाल करने पर, व्यू हर जगह के बीच "बाउंस" करेगा.

सबसे पहले, MapHelpers.swift में "innsbruck" नाम का कैमरा डिक्लेयर करें.

public static var innsbruck: Camera = .init(
  latitude: 47.263,
  longitude: 11.3704,
  altitude: 640.08,
  heading: 237,
  tilt: 80.0,
  roll: 0.0,
  range: 200)

अब FlyAlongRoute.swift नाम की नई फ़ाइल में एक नया व्यू सेट अप करें.

SwiftUI और GoogleMaps3D इंपोर्ट करें. VStack के अंदर Map और Button जोड़ें. बूलियन animation वैरिएबल की स्थिति को टॉगल करने के लिए, Button को सेट अप करें.

FlightDataLoader के लिए State ऑब्जेक्ट का एलान करें. यह ऑब्जेक्ट, JSON फ़ाइल को शुरू होने पर लोड करेगा.

import GoogleMaps3D
import SwiftUI

struct FlyAlongRoute: View {
  @State private var camera: Camera = .innsbruck
  @State private var flyToDuration: TimeInterval = 5
  @State var animation: Bool = true

  @StateObject var flightData: FlightDataLoader = FlightDataLoader()

  var body: some View {
    VStack {
      Map(camera: $camera, mode: .hybrid)
      Button("Fly Along Route"){
        animation.toggle()
      }
    }
  }
}

मुख्य फ़्रेम बनाना

बुनियादी प्रोसेस में, ऐसा फ़ंक्शन बनाना होता है जो ऐनिमेशन क्रम में नया फ़्रेम दिखाता हो. हर नया फ़्रेम, कैमरे की अगली स्थिति तय करता है, ताकि ऐनिमेशन बनाने वाला व्यक्ति उस पर ऐनिमेशन बना सके. यह फ़ंक्शन बनाने के बाद, फ़ाइल में मौजूद हर जगह को क्रम से कॉल करें.

अपने FlyAlongRoute स्ट्रक्चर में दो फ़ंक्शन जोड़ें. फ़ंक्शन makeKeyFrame, कैमरे की स्थिति के साथ CubicKeyframe दिखाता है. फ़ंक्शन makeCamera, फ़्लाइट डेटा के क्रम में एक चरण आगे बढ़ता है और उस चरण को दिखाने वाला Camera ऑब्जेक्ट दिखाता है.

func makeKeyFrame(step: FlightPathLocation) -> CubicKeyframe<Camera> {
  return CubicKeyframe(
    makeCamera(step: step),
    duration: flyToDuration
  )
}

func makeCamera(step: FlightPathLocation) -> Camera {
  return .init(
    latitude: step.latitude,
    longitude: step.longitude,
    altitude: step.altitude,
    heading: step.bearing,
    tilt: 75,
    roll: 0,
    range: 200
  )
}

ऐनिमेशन को एक साथ जोड़ना

Map को शुरू करने के बाद, keyframeAnimator को कॉल करें और शुरुआती वैल्यू सेट करें.

फ़्लाइट के पाथ की पहली जगह के आधार पर, आपको कैमरे की शुरुआती स्थिति की ज़रूरत होगी.

ऐनिमेशन, वैरिएबल की बदलती स्थिति के आधार पर ट्रिगर होना चाहिए.

keyframeAnimator कॉन्टेंट, मैप होना चाहिए.

फ़्लाइट पाथ में हर जगह को लूप करके, कीवर्ड की असल सूची जनरेट की जाती है.

   VStack {
      Map(camera: $camera, mode: .hybrid)
        .keyframeAnimator(
          initialValue: makeCamera(step: flightData.flightPathData.flight[0]),
          trigger: animation,
          content: { view, value in
            Map(camera: .constant(value), mode: .hybrid)
          },
          keyframes: { _ in
            KeyframeTrack(content: {
              for i in  1...flightData.flightPathData.flight.count-1 {
                makeKeyFrame(step: flightData.flightPathData.flight[i])
              }
            })
          }
        )
   }

अपने ऐप्लिकेशन की झलक देखें और उसे चलाएं.

अपने व्यू की झलक देखने के लिए, झलक दिखाने वाला पैनल खोलें.

GoogleMaps3DDemoApp.swift में FlightPathDemo() के डेस्टिनेशन वाला नया NavigationLink जोड़ें और इसे आज़माने के लिए ऐप्लिकेशन चलाएं.

11. बधाई हो

आपने ऐसा ऐप्लिकेशन बना लिया है जो

  • आपके ऐप्लिकेशन में बुनियादी 3D मैप जोड़ता है.
  • आपके मैप में मार्कर, लाइनें, पॉलीगॉन, और मॉडल जोड़ता है.
  • मैप और चुनिंदा जगहों पर फ़्लाय करने के लिए, कैमरे को कंट्रोल करने वाला कोड लागू करता है.

आपको क्या सीखने को मिला

  • Xcode SwiftUI ऐप्लिकेशन में GoogleMaps3D पैकेज जोड़ने का तरीका.
  • एपीआई पासकोड और डिफ़ॉल्ट व्यू की मदद से, 3D मैप को शुरू करने का तरीका.
  • अपने मैप में मार्कर, 3D मॉडल, लाइनें, और पॉलीगॉन जोड़ने का तरीका.
  • किसी दूसरी जगह पर जाने के लिए, कैमरे को कंट्रोल करने का तरीका.
  • जगह मार्कर पर क्लिक इवेंट को मैनेज करने का तरीका.

आगे क्या करना है?

  • iOS के लिए Maps 3D SDK टूल का इस्तेमाल करके क्या-क्या किया जा सकता है, इस बारे में ज़्यादा जानने के लिए डेवलपर गाइड देखें.
  • नीचे दिए गए सर्वे में हिस्सा लेकर, हमें आपके लिए सबसे ज़्यादा काम का कॉन्टेंट बनाने में मदद करें:

आपको कौनसी अन्य कोडलैब देखनी हैं?

मैप पर डेटा विज़ुअलाइज़ेशन अपने मैप की स्टाइल को पसंद के मुताबिक बनाने के बारे में ज़्यादा जानें मैप में 3D इंटरैक्शन के लिए बिल्डिंग