كيفية تحميل خريطة الشارع في خلية؟

في مقال سابق ، درست الترميز الجغرافي العكسي باستخدام Spark. الآن تخيل أننا واجهنا تحدي الترميز الجغرافي المباشر لعناوين البريد. بمعنى ، تلقي العنوان المسجل بواسطة نص بعض الإحداثيات الجغرافية.

العناوين الخاصة بالدقة هي اللغة الروسية ، والأهم من ذلك - أنها غالباً ما تكون مكتوبة بطريقة ملتوية ، أي بالأخطاء والغموض وغيرها من المسرات. وهذه العناوين موجودة في قاعدة بيانات Hive ، على نظام Hadoop.


حسنًا ، يبدو - نحن نأخذ Google Maps Geocoding API (أو ، إذا كنت داعمًا لاستبدال الاستيراد ، فعندئذٍ Yandex Maps API) ، ونحن نعمل. ولكن هنا ، وكذلك مع الترميز الجغرافي العكسي ، ننتظر كمينًا صغيرًا.

أو كبيرة ، انها مثل المشاهدة. الحقيقة هي أننا نحتاج هذه المرة إلى معالجة حوالي 5 ملايين عنوان. وربما 50 - لم يكن واضحا على الفور. كما تعلمون ، ستحظر Google عنوان IP الخاص بك بعد حوالي 10 آلاف عنوان ، لكن Yandex ستفعل الشيء نفسه معك ، على الرغم من أن ذلك ممكن بعد قليل (25 ألف طلب يوميًا ، مثل). وإلى جانب ذلك ، تعد واجهات برمجة التطبيقات (APIs) REST ، مما يعني أنها بطيئة نسبيًا. وحتى إذا اشتريت اشتراكًا مدفوعًا ، فلن تزيد السرعة من ذلك بنس واحد.

وحتى الآن - نفد من حكاية الذخيرة.

لقد نسيت أهم شيء - مجموعة Hadoop الخاصة بنا موجودة على الإنترانت ، وخرائط Google ، للشركة التي لديها خرائط Yandex ، وكل الأشخاص الآخرين ، يتعذر علينا الوصول إليها عمومًا من المجموعة. وهذا هو ، كنا بحاجة إلى حل مستقل.

سأقول على الفور - لن تجد حلاً جاهزًا هنا. سوف أصف فقط النهج الذي نخطط لتطبيقه ، وبتفصيل أكثر قليلاً - إحدى الخطوات على طريق طويل للوصول إلى حل.

بالطبع ، كان لدينا شيء في الاحتياطي. كان هناك خادم ArcGIS داخلي ذكرته بالفعل. لم يُسمح لنا بتوجيههم ، لكن سُمح لنا باستخدام خدمات REST الخاصة به.

أول شيء فعلناه هو المسمار لهذه المهمة. لم يحظرنا ، لكن ببساطة توقف في بعض الأحيان للصيانة. والأمر الجميل - كان يحتوي على مجموعة من الترميز الجغرافي ، عندما ترسل حزمة من العناوين إلى الإدخال (بعد تهيئة الخادم ، كان لدينا حجم حزمة من 1000 قطعة ، افتراضيًا يبدو أن هناك شيئًا ما ذا حجم أو اثنين أصغر). كل هذا لم يكن بالأمر السهل ، ونحن ، ودعم ArcGIS ، شاركنا في مصارعة السومو مع الخادم لفترة طويلة ، لكن هذه قصة أخرى.

بعد كل الحيل واللف والمنعطفات ، تمكنا من معالجة خمسة ملايين في حوالي يوم واحد. كان من الضروري المضي قدمًا ومحاولة الإسراع بعد.

في الوقت نفسه ، أصبح من الواضح أن أي رمز جغرافي مزود بـ REST غير مناسب لنا على الأرجح. بالإضافة إلى ذلك ، نظرنا إلى نوميناتيم ، وبيلياس ، وفوتون ، وفي جغرافيا ، وبشكل عام لم نكن راضين عن أي منها. كانت الجودة والأداء (أو كلاهما) بعيدًا عن المثالية.

على سبيل المثال ، لا أحد يعرف كيفية الترميز الجغرافي (وهذا العمل المتسارع للغاية مع ArcGIS).

أو الجودة - انتقل إلى خادم gisgraphy.com التجريبي وحاول العثور على موسكو. ستحصل على بضع إجابات ، بما في ذلك: موسكو (مدينة في الاتحاد الروسي) ، ومدينة كانساس سيتي (مدينة في الولايات المتحدة الأمريكية) ، وخيمكي ، وكالوغا ، وفيخينو-زوليبينو ، والعديد من الأشياء الأخرى التي لا أريد رؤيتها في إجابة الترميز الجغرافي عندما البحث عن موسكو.

حسنًا ، المشكلة الأخيرة (ولكن ليست مهمة بالنسبة لنا) هي أن واجهة برمجة التطبيقات (API) بعيدة كل البعد عن جميع الرموز الجغرافية ، مثل خرائط Google مثلاً. دعنا نقول أن ArcGIS API غير مريح بالفعل ، والباقي هو في معظمه أسوأ. إذا قمت بإجراء الترميز الجغرافي لعناوين واجهة المستخدم ، فعندئذٍ ، كقاعدة عامة ، يشارك الشخص في اختيار الخيار الأفضل. ويفعل ذلك أفضل من البرنامج. وفي حالة الترميز الجغرافي الشامل ، كما فعلنا ، فإن تقييم جودة النتيجة لعنوان معين هو أحد مكونات النجاح المهمة.

نتيجة لذلك ، اختفت أيضًا خيارات مثل "توسيع Nominatim الخاص بك" ، على سبيل المثال.

ماذا تفعل؟


كان الحل واضحًا إلى حد ما: نظرًا لأن العناوين لا تؤخذ من أي مكان ولا تختفي ، لا يتم بناء المنازل يوميًا ، ولا يتم بناء الشوارع ، فما عليك سوى إضافة قاعدة بيانات للعناوين الموجودة رسميًا إلى عمليتنا. أفضل على الفور مع الإحداثيات ، وإذا لم يحدث هذا ، ثم الترميز الجغرافي مرة واحدة. في هذه الحالة ، سيكون كافياً بالنسبة لنا لتحديث قاعدتنا بنفس التردد الذي تظهر به المنازل أو الشوارع الجديدة ، أي في كثير من الأحيان.

المرشح الأول والرئيسي لقاعدة العناوين الحالية هو FIAS . انت تقول دقيقة ، لكن FIAS لديه بضعة ملايين من العناوين - ولديك ما يصل إلى 50 مليون عنوان؟ نعم ، يوجد بالفعل بضعة ملايين من المنازل . 50 لدينا هو 50 مليون عنوان لمستخدمينا ، أي هذه هي عناوين الأشخاص ، ولديهم فجأة شقة في العنوان. خمسة ملايين منزل من 1-100 شقة ، يعيش العديد من الأشخاص في كل شقة ... حسنًا ، أنت تفهم كل شيء. والخيار الثاني هو عناوين المكاتب ، حيث يوجد أيضًا مركز مكاتب واحد يضم مئات المباني التي يتم تأجيرها في بعض الأحيان.

في الوقت نفسه ، من الواضح أننا لسنا بحاجة إلى عنوان برقم الشقة (أو المكتب) - أولاً ، هذه بيانات شخصية لها جميع العواقب ، وثانياً ، ما زلنا غير مهتمين بكيفية وجود الشقق في منزل معين ، وما هي إحداثياتها . هناك حاجة فقط منزل. بالنسبة للمكاتب ، هذا ليس صحيحًا تمامًا ، ولكن موقع المكاتب في مبنى حسب الطوابق لا يزال غير محدد بالإحداثيات.

في نهاية المطاف ، بوجود قاعدة ، على سبيل المثال ، 5 ملايين منزل (مشروط) ، يمكننا حل مشكلة الترميز الجغرافي المتمثلة في 50 أو 100 مليون عنوان بمجرد التخلص من الشقة أو المكتب خارج العنوان ومطابقتها مع القاعدة.

وأين يمكن الحصول على إحداثيات المنازل؟ لا يوجد سوى مصدر مفتوح واضح واحد - خريطة الشارع المفتوح ، وهناك منازل هناك ، بها أشكال هندسية ، والعديد من السمات الأخرى مثل عدد الطوابق أو حتى لون السطح.

بعد كل المناقشات ، كان لدينا خطة نابليون. هنا واحد:

  • تحميل بيانات الخريطة من OSM إلى Hadoop
  • تحميل بيانات FIAS مع العناوين
  • بناء قائمة من عناوين كاملة فريدة من نوعها مع أرقام المنازل
  • نحن نقوم بترميزه الجغرافي من خلال البحث عن عناوين في OSM ، وما لم نعثر عليه هو من خلال ArcGIS


نحصل على قاعدة المنازل مع خطوط الطول والعرض. استمتع جني الفوائد. شرب المكافآت (نكتة).

في هذه المقالة ، سوف أخبرك كيف طبقنا النقطة الأولى من هذه الخطة.

ما هو خريطة الشارع المفتوح


إذا نظرت إلى OSM من وجهة نظر البيانات ، فيمكنك تخيل البطاقات في شكل ثلاثة جداول:

  • نقاط
  • خطوط (طرق)
  • العلاقات


سيتم إعطاء مخططات حقيقية لهذه البيانات أدناه.

تحتوي النقاط فقط على إحداثيات (خطوط الطول والعرض ، بالدرجات). الخطوط هي تسلسل مرتبة من النقاط. العلاقات هي مجموعة من النقاط والخطوط ، لكل منها دور .

كل شيء آخر هو ما يسمى العلامات. هذا ، على سبيل المثال ، جهاز صراف آلي ، أو متجر ، أو مدخل إلى المترو - يمكن أن يكون نقطة مجهزة بوسم الراحة = atm ، أو متجر = يبيع شيئًا ، أو أي شيء آخر. يوجد دليل للعلامات الموصى بها رسميًا (لكل لغة وبلد معمول بهما ، يمكن أن تكون جزئية خاصة بهم) ، وممارسة اختراع العلامات غير القياسية.

بالإضافة إلى العلامات ، يحتوي كل عنصر من عناصر الخريطة على معرف رقمي فريد ، بالإضافة إلى بعض السمات المتعلقة بالسجل - الذي قام بتحرير الوقت وتعديل الرقم وما إلى ذلك.

قاعدة البيانات مع البطاقة تأتي في عدة أشكال:
- pbf هو Google Protobuf ، وهو تنسيق تسلسل بيانات محمول.
- XML ​​بوضوح XML. الكثير في الحجم.

تحتاج إلى فهم أن يتم تحديث قاعدة البيانات يوميا. لذلك ، عمليات التفريغ كاملة وتدريجية.

اخترنا PBF كما أكثر إحكاما.

لقراءتها في Hadoop ، هناك واجهة برمجة تطبيقات Java مصممة خصيصًا لنظام التشغيل OSM تسمى مشروع التناضح. من حيث المبدأ ، يكون العمل معها بسيطًا - يمكنك تحميل ملف وتصفح دورة عناصر الخريطة. أضف النقاط في مكان واحد ، والخطوط في مكان آخر ، والعلاقة في المركز الثالث. من حيث المبدأ ، فإن التناضح ، وعلى سبيل المثال Spark ، يكفي بالفعل لتنزيل جميع البيانات.

لحسن الحظ ، في عملية تطبيق دراجتي ، حدث لي بطريقة أو بأخرى البحث في الإنترنت لتحويل OSM إلى التنسيقات المقبولة في Hadoop - Parquet (الباركيه) و Avro. بمعنى ما ، كلاهما نظائر PBF ، لذلك كانت هناك فرصة للعثور على محول. ووجد ، ولكن ليس واحد.

تلبية OSM الباركيه


انظر ماذا وجدت!

بالنسبة للأشخاص الكسولين - مباشرة في الملف التمهيدي للمشروع في السطر الأول ، يقول: تنشر Telenav التنزيلات الأسبوعية للكوكب على العنوان .

للناس كسول للغاية: الاستعداد لشحن حوالي 700 غيغابايت ؛) حسنًا ، إذا كنت تحتاج بالتأكيد إلى كوكب. يمكنك عادة الحصول على مثل أوروبا.

إذا كنت لا تريد التحميل ، فستبدو العملية كما يلي: قم بتنزيل خريطة بتنسيق PBF ، على سبيل المثال من geofactory . هذا هو 2.5 غيغا بايت إذا كنت بحاجة إلى روسيا ، و 19 غيغا أوروبا. أيضا ليس قليلا ، ولكن يمكنك العثور على عينات أكثر دقة المفروم. بعد ذلك ، ضع الملف على القرص ، وقم بتشغيل البرنامج:

java -jar ./osm-parquetizer.jar russia-latest.osm.pbf 

بعد بضع دقائق أو حتى ثوانٍ ، اعتمادًا على أداء جهازك ، تحصل على ثلاثة ملفات بتنسيق باركيه. إليكم ما يبدو عليه المؤلف (من رومانيا):

 -rw-r--r-- 1 adrianbona adrianbona 145M Apr 3 19:57 romania-latest.osm.pbf -rw-r--r-- 1 adrianbona adrianbona 372M Apr 3 19:58 romania-latest.osm.pbf.node.parquet -rw-r--r-- 1 adrianbona adrianbona 1.1M Apr 3 19:58 romania-latest.osm.pbf.relation.parquet -rw-r--r-- 1 adrianbona adrianbona 123M Apr 3 19:58 romania-latest.osm.pbf.way.parquet 

مخططات ملفات الباركيه المستلمة:

node
|-- id: long
|-- version: integer
|-- timestamp: long
|-- changeset: long
|-- uid: integer
|-- user_sid: string
|-- tags: array
| |-- element: struct
| | |-- key: string
| | |-- value: string
|-- latitude: double
|-- longitude: double

way
|-- id: long
|-- version: integer
|-- timestamp: long
|-- changeset: long
|-- uid: integer
|-- user_sid: string
|-- tags: array
| |-- element: struct
| | |-- key: string
| | |-- value: string
|-- nodes: array
| |-- element: struct
| | |-- index: integer
| | |-- nodeId: long

relation
|-- id: long
|-- version: integer
|-- timestamp: long
|-- changeset: long
|-- uid: integer
|-- user_sid: string
|-- tags: array
| |-- element: struct
| | |-- key: string
| | |-- value: string
|-- members: array
| |-- element: struct
| | |-- id: long
| | |-- role: string
| | |-- type: string


كما ترون ، كل شيء بسيط هنا. ثم نقوم بما يلي:

  • نضع الملفات على نظام Hadoop باستخدام الأمر hdfs dfs -put
  • دعنا نقول في هوى وإنشاء مخطط / قاعدة ، وثلاثة جداول لذلك ، استنادا إلى البيانات المذكورة أعلاه
  • قم بتنفيذ select * من osm.nodes ، واستمتع بالنتيجة.

فارق بسيط: في إصدارنا من Hive (وربما نسختك أيضًا) ، لا يمكنه إنشاء جداول بناءً على المخطط من Parquet. يلزمك إما تحويل ما سبق إلى CREATE TABLE (وهو أمر غير صعب بوجه عام ، وسأترك هذا كتمرين منزلي للقراء) ، أو لأفعل بعض الصعوبات: يمكن لـ Spark قراءة المخطط والبيانات من الأرضية ، وإنشاء جداول مؤقتة بناءً عليها. . حتى نتمكن من قراءة البيانات في Spark Shell مثل هذا:

 val nodeDF = sqlContext.read.parquet("file:/tmp/osm/romania-latest.osm.pbf.node.parquet") nodeDF.createOrReplaceTempView("nodes") 

ثم يمكنك بالفعل إنشاء جداول في الخلية باستخدام عقد LIKE.

ملاحظة أخرى للأشخاص الكسولين: لدى المؤلف مثال رائع ، حيث يصبح كل شيء واضحًا بشكل عام (حسنًا ، إذا كنت تمتلك Spark). هذا بالطبع ليس Spark Shell ، لكنه دفتر Databricks ، لكنني استغرقت حوالي 15 دقيقة للاستفادة من لوحة مفاتيح واحدة لترجمة واحدة إلى أخرى. وفي 30-40 دقيقة ، كان من الممكن تحويلها كلها إلى استفسارات لـ Hive باستخدام بعض نظائرها التي تختلف اختلافًا طفيفًا عن الشرارة.

مثال طلب حقيقي


ما الذي يمكن أن نحصل عليه من قاعدة البيانات هذه في شكلها الحالي؟ بشكل عام ، الكثير جدا. إذا كان لديك Hive أو Spark أو Spatial Framework أو Geometry API أو أحد البدائل ، وهي GeoSpark أو GeoMesa ، على سبيل المثال ، يمكنك حل العديد من المشكلات المختلفة على هذا الأساس.

دعنا نرى مثالا. أسهل طريقة للعمل مع النقاط. على سبيل المثال ، يبدو الاستعلام للحصول على قائمة بأجهزة الصراف الآلي بإحداثياتها كما يلي:

 select * from nodes where tags['amenity']='atm' 

كيفية بناء مثل هذا الاستعلام ، يمكنك تخمين من خلال قراءة الصفحة على الويكي . ستجد هناك العلامات الأخرى ، ويمكن إدراج بعضها في طلبك بدلاً من * ، في شكل علامات ['عامل التشغيل'] ، على سبيل المثال ، لإظهار اسم البنك.

من نفس الصفحة ، يتضح أن ترميز أجهزة الصراف الآلي ممكن في شكل علامات تسامح = bank و atm = yes. للأسف ، هذه الغموض موجودة في كل مكان في OSM.

إذا كنت مبتدئًا ، وتعرف فقط على OSM ، فإنني أوصي بشدة بإتقان (بأمثلة جيدة على الويكي) overpass-turbo . هذه هي الأداة التي تسمح لك بإجراء أنواع مختلفة من عمليات البحث على بيانات الخريطة ، سواء مع الظروف الهندسية أو مع شروط العلامات.

وأين هي العناوين؟


سؤال جيد العناوين في OSM هي عناصر خرائط مقدمة مع addr: * tags ، أي بدءا من addr. الوصف سوف تجد هنا . من حيث المبدأ ، معرفة كل ما ذكرته أعلاه ، يمكنك بالفعل كتابة بعض طلبات العمل:

 select * from nodes where tags['addr:housenumber']!=null 

ما هي المشاكل التي تنتظرنا هنا؟ أولاً ، يتم وضع العناوين في نقاط (على سبيل المثال ، بناء المداخل) ، وعلى المضلعات ، على سبيل المثال على الطرق. لذلك يتعين علينا تكرار الطلب على الأقل. وثانياً ، على الصفحة المذكورة أعلاه ، تمت كتابة الويكي بنص عادي أنه لا يوصى بوضع علامات تشير إلى المدينة والمنطقة والمنطقة والبلد ، ولكن يجب حساب ذلك هندسيًا. كيف نفعل ذلك؟ بشكل عام ، هذه هي مهمة الترميز الجغرافي العكسي ، مع تعديلات الضوء ، وقد تم وصفها في منشور سابق.

هذا ، بشكل عام ، تحتاج إلى العثور على حدود إدارية ، ولجميع العناوين الموجودة بداخلها ، أضف العنوان إلى المنطقة وكل شيء أعلاه. كيف يتم وصف حدود الكيانات الإدارية هنا .

بشكل عام ، هذه المهمة ليست بسيطة للغاية ، ولكنها قابلة للحل ، ولا يتم حلها عن طريق الترميز الجغرافي ، ولكن عن طريق تنزيل تحديثات OSM لقاعدة البيانات الخاصة بنا ، في جو مريح.

ما هو مفيد القيام به بعد ذلك


من حيث المبدأ ، يمكنك بالفعل العمل مع العقد والطرق وجداول العلاقات التي لدينا ، ولكن من الأفضل تغيير المخطط قليلاً ، مما يجعله أكثر ملاءمة لـ Hive و Spark. الحقيقة هي أن نظام OSM تم تطبيعه بالكامل ، والطرق والعلاقات لا تحتوي على إحداثيات على الإطلاق. لإنشاء مضلع للطريقة ، تحتاج إلى الانضمام إلى العقد. أوصي بإجراء هذه العملية على الفور ، مع توفير المضلعات إما كصفيف من الهياكل (يمكن لخلية الخلية العمل مع صفيف الأنواع المركبة والخريطة والهيكل) ، أو فورًا كتمثيل متسلسل لفئة الهندسة ، على سبيل المثال. كيفية القيام بذلك في مثال الباركيه المؤلف.

يمكنك تكرار عملية مماثلة على مستوى العلاقات ، إذا كنت تريد ذلك ، ولكن بالكاد يستحق كل هذا العناء. أولاً ، لن تحتاج دائمًا إلى جميع عناصر العلاقة ، وثانيًا ، العلاقات نفسها في OSM أصغر كثيرًا.

تحويل إلى Avro


هنا محول آخر ، هذه المرة إلى تنسيق Avro. وهنا هو موضح أين يمكن الحصول على الملفات النهائية. لم أقم بقياس الأحجام ، لكنني أعتقد أن حوالي 15-20 ملفًا لكل كوكب يجب أن تكون قابلة للمقارنة مع PBF. وهذا هو ، غيغابايت ، والكثير.

بعض الاستنتاجات


وأين الترميز الجغرافي ، تسأل؟ نعم ، يعد تنزيل الخرائط واستخراج العناوين جزءًا فقط من المهمة الكلية. آمل أن يأتي الأمر إلى هذا.

Source: https://habr.com/ru/post/ar438374/


All Articles