दस्तावेज़ / अवधारणा / आर्किटेक्चर

आर्किटेक्चर ओवरव्यू

MapConductor एप और विभिन्न मानचित्र SDK के बीच का पुल है। एप केवल एकीकृत मानचित्र API को कॉल करता है, और MapConductor चयनित प्रदाता को प्रोसेसिंग अग्रेषित करता है। Android (Kotlin + Compose) • iOS (Swift + SwiftUI) • React (Web) में, पैकेज का विभाजन और आंतरिक भूमिकाओं का वितरण भी समान डिज़ाइन है।

ANDROID
android-sdk-core
iOS
ios-sdk-core
REACT
js-sdk-core / js-sdk-react

01 · समग्र दृश्य

किसी भी प्लेटफ़ॉर्म पर प्रोसेसिंग का प्रवाह समान है। एप → एकीकृत मानचित्र API → Core → विभिन्न मानचित्र SDK ड्राइवर → विभिन्न मानचित्र SDK। ऊपर के 2 स्तर केवल एप के द्वारा लिखा गया कोड हैं, नीचे के 2 स्तर बदले जा सकते हैं।

APP

UI और बिज़नेस लॉजिक

React · Compose · SwiftUI
UNIFIED API

एकीकृत मैप API

MapViewState · Marker · Camera
CORE

कोर सुविधाएँ (मैप, मार्कर, आकृतियाँ, इवेंट)

Manager · Controller · Overlay
DRIVER

प्रोवाइडर ड्राइवर

*-for-googlemaps / -maplibre / …
MAP SDK

मैप SDK (नेटिव / JavaScript)

Google Maps · MapLibre · Mapbox · MapKit · ArcGIS · HERE …

प्रदाता बदलते समय, केवल सबसे निचले 2 स्तर बदलते हैं। चेहरे का कोड एकीकृत API के लिए लिखा गया है, इसलिए यह यथावत काम करता है।

प्लेटफ़ॉर्म

02 · प्लेटफ़ॉर्म-विशिष्ट कॉन्फ़िगरेशन

Core और ड्राइवर पैकेज के रूप में अलग हैं। एप केवल Core और उपयोग किए जा रहे प्रदाता के ड्राइवर को निर्भरता में जोड़ता है।

android-sdk-core में सामान्य मॉडल और अंतर लागू करना है, और android-sdk-compose Compose के लिए स्टेट होल्डर प्रदान करता है। GeoJSON • क्लस्टरिंग • हीटमैप अतिरिक्त मॉड्यूल (android-geo-layer / android-marker-clustering / android-heatmap) के रूप में स्वतंत्र हैं।

03 · स्तर संरचना

प्लेटफ़ॉर्म के पार पुनः उपयोग करने योग्य बनाने के लिए, जिम्मेदारियों को 6 स्तरों में विभाजित किया गया है। ऊपरी स्तर निचले स्तर की वास्तविकता नहीं जानता है।

#
स्तर
भूमिका
1
UI ढांचा
React / Vue / Jetpack Compose / SwiftUI आदि, जो ऐप उपयोग करता है घोषणात्मक UI।
2
एकीकृत मानचित्र API
मार्कर, आकृतियाँ, कैमरा, घटनाओं को सामान्य अवधारणाओं से निपटाने वाला MapConductor का API। ऐप जो वास्तव में कोड लिखता है वह यहाँ के लिए लिखा जाता है।
3
पुल
एकीकृत API के संचालन को निष्पादन वातावरण के अनुसार नीचे की ओर पुल के रूप में स्थानांतरित करता है। UI और रेंडरिंग एक ही निष्पादन वातावरण में पूर्ण होने पर इसकी आवश्यकता नहीं होती है, और यह केवल तब हस्तक्षेप करता है जब दोनों अलग-अलग निष्पादन वातावरण में विभाजित होते हैं।
4
क्रॉस-प्लेटफ़ॉर्म परत
मूल मानचित्र SDK को एम्बेड करने की विधि और घोषणा की विधि केवल इस परत में प्रत्येक प्लेटफ़ॉर्म के लिए भिन्न होती है।
5
मूल SDK / ड्राइवर
कैमरा, शैली, ओवरले की रेंडरिंग को वास्तव में संभालने वाली परत (Android / iOS का मूल, या Web का JS ड्राइवर)।
6
मानचित्र SDK
Google Maps / MapKit / MapLibre / Mapbox / ArcGIS / HERE आदि की वास्तविकता।

इस पृथक्करण के माध्यम से, "कौन सा प्लेटफ़ॉर्म है" के बजाय "मानचित्र पर क्या करना है" पर केंद्रित कोड को यथावत बहु-वातावरणों में तैनात किया जा सकता है। प्लेटफ़ॉर्म-विशिष्ट अंतर, सिद्धांत रूप में, क्रॉस-प्लेटफ़ॉर्म परत की स्थापना / घोषणा विधि में ही बंद रखे जाते हैं।

React Native के मामले में

Web और React Native ऐप्स कोड साझा करते हैं। स्टेट ऑब्जेक्ट और कंपोनेंट भी समान हैं, बस चुना गया MapView बदलना है। अंतर उसके नीचे है। Web में ड्राइवर उसी एक्ज़ीक्यूशन एनवायरनमेंट के JavaScript मैप लाइब्रेरी को कॉल करता है, जबकि React Native में यह ब्रिज के ज़रिए MapConductor के नेटिव SDK में जाता है और अंत में नेटिव मैप SDK रेंडर करता है।

वही कोड, कहाँ अलग होता है
SHARED

ऐप जो लिखता है

js-sdk-core · js-sdk-react
WEB

React

DRIVER
JavaScript ड्राइवर
react-for-*
कोई ब्रिज नहीं — एक ही रनटाइम
MAP SDK
JavaScript मैप SDK
Google Maps · MapLibre · Leaflet · Cesium …
REACT NATIVE

React Native

DRIVER
नेटिव को सौंपने वाला ड्राइवर
reactnative-for-*
BRIDGE
RN नेटिव मॉड्यूल
परत 3
NATIVE SDK
MapConductor नेटिव SDK → मैप SDK
Google Maps · MapLibre · ArcGIS · HERE

ऊपर दी गई तालिका में लेयर 3 ब्रिज है। Web में UI और रेंडरिंग उसी एक्ज़ीक्यूशन एनवायरनमेंट में पूरी हो जाती है, इसलिए यह बीच में नहीं आता। React Native में दोनों अलग-अलग एक्ज़ीक्यूशन एनवायरनमेंट में बँट जाते हैं, इसलिए यहाँ इसकी ज़रूरत होती है। प्लैटफ़ॉर्म के हिसाब से सिर्फ़ यह लेयर अलग है, इसके ऊपर कुछ नहीं बदलता।

React Native में उपलब्ध प्रोवाइडर Google Maps, MapLibre, ArcGIS, HERE — ये चार हैं। नेटिव साइड पर संगत मॉड्यूल वालों तक सीमित होने की वजह से, ये Web के 13 प्रोवाइडर से कम हैं।

04 · Core की आंतरिक संरचना

Core मार्कर, पॉलीलाइन, पॉलीगन, सर्कल, ग्राउंड ओवरले, रास्टर लेयर आदि हर एलिमेंट के लिए, वही 7 भूमिकाओं को दोहराने के रूप में बना है। एक समझ लें, बाकी एलिमेंट भी उसी तरह से पढ़े जा सकते हैं।

भूमिका
जिम्मेदारी
कार्यान्वयन स्थान
State
ऐप द्वारा दिया गया अपरिवर्तनीय मान। कोऑर्डिनेट, रंग, zIndex आदि। fingerPrint() से कंटेंट का हैश लौटाता है।
core
Entity
State, और प्रोवाइडर द्वारा वास्तव में बनाया गया ऑब्जेक्ट, उस समय का fingerPrint — इन्हें बाँधकर बनी एक रिकॉर्ड।
core
Manager
Entity को id से रखने वाला रजिस्टर। कोऑर्डिनेट से हिट टेस्ट (find) भी यही संभालता है।
core
Controller
add / update / clear / find / onCameraChanged / destroy वाला ऑपरेशन का विंडो। डेल्टा का निर्धारण करता है।
core
Overlay
समान प्रकार के एलिमेंट को जोड़ने वाली रेंडरिंग यूनिट। zIndex से ओवरलैप का क्रम तय करती है।
core
OverlayRenderer
onAdd / onChange / onRemove / onPostProcess को हर मैप SDK कॉल में बदलता है। एलिमेंट के लिए तैयार एब्सट्रैक्ट क्लास (जैसे AbstractPolygonOverlayRenderer) को इनहेरिट करके सिर्फ़ 3 मेथड भरने होते हैं।
driver
Capable
यह घोषित करता है कि वह प्रदाता किन तत्वों को संभाल सकता है, टाइप के रूप में (compositionPolygons / updatePolygon / hasPolygon)। प्रत्येक तत्व के लिए एक तैयार किया जाता है, और इसे Kotlin में PolygonCapableInterface, TypeScript में PolygonCapable की तरह नाम दिया जाता है। Swift में यह प्रोटोकॉल नहीं है, बल्कि यह इस बात से व्यक्त होता है कि क्या उस प्रदाता के पास PolygonController है या नहीं।
driver

महत्वपूर्ण है सीमा की स्थिति। Core पक्ष (State / Entity / Manager / Controller / Overlay) लगभग समान कोड के रूप में तीनों भाषाओं में लिखा गया है, और प्रति प्रदाता केवल Renderer और उस तत्व को संभालने की घोषणा लिखी जाती है।

ANDROID · Kotlin
iOS · Swift
REACT · TypeScript
core/polygon/PolygonManager.kt
PolygonCapableInterface.kt
AbstractPolygonOverlayRenderer.kt
polygon/PolygonManager.swift
polygon/PolygonOverlayRenderer.swift
polygon/PolygonHoleSplit.swift
polygon/PolygonManager.ts
polygon/PolygonCapable.ts
AbstractPolygonOverlayRenderer.ts

05 · अंतर लागू करने की प्रक्रिया

ऐप केवल "वर्तमान में होने वाली स्थिति की सरणी" पास करता है। Core पिछली बार के साथ अंतर निकालता है, और बढ़ी हुई चीज़ों, बदली हुई चीज़ों और मिटाई गई चीज़ों में अलग करके ड्राइवर को पास करता है। मानचित्र ऑब्जेक्ट को फिर से नहीं बनाया जाता है, इसलिए बड़ी मात्रा में तत्वों के लिए भी रेंडरिंग स्थिर रहता है।

controller/OverlayRendererInterface.ts · 3 प्लेटफ़ॉर्म सामान्य अनुबंध
export interface OverlayRendererInterface<ActualType, StateType, EntityType> {
    onAdd(data: StateType[]): Promise<Array<ActualType | null>> | Array<ActualType | null>;
    onChange(data: Array<ChangeParamsInterface<EntityType>>): Promise<Array<ActualType | null>> | Array<ActualType | null>;
    onRemove(data: EntityType[]): Promise<void> | void;
    onPostProcess(): Promise<void> | void;
}

onChange पिछला Entity (prev) और वर्तमान State (current) दोनों प्राप्त करता है। ड्राइवर केवल बदले गए गुणों को अपडेट कर सकता है, और Kotlin / Swift में भी सिग्नेचर समान है।

06 · ड्राइवर द्वारा लागू किए जाने वाले तत्व

नए मानचित्र SDK के अनुकूल होने का काम प्रत्येक तत्व के लिए एब्सट्रैक्ट रेंडरर को इनहेरिट करके तीन संचालन को भरने तक सीमित है। Core के मॉडल या अंतर लॉजिक में कोई बदलाव नहीं किया जाता है।

android-for-googlemaps · रेंडरर का कार्यान्वयन
// ड्राइवर एब्स्ट्रैक्ट रेंडरर से विरासत लेता है और सिर्फ़ तीन ऑपरेशन भरता है
internal class GoogleMapPolygonOverlayRenderer(
    override val holder: GoogleMapViewHolder,
    override val coroutine: CoroutineScope,
) : AbstractPolygonOverlayRenderer<GoogleMapActualPolygon>() {

    override suspend fun createPolygon(state: PolygonState) = /* map.addPolygon(...) */
    override suspend fun updatePolygonProperties(polygon, current, prev) = /* सिर्फ़ अंतर लागू करें */
    override suspend fun removePolygon(entity: PolygonEntityInterface<GoogleMapActualPolygon>) =
        entity.polygon.remove()
}

निर्माण, अपडेट और हटाने के केवल तीन ही प्रदाता-विशिष्ट हैं। अंतर निर्धारण, रजिस्टर प्रबंधन, और हिट टेस्ट Core द्वारा पूरा कर लिए जाते हैं।

07 · अमूर्तता की सीमा और एस्केप हैच

MapConductor हर मैप SDK की हर सुविधा को रैप नहीं करता। यह आम तौर पर इस्तेमाल होने वाली ऑपरेशन पर फ़ोकस करता है, और उससे आगे की मांगों के लिए दो रास्ते उपलब्ध कराता है।

getMapViewHolder() · नेटिव सुविधाओं को सीधे कॉल करें
// साझा इंटरफ़ेस का map unknown है — इस्तेमाल से पहले प्रोवाइडर के टाइप तक सीमित करें
const holder = mapViewState.getMapViewHolder();
const map = holder?.map as maplibregl.Map | undefined;

map?.addLayer({ id: 'buildings', type: 'fill-extrusion', source: 'composite' });

यह डिज़ाइन साझा API को सरल रखते हुए, हर प्रोवाइडर की खास ताक़त को भी खराब नहीं करता। विस्तार के लिए "नेटिव एक्सटेंशन" देखें।

संबंधित पेज