تحويل دولة كاملة إلى فوكسلات: خط أنابيب للبيانات الجغرافية
كيف حوّل خط أنابيب فوكسل بيانات سويسرا الجغرافية المفتوحة إلى عالم Minecraft بمقياس 1:1، مع دروس في البلاطات ومستويات التفاصيل وبث البيانات المكانية.

في مكان ما داخل بوابة البيانات المفتوحة للحكومة السويسرية توجد خريطة ارتفاعات لواجهة الشمال للإيغر، بدقة عالية تكفي لتشعر بصلابة الصخر. أخذ مطور ملفات كهذه وغذّى بها خط أنابيب فوكسل، وأطلق النتيجة كمنتج قابل للعب: سويسرا كاملة كعالم Minecraft بمقياس 1:1، حيث يمثل كل مكعب متراً واحداً، ويقف جبل ماترهورن بالارتفاع والانحدار نفسيهما للأصل. حجم التحميل 24 غيغابايت مضغوطة، والمنطقة التجريبية المجانية وحدها تغطي نحو 2400 كم². أما الهندسة الكامنة خلفه، من التقسيم إلى بلاطات ومستويات التفاصيل والتوليد الكسول، فدرس متقن في نقل مجموعات بيانات مكانية ضخمة دون أن يحترق كل شيء.
المشكلة: دولة من الفوكسلات لن تتسع في الذاكرة
دعني أحسب معك. تبلغ مساحة سويسرا 41,285 كم². بمكعب واحد لكل متر مربع، هذا يعني 41.3 مليار عمود سطحي قبل أن تحفر حفرة واحدة. امنح كل عمود عمقاً متواضعاً قدره 100 مكعب، من حجر وتربة وقاع بحيرة، فتصل إلى أربعة تريليونات مكعب. حتى بمعدل بايت واحد لكل مكعب، فهذا أربعة تيرابايت من الهندسة الخام. ومع ذلك يُضغط العالم المنشور إلى تحميل بحجم 24 غيغابايت، وهذا يخبرك بشيء مهم: لا يُخزَّن معظم تلك الهندسة كهندسة أصلاً، بل كوصفة.
والبعد الرأسي يكسر الأمور أيضاً. يحدّ Minecraft الأصلي ارتفاع البناء بـ384 مكعباً فقط. تمتد سويسرا من 193 م فوق مستوى البحر عند بحيرة ماجوري إلى 4,634 م عند قمة دوفورشبيتسه، أي فرق قدره 4,441 م، وهو أكثر من أحد عشر ضعف الحد الأصلي قبل أن يحفر أحد منجماً. لذلك يحتاج العالم إلى Cubic Chunks، وهو مود يستبدل تخزين Minecraft القائم على الأعمدة بمكعبات 16×16×16 مكدسة بالارتفاع المطلوب. ولا يعمل هذا المود بثبات إلا على نسخة Minecraft Java 1.12.2، ولهذا يثبّت مشروع يُطلق اليوم إصدار لعبة يعود إلى سنوات مضت.
الجدار الثالث هو الذاكرة. بناء المكعبات من البيانات المصدرية في أول زيارة للاعب إلى منطقة يستهلك حساباً كثيفاً: يطلب المشروع 16 غيغابايت من الذاكرة كحد أدنى، ويُختبر على أجهزة مثل Ryzen 7 7800X3D مع 32 غيغابايت. كل من خاض معارك ميزانية البث في الألعاب أو نظم المعلومات الجغرافية سيتعرف على هذا الشكل. إنه نفس الفرز الذي تقوم به عندما تنفد ذاكرة الفيديو في كرت الشاشة: لا يمكنك حمل كل شيء، فتصبح بارعاً في تحديد ما تحمله الآن.
المحاولة الأولى الفاشلة: بناء العالم كله مسبقاً
النهج البديهي هو مهمة دفعية واحدة بلا اتصال: قراءة البيانات الجغرافية، وإخراج ملفات مناطق Minecraft، إذ يخزن تنسيق Anvil العالم في مناطق 512×512 مكعباً، ثم ضغط الناتج وإرساله. قامت الدنمارك بشيء شبيه بهذا عام 2014، حين أصدرت وكالة البيانات الجيودية الدنماركية البلد بأكمله كخريطة Minecraft. كان عرضاً تاريخياً للبيانات المفتوحة، وأثبت أن خريطة بحجم دولة ممكنة. فلماذا لا نفعل ذلك؟
لأن البناء المسبق يحمل تكاليف هيكلية تتضخم مع الطموح. يجب توليد كل مكعب في كل منطقة وكتابته وضغطه قبل أن يلعب أحد، فيتحول كل تحديث للبيانات إلى إعادة بناء كاملة وإعادة إرسال لعشرات الغيغابايتات. ويحمّل كل لاعب جبالاً من التضاريس لن يزورها أبداً، ومعظم الـ41,000 كم² لن يزورها أحد على الإطلاق. والأسوأ أن العالم المبني مسبقاً يتجمد عند لقطة بياناته لحظة نشره. إنه عمل يُكتب مرة واحدة، ولا يتحسن إلا إذا أُعيد توليده وأُعيد توزيعه بالكامل، ويضطر مستخدموك إلى إعادة تحميل الكوكب كله.
المحاولة الثانية الفاشلة: ارتفاع واحد بدقة واحدة
الإغراء الثاني هو التوحيد: تحويل كل مدخل إلى رastر عالمي واحد بدقة واحدة، فيكون لخط الأنابيب مسار تنفيذ واحد فقط. داخل سويسرا لديك swissALTI3D، وهو نموذج تضاريس عالي الدقة. وخارج الحدود لديك Copernicus GLO-30 DEM، أي نقطة ارتفاع كل 30 متراً. إذا خفّضت كل شيء إلى 30 م من أجل التوحيد، تتحول واجهة الشمال للإيغر إلى كومة رمال مدرجة. وإذا رفعت كل شيء إلى أدق دقة متاحة، ينفجر التخزين والمعالجة، ومع ذلك تظل مناطق الحدود بلا بيانات حقيقية، فقد أعدت أخذ عينات من جهلك فحسب.
يضرب عدم التجانس الدلالات بقوة توازي قوته في الارتفاعات. تغطي 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، ومخططات الأنهار الجليدية من جرد GLAMOS الممتد إلى عام 1850، وسماكة الجليد من مجموعة بيانات لجامعة ETH زيورخ، لذا فإن نهر ألييتش الجليدي منحوت من جليد حقيقي لا مجرد نسيج أبيض مُسدل على الصخر. تأتي المروج والمنحدرات الصخرية والكروم من خريطة الموائل الفيدرالية، حتى أشجار شوارع زيورخ تأتي من السجل الشجري للمدينة نفسها. نحو خمسة عشر مجموعة بيانات مفتوحة في المجموع، كلها مجانية الاستخدام، فقد فتحت swisstopo بياناتها عام 2021، بما فيها الاستخدام التجاري.
عالم الفوكسل ليس صورة للتضاريس. إنه ذاكرة تخزين مؤقت لملايين القرارات الصغيرة التي اتخذها خط أنابيبك، قرار لكل متر مربع، وجودة العالم هي بالضبط جودة تلك القرارات.
مستوى التفاصيل مشكلة بيانات، لا حيلة عرض
مسافة العرض الافتراضية في Minecraft تُظهر بضع مئات من الأمتار. تُظهر لقطات المشروع نهر ألييتش الجليدي ينحني بعيداً لكيلومترات. هذا المنظر البعيد («فيرنزيخت») تمثيل منفصل ومخفَّض الدقة يبنيه اللعب مرة واحدة عند أول تشغيل. هذا مستوى تفاصيل كلاسيكي، لكن القرار المهم هو أين يعيش مستوى التفاصيل: يُحسب من البيانات المصدرية وقت الاستيعاب، ولا يُرقَّع من قِبَل المُصيِّر أثناء التشغيل.
إذا بنيت هرميات بلاطات الخرائط فأنت تعرف الحساب. كل مستوى تكبير يقسم الدقة على اثنين في كلا المحورين، لذا يكلف الهرم الكامل 1 + 1/4 + 1/16 + … ≈ 4/3 من الطبقة الأساسية، أي عبء تخزين بنسبة 33% مقابل سلوك سلس عند كل مقياس. تضاريس الفوكسل مع مستويات التفاصيل هي الهرم نفسه منتصباً: التضاريس البعيدة هي مستوى التكبير الخشن، والقريبة هي الدقيقة، والفن الحقيقي يكمن في اختيار مخطط مفاتيح يتيح جلب الخلية الصحيحة بسرعة. واجهنا الأسئلة نفسها في المفاضلات بين geohash والفهارس المكانية الحقيقية، فاختيار المفتاح يحدد كلفة البحث في كل ما يليه.
قراري المفضل هنا ليس بصرياً أبداً. التحميل المجاني شريحة من 2,400 كم²، وهي منطقة يونيسكو ياونفراو-ألييتش: الإيغر والمونش ويونغفراو وأكبر نهر جليدي في جبال الألب. وهي تعمل بخط الأنابيب نفسه الذي يعمل به العالم المدفوع كاملاً. هذا إصدار تجريبي كميزة في المنتج. حجمه 1.1 غيغابايت بدلاً من 24، ولا يتطلب تسجيلاً، وإذا عمل على جهازك فستعمل الخريطة الكاملة أيضاً. إذا كنت تطلق منتجات بيانات ضخمة، فانسخ هذا فوراً: يجب أن تكون طبقتك المجانية شريحة تمثل أصعب تضاريسك، لا عرضاً مبتوراً لأسهل ما لديك.

بث البلاطات المكانية داخل المتصفح
يظهر الانضباط نفسه في صفحة الويب المتواضعة للمشروع. تتيح خريطته العامة سحب شريط منزلق لمقارنة عالم الفوكسل بالصورة الجوية الحقيقية، والصورة لا تأتي من خوادم المشروع أصلاً. يجلب المتصفح بلاطات SWISSIMAGE مباشرة من خدمة swisstopo نفسها، ولا يفعل ذلك إلا بعد تحريك الشريط. كسول، ومباشر من المصدر، وصديق للتخزين المؤقت: يُقدَّم عرض النطاق الثقيل عبر بنية تحتية عامة وُجدت لهذا الغرض تحديداً، وتبقى فاتورة استضافة المشروع قريبة من الصفر.
عنونة البلاطات على الويب مسألة محلولة، ويستحق معرفتها جيداً إن لمست يوماً العمل الجغرافي المكاني:
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 كم² اليوم، والبناء اليدوي يمنحك بلدة قديمة رائعة في النهاية. موقفي: في منتج بيانات، يفوز التوليد الآلي مع مصدر منشور، ويمكن أن تُراكم المعالم اليدوية المنتقاة فوقه حيث تهم.
وأما المصدر فهو الجزء الذي يتجاوزه الجميع. يشحن هذا المشروع قائمة بالعيوب المعروفة: فجوات قرب الحدود حيث تصل شبكة Copernicus بدقة 30 م وحدها، ومناطق متفاوتة أو مسطحة، وجسور وطرق خاطئة أو مفقودة، وضمان جودة يُجرى بأخذ عينات لا متراً بمتر. تقوم هذه القائمة بعمل حقيقي، فهي تحوّل تقارير «العالم خاطئ هنا» إلى توثيق من نوع «نعم، تنتهي مجموعة البيانات عند هذا الحد». يجب على كل منتج بيانات مشتقة أن ينشر مصفوفة مصدره وقائمة أخطائه المعروفة. المنتجات التي لا تفعل ذلك ليست أدق، بل أقل صدقاً فحسب.
- قسّم كل شيء إلى بلاطات. البلاطة هي وحدتك للتخزين والتخزين المؤقت والتوليد والفشل. الكتل الضخمة لا تتدهور بسلاسة.
- لا تخفّض الدقة عند الاستيعاب أبداً. احفظ الدقة الأصلية لكل مصدر، وأعد أخذ العينات وقت التصيير.
- وَلِّد عند الحاجة. حين يصبح العالم أكبر من وقت لعب أي شخص، يتفوق الحساب لكل زيارة على البناء المسبق.
- ابنِ هرم مستويات التفاصيل عند الاستيعاب. خصص حوالي 33% كعبء إضافي، واشترِ توسعاً سلساً عند كل مسافة.
- أطلق شريحة تجريبية. جزء مجاني ممثل من أصعب بياناتك أفضل من أي ورقة مواصفات.
- انشر المصدر والعيوب المعروفة. هي جزء من المنتج، وليست اعتذاراً عنه.
تُباع الدولة كاملة بـ15 فرنكاً سويسرياً مع كل الإصدارات المستقبلية، ولمقيمين سويسريين فقط، لأسباب قانونية، وهو قيد لطيف بشكل غريب لسلعة رقمية بحتة. لكن المنتج الحقيقي ليس الخريطة، بل البرهان على أن شخصاً واحداً، ببيانات عامة وخط أنابيب مقسّم إلى بلاطات ووثائق صادقة، يستطيع أن يطلق أكثر مما تطلقه بنية جيومكانية لدى معظم الفرق. بياناتك على الأرجح ليست 41,285 كم². وأعذارك أصغر أيضاً.
