आर्किटेक्चर ओवरव्यू
MapConductor एप और विभिन्न मानचित्र SDK के बीच का पुल है। एप केवल एकीकृत मानचित्र API को कॉल करता है, और MapConductor चयनित प्रदाता को प्रोसेसिंग अग्रेषित करता है। Android (Kotlin + Compose) • iOS (Swift + SwiftUI) • React (Web) में, पैकेज का विभाजन और आंतरिक भूमिकाओं का वितरण भी समान डिज़ाइन है।
01 · समग्र दृश्य
किसी भी प्लेटफ़ॉर्म पर प्रोसेसिंग का प्रवाह समान है। एप → एकीकृत मानचित्र API → Core → विभिन्न मानचित्र SDK ड्राइवर → विभिन्न मानचित्र SDK। ऊपर के 2 स्तर केवल एप के द्वारा लिखा गया कोड हैं, नीचे के 2 स्तर बदले जा सकते हैं।
UI और बिज़नेस लॉजिक
एकीकृत मैप API
कोर सुविधाएँ (मैप, मार्कर, आकृतियाँ, इवेंट)
प्रोवाइडर ड्राइवर
मैप SDK (नेटिव / JavaScript)
प्रदाता बदलते समय, केवल सबसे निचले 2 स्तर बदलते हैं। चेहरे का कोड एकीकृत API के लिए लिखा गया है, इसलिए यह यथावत काम करता है।
02 · प्लेटफ़ॉर्म-विशिष्ट कॉन्फ़िगरेशन
Core और ड्राइवर पैकेज के रूप में अलग हैं। एप केवल Core और उपयोग किए जा रहे प्रदाता के ड्राइवर को निर्भरता में जोड़ता है।
android-sdk-core में सामान्य मॉडल और अंतर लागू करना है, और android-sdk-compose Compose के लिए स्टेट होल्डर प्रदान करता है। GeoJSON • क्लस्टरिंग • हीटमैप अतिरिक्त मॉड्यूल (android-geo-layer / android-marker-clustering / android-heatmap) के रूप में स्वतंत्र हैं।
ios-sdk-core में सामान्य मॉडल और SwiftUI दृश्य का आधार है, और प्रत्येक SwiftUI दृश्य प्रदाता पैकेज (ios-for-*) द्वारा प्रदान किए जाते हैं। MapKit ड्राइवर Apple मूल SDK के लिए है, जिसका उपयोग किसी अतिरिक्त शुल्क या API कुंजी के बिना किया जा सकता है।
js-sdk-core React पर निर्भर नहीं करने वाला TypeScript का कोर है, जिसमें सामान्य मॉडल और अंतर लागू करना है (Kotlin / Swift के core के समान ही विन्यास है)। js-sdk-react इसे React पर ले जाता है, और Marker / Polygon / Polyline / Circle / GroundImage / RasterLayer / InfoBubble जैसे घटक प्रदान करता है। मानचित्र दृश्य स्वयं प्रत्येक ड्राइवर (react-for-*) "दृश्य + हुक" के जोड़े में MapLibreMapView / MapLibreMapView2D और useMapLibreViewState की तरह प्रकाशित करता है। GeoJSON, क्लस्टरिंग, हीटमैप और आइकन अतिरिक्त पैकेज (react-geo-layer / react-marker-clustering / react-heatmap / react-icons) के रूप में स्वतंत्र हैं।
03 · स्तर संरचना
प्लेटफ़ॉर्म के पार पुनः उपयोग करने योग्य बनाने के लिए, जिम्मेदारियों को 6 स्तरों में विभाजित किया गया है। ऊपरी स्तर निचले स्तर की वास्तविकता नहीं जानता है।
इस पृथक्करण के माध्यम से, "कौन सा प्लेटफ़ॉर्म है" के बजाय "मानचित्र पर क्या करना है" पर केंद्रित कोड को यथावत बहु-वातावरणों में तैनात किया जा सकता है। प्लेटफ़ॉर्म-विशिष्ट अंतर, सिद्धांत रूप में, क्रॉस-प्लेटफ़ॉर्म परत की स्थापना / घोषणा विधि में ही बंद रखे जाते हैं।
React Native के मामले में
Web और React Native ऐप्स कोड साझा करते हैं। स्टेट ऑब्जेक्ट और कंपोनेंट भी समान हैं, बस चुना गया MapView बदलना है। अंतर उसके नीचे है। Web में ड्राइवर उसी एक्ज़ीक्यूशन एनवायरनमेंट के JavaScript मैप लाइब्रेरी को कॉल करता है, जबकि React Native में यह ब्रिज के ज़रिए MapConductor के नेटिव SDK में जाता है और अंत में नेटिव मैप SDK रेंडर करता है।
React
React Native
ऊपर दी गई तालिका में लेयर 3 ब्रिज है। Web में UI और रेंडरिंग उसी एक्ज़ीक्यूशन एनवायरनमेंट में पूरी हो जाती है, इसलिए यह बीच में नहीं आता। React Native में दोनों अलग-अलग एक्ज़ीक्यूशन एनवायरनमेंट में बँट जाते हैं, इसलिए यहाँ इसकी ज़रूरत होती है। प्लैटफ़ॉर्म के हिसाब से सिर्फ़ यह लेयर अलग है, इसके ऊपर कुछ नहीं बदलता।
React Native में उपलब्ध प्रोवाइडर Google Maps, MapLibre, ArcGIS, HERE — ये चार हैं। नेटिव साइड पर संगत मॉड्यूल वालों तक सीमित होने की वजह से, ये Web के 13 प्रोवाइडर से कम हैं।
04 · Core की आंतरिक संरचना
Core मार्कर, पॉलीलाइन, पॉलीगन, सर्कल, ग्राउंड ओवरले, रास्टर लेयर आदि हर एलिमेंट के लिए, वही 7 भूमिकाओं को दोहराने के रूप में बना है। एक समझ लें, बाकी एलिमेंट भी उसी तरह से पढ़े जा सकते हैं।
महत्वपूर्ण है सीमा की स्थिति। Core पक्ष (State / Entity / Manager / Controller / Overlay) लगभग समान कोड के रूप में तीनों भाषाओं में लिखा गया है, और प्रति प्रदाता केवल Renderer और उस तत्व को संभालने की घोषणा लिखी जाती है।
PolygonCapableInterface.kt
AbstractPolygonOverlayRenderer.kt
polygon/PolygonOverlayRenderer.swift
polygon/PolygonHoleSplit.swift
polygon/PolygonCapable.ts
AbstractPolygonOverlayRenderer.ts
05 · अंतर लागू करने की प्रक्रिया
ऐप केवल "वर्तमान में होने वाली स्थिति की सरणी" पास करता है। Core पिछली बार के साथ अंतर निकालता है, और बढ़ी हुई चीज़ों, बदली हुई चीज़ों और मिटाई गई चीज़ों में अलग करके ड्राइवर को पास करता है। मानचित्र ऑब्जेक्ट को फिर से नहीं बनाया जाता है, इसलिए बड़ी मात्रा में तत्वों के लिए भी रेंडरिंग स्थिर रहता है।
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 के मॉडल या अंतर लॉजिक में कोई बदलाव नहीं किया जाता है।
// ड्राइवर एब्स्ट्रैक्ट रेंडरर से विरासत लेता है और सिर्फ़ तीन ऑपरेशन भरता है
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 द्वारा पूरा कर लिए जाते हैं।
// Kotlin जैसा ही ढाँचा: एब्स्ट्रैक्ट रेंडरर से विरासत लेकर तीन ऑपरेशन भरें
final class MapKitPolygonOverlayRenderer: AbstractPolygonOverlayRenderer<MKPolygon> {
override func createPolygon(state: PolygonState) async -> MKPolygon? { /* MKPolygon(...) */ }
override func updatePolygonProperties(polygon, current, prev) async -> MKPolygon? { /* सिर्फ़ अंतर लागू करें */ }
override func removePolygon(entity: PolygonEntity<MKPolygon>) async { /* mapView.removeOverlay */ }
}
// कंट्रोलर Core का जेनेरिक इंप्लीमेंटेशन जस का तस इस्तेमाल करता है
final class MapKitPolygonController: PolygonController<MKPolygon, MapKitPolygonOverlayRenderer> { }Swift में "वह प्रदाता जिसके पास नियंत्रक है" कार्य सूची बन जाता है। पॉलीगन के छेद या मार्कर एनीमेशन की तरह जो सुविधाएं SDK पक्ष के पास नहीं हैं, उन्हें संबंधित रेंडरर को लागू न करके या कोर पक्ष के वैकल्पिक निरूपण (जैसे PolygonHoleSplit द्वारा छेद रहित साधारण रिंग में विभाजित करना) में स्विच करके व्यक्त किया जाता है।
// Kotlin और Swift जैसा ही ढाँचा: एब्स्ट्रैक्ट रेंडरर से विरासत लेकर तीन ऑपरेशन भरें
export class MapLibrePolygonOverlayRenderer extends AbstractPolygonOverlayRenderer<
MapLibreMapViewHolder,
MapLibreActualPolygon
> {
async createPolygon(state: PolygonState) { /* GeoJSON फ़ीचर बनाएँ */ }
async updatePolygonProperties({ current, prev }) { /* सिर्फ़ अंतर लागू करें */ }
async removePolygon(entity: PolygonEntity<MapLibreActualPolygon>) { /* हटाएँ */ }
// अंतर लागू होने के बाद, बची हुई एंटिटी से स्रोत दोबारा लिखें
override async onPostProcess() { this.layer.draw(this.polygonManager.allEntities()); }
}
// जो तत्व संभाले जा सकते हैं, उन्हें Capable इंटरफ़ेस implements करके टाइप के रूप में घोषित करें
export class MapLibreViewController extends BaseMapViewController
implements MapViewControllerInterface, MarkerCapable, PolygonCapable, /* … */ { }TypeScript में भी बनाना, अपडेट करना और हटाना—ये तीन ही प्रोवाइडर-विशिष्ट हैं। MapLibre की तरह लेयर में एक साथ बनाने वाले SDK में, एक-एक करके हटाने के बजाय onPostProcess में पूरे सोर्स को फिर से लिखना, जैसे अलग-अलग तरीकों को भी रेंडरर के अंदर ही सीमित रखा जाता है। ड्राइवर जिन तत्वों को संभाल सकता है, वे MapLibreViewController द्वारा लागू किए गए Capable इंटरफ़ेस (जैसे PolygonCapable) से व्यक्त होते हैं, और उनका इस्तेमाल किया जा सकता है या नहीं, यह टाइप से समझा जा सकता है।
07 · अमूर्तता की सीमा और एस्केप हैच
MapConductor हर मैप SDK की हर सुविधा को रैप नहीं करता। यह आम तौर पर इस्तेमाल होने वाली ऑपरेशन पर फ़ोकस करता है, और उससे आगे की मांगों के लिए दो रास्ते उपलब्ध कराता है।
// साझा इंटरफ़ेस का map unknown है — इस्तेमाल से पहले प्रोवाइडर के टाइप तक सीमित करें
const holder = mapViewState.getMapViewHolder();
const map = holder?.map as maplibregl.Map | undefined;
map?.addLayer({ id: 'buildings', type: 'fill-extrusion', source: 'composite' });यह डिज़ाइन साझा API को सरल रखते हुए, हर प्रोवाइडर की खास ताक़त को भी खराब नहीं करता। विस्तार के लिए "नेटिव एक्सटेंशन" देखें।