भविष्य को आकार देने वाली तकनीक पर गहन लेख।

पूरे देश को वॉक्सल में बदलना: एक जियोडेटा पाइपलाइन

स्विट्ज़रलैंड के ओपन जियोडेटा से 1:1 Minecraft दुनिया बनाने वाली वॉक्सल पाइपलाइन: टाइल, LOD और स्पेशियल डेटा स्ट्रीमिंग के सबक।

ब्लॉकी ग्लेशियर और सीढ़ीदार घनाकार पहाड़ चोटियों वाली वॉक्सल-शैली की अल्पाइन घाटी।
एक ब्लॉक, एक मीटर: खुले सरकारी जियोडेटा से वॉक्सल में दोबारा बनाया गया एक पूरा देश।

स्विस सरकार के ओपन-डेटा पोर्टल में कहीं एक हाइटमैप पड़ा है, जिसमें आइगर की उत्तरी दीवार इतनी बारीकी से नापी गई है कि चट्टान का खुरदुरापन महसूस हो। एक डेवलपर ने ऐसी फ़ाइलों को वॉक्सल पाइपलाइन में डाला और नतीजा एक खेलने लायक प्रोडक्ट बनकर सामने आया: पूरा स्विट्ज़रलैंड 1:1 Minecraft दुनिया के रूप में, जहाँ हर ब्लॉक एक मीटर का है और मैटरहॉर्न अपनी असली ऊँचाई और ढलान के साथ खड़ा है। डाउनलोड ज़िप करके 24 GB का है, और मुफ़्त सैंपल क्षेत्र अकेला लगभग 2,400 km² को कवर करता है। इसके नीचे का इंजीनियरिंग काम — टाइलिंग, लेवल ऑफ़ डिटेल, और आलसी (lazy) जनरेशन — इस बात का बढ़िया उदाहरण है कि विशाल स्पेशियल डेटासेट को बिना सिस्टम को चरमराए कैसे संभाला जाए।

समस्या: वॉक्सल वाला देश मेमोरी में नहीं समाएगा

हिसाब लगाकर देखिए। स्विट्ज़रलैंड का क्षेत्रफल 41,285 km² है। हर वर्ग मीटर पर एक ब्लॉक रखें, तो एक भी गड्ढा खोदने से पहले ही 41.3 अरब सतह कॉलम हो जाते हैं। हर कॉलम में सिर्फ़ 100 ब्लॉक गहराई जोड़ दें — पत्थर, मिट्टी, झील की तली — तो यह चार ट्रिलियन ब्लॉक पर पहुँच जाता है। प्रति ब्लॉक एक बाइट भी मानें, तो यह चार टेराबाइट कच्ची ज्यामिति है। फिर भी तैयार दुनिया 24 GB की ज़िप फ़ाइल बनती है, जो एक ज़रूरी बात बताती है: इसकी लगभग पूरी ज्यामिति असल में ज्यामिति की तरह स्टोर ही नहीं हुई। वह एक नुस्खे (recipe) के रूप में स्टोर होती है।

ऊर्ध्वाधर अक्ष भी दिक्कत खड़ी करता है। वेनिला Minecraft दुनिया की build height 384 ब्लॉक पर सीमित रखता है। स्विट्ज़रलैंड समुद्र तल से 193 m ऊँचे Lago Maggiore से लेकर 4,634 m ऊँची Dufourspitze तक फैला है — यानी 4,441 m का फासला, जो वेनिला सीमा से ग्यारह गुने से भी ज़्यादा है, और अभी किसी ने खान खोदना भी शुरू नहीं किया। इसलिए इस दुनिया को Cubic Chunks चाहिए, एक मॉड जो कॉलम-आधारित स्टोरेज की जगह 16×16×16 क्यूब्स का इस्तेमाल करता है, जिन्हें ज़रूरत भर ऊपर तक स्टैक किया जा सकता है। यह मॉड केवल Minecraft Java 1.12.2 पर स्थिर चलता है, इसलिए आज शिप होने वाला यह प्रोजेक्ट कई साल पुराना गेम वर्शन पकड़े बैठा है।

मेमोरी तीसरी दीवार है। किसी खिलाड़ी के पहली बार किसी इलाके में पहुँचने पर स्रोत डेटा से ब्लॉक बनाना कम्प्यूट-भारी काम है: प्रोजेक्ट कम से कम 16 GB RAM माँगता है और 32 GB वाले Ryzen 7 7800X3D जैसी मशीनों पर टेस्ट होता है। गेम या GIS में स्ट्रीमिंग बजट से जूझ चुका कोई भी इस ढाँचे को पहचान लेगा। यह वही छँटाई है जो जब आपका GPU VRAM खत्म कर देता है तब करनी पड़ती है — सब कुछ पकड़ नहीं सकते, तो इस पल क्या पकड़ना है, यह तय करने में माहिर बनना पड़ता है।

नाकाम कोशिश एक: पूरी दुनिया पहले से बेक कर दें

सबसे स्पष्ट तरीका है एक बड़ा ऑफ़लाइन जॉब: जियोडेटा पढ़ें, Minecraft की region फ़ाइलें बनाएँ — Anvil फ़ॉर्मेट दुनिया को 512×512-ब्लॉक region में रखता है — फिर नतीजे को ज़िप करके शिप कर दें। डेनमार्क ने 2014 में कुछ ऐसा ही किया था, जब Danish Geodata Agency ने पूरे देश को Minecraft मैप के रूप में जारी किया था। यह ओपन-डेटा का एक ऐतिहासिक डेमो था और साबित हुआ कि देश-स्तर का मैप संभव है। तो यह तरीका क्यों नहीं?

क्योंकि प्री-बेकिंग की संरचनात्मक लागत महत्वाकांक्षा के साथ बढ़ती है। हर region के हर ब्लॉक को खेलने से पहले जनरेट, लिखा और कंप्रेस करना पड़ता है, यानी हर डेटा रिफ़्रेश का मतलब पूरा री-बिल्ड और दसियों गीगाबाइट का दोबारा शिप। हर खिलाड़ी ऐसा पहाड़ों जितना टेरेन डाउनलोड करता है जहाँ वह कभी नहीं जाएगा — और 41,000 km² के ज़्यादातर हिस्से पर शायद कोई कभी जाएगा ही नहीं। सबसे बुरी बात: बेक की गई दुनिया प्रकाशन के समय अपने डेटा स्नैपशॉट पर जम जाती है। वह एक बार लिखा जाने वाला आर्टिफ़ैक्ट है। सब कुछ दोबारा जनरेट करके फिर से वितरित किए बिना वह बेहतर नहीं हो सकती, और यूज़र्स को पूरी धरती दोबारा डाउनलोड करनी पड़ती है।

नाकाम कोशिश दो: एक हाइटमैप, एक रिज़ॉल्यूशन

दूसरा प्रलोभन है नॉर्मलाइज़ेशन: हर इनपुट को एक ही ग्लोबल रास्टर में, एक ही रिज़ॉल्यूशन पर बदल दो, ताकि पाइपलाइन में सिर्फ़ एक कोड-पाथ रहे। स्विट्ज़रलैंड के भीतर आपके पास swissALTI3D है, एक हाई-रिज़ॉल्यूशन टेरेन मॉडल। सीमा के बाहर Copernicus GLO-30 DEM है — हर 30 मीटर पर एक एलिवेशन पॉइंट। एकरूपता के लिए सब कुछ 30 m पर घटा दें, तो आइगर की उत्तरी दीवार सीढ़ीदार रेत के ढेर जैसी दिखेगी। सब कुछ सबसे बारीक उपलब्ध रिज़ॉल्यूशन पर ऊपर उठा दें, तो स्टोरेज और प्रोसेसिंग फट जाएगी, और सीमावर्ती इलाकों में फिर भी कोई असली डेटा नहीं होगा — आपने बस अपनी अज्ञानता को अपस्केल कर दिया।

विषमता एलिवेशन जितनी ही सेमेंटिक्स पर भी चोट करती है। swissBUILDINGS3D स्विट्ज़रलैंड को कवर करता है, इसलिए जनरेटर असली फुटप्रिंट पर सरल वॉक्सल इमारतें खड़ी कर सकता है — लेकिन सिर्फ़ देश के भीतर। जिनेवा के पास सीमा पार करते ही बिल्डिंग लेयर बिल्कुल नहीं होती, तो पाइपलाइन एक ही समझदार फ़ॉलबैक करती है: जहाँ घर होने चाहिए थे वहाँ पेड़ लगा देती है। पानी का अपना स्रोत चाहिए (झीलों की तली के लिए swissBATHY3D), और ग्लेशियर, जंगल और अंगूर के बाग़ भी। कोई एक इनपुट फ़ाइल नहीं है। जियोडेटा में कभी होती ही नहीं।

यह सबक Minecraft से कहीं आगे तक लागू होता है: रिज़ॉल्यूशन हर टाइल का मेटाडेटा है, कोई ग्लोबल स्थिरांक नहीं। जो पाइपलाइन इनपुट को एकरूप मान लेती है, वह या तो फ़िडेलिटी बर्बाद करेगी या उसे गढ़ लेगी — और गढ़ी हुई फ़िडेलिटी ईमानदार मोटेपन से बदतर है, क्योंकि अंदर से कोई फ़र्क नहीं बता सकता।

मानचित्र टाइल्स की एक ग्रिड कीप से होकर बहती है और एक असेंबल्ड वॉक्सल लैंडस्केप बनकर उभरती है।
मुख्य उलटफेर: डेटा को टाइल और नुस्खों के रूप में रखें, और ब्लॉक सिर्फ़ वहीं बनाएँ जहाँ कोई सचमुच जाए।

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

स्विस प्रोजेक्ट इसलिए काम करता है क्योंकि वह “सब कुछ पहले से बना दो” वाली प्रवृत्ति को उलटता है। आप तैयार दुनिया डाउनलोड नहीं करते; आप एक वर्ल्ड पैकेज डाउनलोड करते हैं — पहले से प्रोसेस किया गया जियोडेटा और एक कस्टम जनरेटर — और गेम किसी जगह पर पहली बार पहुँचने पर ब्लॉक बनाता है। किसी नए इलाके की पहली विज़िट में कुछ मिनट की हलचल लगती है; उसके बाद वह किसी भी दूसरी Minecraft दुनिया की तरह कैश्ड चंक बन जाता है। कम्प्यूट हर विज़िट पर चुकाया जाता है, पहले से नहीं, और ऐसा टेरेन कभी जनरेट नहीं होता जिस पर कोई खड़ा ही न हो। टाइल ही हर चीज़ की इकाई है: स्टोरेज, कैशिंग, जनरेशन और फ़ेल्योर।

टाइलिंग स्विट्ज़रलैंड की आधिकारिक सर्वे कोऑर्डिनेट प्रणाली LV95 पर टिकी है। हर टाइल रिकॉर्ड करती है कि कौन से डेटासेट उसे कवर करते हैं और किस रिज़ॉल्यूशन पर, और सर्वे कोऑर्डिनेट्स को ब्लॉक कोऑर्डिनेट्स में बदलना एक शुद्ध एफ़िन ट्रांसफ़ॉर्म है। प्रोजेक्ट वह फ़ॉर्मूला भी प्रकाशित करता है, ताकि आप राष्ट्रीय मैप व्यूअर से कोऑर्डिनेट्स लेकर गेम में ठीक उसी जगह टेलीपोर्ट कर सकें:

def lv95_to_block(east: float, north: float, height: float) -> tuple[int, int, int]:
"""Convert Swiss LV95 survey coordinates to Minecraft block coordinates."""
x = int(east - 2_480_000)   # strip the LV95 easting offset
z = int(1_300_000 - north)  # Minecraft's z axis grows southward
y = int(height)             # one block = one meter above sea level
return x, y, z
# The summit of the Jungfrau, 4,158 m:
print(lv95_to_block(2_640_188, 1_154_072, 4158))
# -> (160188, 4158, 145928)
# x and z match the in-game teleport command exactly; the game just
# drops you a few meters higher so you land on the summit, not in it.

टाइल्ड ग्रिड के ऊपर जनरेशन एक लेयर-स्टैक है जिसे हर कॉलम पर मूल्यांकित किया जाता है। बेस ऊँचाई swissALTI3D से आती है। सतह का आवरण — पानी, जंगल, सड़कें, रेलवे लाइनें, बाँध, हिमस्खलन अवरोधक — swissTLM3D से आता है। झीलों की तली swissBATHY3D से, पेड़ों की ऊँचाई swissSURFACE3D से, 1850 तक जाने वाली GLAMOS इन्वेंट्री से ग्लेशियर की रूपरेखा, और ETH Zürich के डेटासेट से बर्फ़ की मोटाई आती है — ताकि Aletsch ग्लेशियर चट्टान पर बिछी सफ़ेद टेक्सचर नहीं, बल्कि सचमुच तराशी गई बर्फ़ हो। घास के मैदान, स्क्री और अंगूर के बाग़ संघीय आवास मानचित्र से आते हैं; यहाँ तक कि ज़्यूरिख़ के सड़क के पेड़ भी शहर के अपने वृक्ष कैडस्ट्रे से हैं। कुल मिलाकर लगभग पंद्रह ओपन डेटासेट हैं, सब मुफ़्त में इस्तेमाल योग्य — swisstopo ने 2021 में अपना डेटा, व्यावसायिक उपयोग समेत, खोल दिया था।

वॉक्सल दुनिया टेरेन की तस्वीर नहीं है। यह उन लाखों छोटे फ़ैसलों का कैश है जो आपकी पाइपलाइन ने हर वर्ग मीटर पर लिए, और दुनिया की गुणवत्ता ठीक उन्हीं फ़ैसलों की गुणवत्ता है।

लेवल ऑफ़ डिटेल एक रेंडरिंग चाल नहीं, डेटा की समस्या है

Minecraft का डिफ़ॉल्ट render distance कुछ सौ मीटर तक दिखाता है। प्रोजेक्ट के स्क्रीनशॉट में Aletsch ग्लेशियर किलोमीटरों तक मुड़ता हुआ दिखता है — वह दूर का दृश्य (“Fernsicht”) एक अलग, कम-फ़िडेलिटी वाला प्रतिनिधित्व है, जिसे गेम पहली बार लॉन्च होने पर एक बार बनाता है। यह क्लासिक LOD है, लेकिन असली बात यह है कि LOD कहाँ रहता है: इसे स्रोत डेटा से इनजेस्ट के समय गणना किया जाता है, रेंडरर द्वारा उड़ते हुए अंदाज़े से नहीं।

अगर आपने मैप-टाइल पिरामिड बनाए हैं, तो गणित जानते होंगे। हर ज़ूम लेवल दोनों अक्षों पर रिज़ॉल्यूशन आधा कर देता है, इसलिए पूरा पिरामिड बेस लेयर के लगभग 4/3 गुना जगह लेता है — हर स्केल पर सहज व्यवहार के लिए लगभग 33% स्टोरेज प्रीमियम। वॉक्सल टेरेन का LOD वही पिरामिड खड़ा करके बनाया गया है: दूर का टेरेन मोटा ज़ूम लेवल है, पास का टेरेन बारीक, और असली कला यह चुनने में है कि की-स्कीम ऐसी हो जो सही सेल तेज़ी से ले आए। यही सवाल हम geohash और सही spatial index के बीच के ट्रेड-ऑफ़ में भी देखते हैं — की का चुनाव आगे हर जगह आपकी लुकअप लागत तय करता है।

मेरा पसंदीदा LOD फ़ैसला दिखने में बिल्कुल भी विज़ुअल नहीं है। मुफ़्त डाउनलोड 2,400 km² का एक टुकड़ा है — Jungfrau-Aletsch UNESCO क्षेत्र: Eiger, Mönch, Jungfrau और आल्प्स का सबसे बड़ा ग्लेशियर — जो भुगतान वाले पूरे देश वाली उसी पाइपलाइन पर चलता है। यह एक फ़ीचर के रूप में कैनरी रिलीज़ है। यह 24 की जगह 1.1 GB का है, इसके लिए साइनअप नहीं चाहिए, और अगर यह आपकी मशीन पर चल गया, तो पूरा मैप भी चलेगा। अगर आप बड़े डेटा प्रोडक्ट शिप करते हैं, तो इसे सीधे अपना लें: आपका मुफ़्त टियर आपके सबसे कठिन टेरेन का प्रतिनिधि टुकड़ा होना चाहिए, न कि आपके सबसे आसान हिस्से का अपंग डेमो।

पास में बारीक छोटे ब्लॉक से धुंधली दूरी में विशाल मोटे ब्लॉक तक बदलते वॉक्सल पहाड़।
दूर का टेरेन उसी पिरामिड का मोटा ज़ूम लेवल है — LOD इनजेस्ट के समय तय होता है, रेंडरर के द्वारा नहीं।

वेब पर स्पेशियल टाइल्स की स्ट्रीमिंग

वही अनुशासन प्रोजेक्ट के सादे-से वेब पेज में भी दिखता है। उसका ओवरव्यू मैप एक स्लाइडर देता है, जिससे वॉक्सल दुनिया की असली हवाई तस्वीर से तुलना की जा सकती है — और यह इमेजरी प्रोजेक्ट के सर्वर से आती ही नहीं। स्लाइडर हिलाने के बाद ही आपका ब्राउज़र सीधे swisstopo की अपनी सेवा से SWISSIMAGE टाइल्स लाता है। आलसी, सीधे मूल स्रोत से, कैश-अनुकूल: भारी बैंडविड्थ वह सार्वजनिक इन्फ़्रास्ट्रक्चर उठाता है जो ठीक इसी काम के लिए बना है, और प्रोजेक्ट का अपना होस्टिंग बिल लगभग शून्य रहता है।

वेब पर टाइल एड्रेसिंग एक हल की जा चुकी समस्या है, और अगर आप कभी जियोस्पेशियल काम छूएँ तो इसे अच्छी तरह जानना फ़ायदेमंद है:

import math
def latlon_to_tile(lat: float, lon: float, zoom: int) -> tuple[int, int]:
"""Standard slippy-map (XYZ) tile addressing used by OSM and most WMTS fronts."""
n = 2 ** zoom
x = int((lon + 180.0) / 360.0 * n)
lat_rad = math.radians(lat)
y = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
return x, y
# At zoom 15, any point on Earth lands in one of 1,073,741,824 tiles.
# Fetch the few that intersect the viewport. Skip the other billion.

फ़ॉर्मूले से ज़्यादा मायने रखने वाली दो बातें हैं। पहली, अनुरोध तब तक टाला जाता है जब तक यूज़र का इरादा साफ़ न हो — स्लाइडर सचमुच हिलता है — जो बैंडविड्थ की बचत भी है और सार्वजनिक पैसे से चल रही मुफ़्त सार्वजनिक सेवा के प्रति शिष्टाचार भी। दूसरी, प्रोवेनेंस टाइल्स के साथ चलता है: पेज मैप पर ही SWISSIMAGE, swissBOUNDARIES3D और swissNAMES3D का श्रेय देता है। जब आपका प्रोडक्ट ओपन डेटा का व्युत्पन्न कार्य हो, तो प्रदर्शन के बिंदु पर एट्रिब्यूशन कोई सजावट नहीं है। यही तो लाइसेंस का इच्छित काम है।

स्विट्ज़रलैंड पाइपलाइन से क्या चुराएँ

पहले विरोधी तर्क, क्योंकि प्रैक्टिशनर्स ने अच्छे तर्क रखे हैं। Build the Earth जैसे हाथ से बनाए गए प्रयासों में हज़ारों स्वयंसेवक असली इमारतों की मॉडलिंग करते हैं, और कोई स्वचालित पाइपलाइन उस फ़िडेलिटी तक नहीं पहुँचती — वॉक्सलाइज़्ड swissBUILDINGS3D फुटप्रिंट एक मोटा अनुमान है, और अगर आर्किटेक्चर आपकी प्राथमिकता है तो सिर्फ़ टेरेन वाला एक्सपोर्ट शायद ज़्यादा साफ़ आर्टिफ़ैक्ट है। यह ठीक है। लेकिन कवरेज और फ़िडेलिटी सीधे आपस में ट्रेड-ऑफ़ करते हैं: ऑटोमेशन आज 41,285 km² दे देता है, हाथ से बनाना आखिरकार एक शानदार पुराना शहर देता है। मेरा मत है: डेटा प्रोडक्ट के लिए प्रकाशित प्रोवेनेंस वाली स्वचालित जनरेशन जीतती है, और क्यूरेटेड, हाथ से बने लैंडमार्क वहाँ ऊपर परत के रूप में जोड़े जा सकते हैं जहाँ वे मायने रखते हैं।

और प्रोवेनेंस वह हिस्सा है जिसे हर कोई छोड़ देता है। यह प्रोजेक्ट एक ज्ञात-दोष सूची शिप करता है: सीमाओं के पास के वे अंतराल जहाँ केवल 30 m का Copernicus ग्रिड पहुँचता है, धब्बेदार या सपाट हिस्से, गलत या गायब पुल और सड़कें, और QA मीटर-दर-मीटर नहीं बल्कि सैंपलिंग से किया गया। यह सूची असली काम करती है — यह “आपकी दुनिया यहाँ गलत है” वाली बग रिपोर्ट को “हाँ, वह डेटासेट यहीं खत्म होता है” वाले दस्तावेज़ में बदल देती है। हर व्युत्पन्न-डेटा प्रोडक्ट को अपना प्रोवेनेंस मैट्रिक्स और अपनी ज्ञात-गलत सूची प्रकाशित करनी चाहिए। जो नहीं करते वे ज़्यादा सटीक नहीं होते; बस कम ईमानदार होते हैं।

  • सब कुछ टाइल करें। टाइल आपकी स्टोरेज, कैशिंग, जनरेशन और फ़ेल्योर की इकाई है। मोनोलिथ सहजता से नहीं गिरते।
  • इनजेस्ट पर कभी डाउनसैंपल न करें। हर स्रोत का मूल रिज़ॉल्यूशन रखें और रेंडर के समय रीसैंपल करें।
  • आलसी तरीके से जनरेट करें। जब दुनिया किसी के प्लेटाइम से बड़ी हो जाए, तो प्रति-विज़िट कम्प्यूट प्री-बेकिंग को हरा देता है।
  • इनजेस्ट पर LOD पिरामिड बनाएँ। लगभग 33% ओवरहेड का बजट रखें और हर दूरी पर सहज स्केलिंग खरीदें।
  • एक कैनरी स्लाइस शिप करें। आपके सबसे कठिन डेटा का मुफ़्त, प्रतिनिधि टुकड़ा किसी भी स्पेक शीट से बेहतर है।
  • प्रोवेनेंस और ज्ञात दोष प्रकाशित करें। ये प्रोडक्ट का हिस्सा हैं, उसके लिए माफ़ी नहीं।

पूरा देश 15 CHF में बिकता है, जिसमें भविष्य के सभी वर्शन शामिल हैं — और कानूनी कारणों से केवल स्विस निवासियों को, जो एक पूरी तरह डिजिटल सामान के लिए अजीब तौर पर दिलचस्प बाधा है। लेकिन असली प्रोडक्ट मैप नहीं है। असली प्रदर्शन यह है कि सार्वजनिक डेटा, टाइल्ड पाइपलाइन और ईमानदार दस्तावेज़ों के साथ अकेला एक व्यक्ति भी ज़्यादातर टीमों के जियोस्पेशियल इन्फ़्रास्ट्रक्चर से आगे प्रोडक्ट शिप कर सकता है। आपका डेटासेट शायद 41,285 km² का नहीं होगा। आपके बहाने भी छोटे होंगे।