Skip to main content

خرائط OsmAnd الثنائية - .obf

مقدمة

تحدث عن *.travel.obf, *.wiki.obf, *.roads.obf, ..

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

توجد بيانات خرائط OsmAnd غير المتصلة بالإنترنت في ملفات "obf". تتميز ملفات "obf" بهيكل معقد ويمكن أن تتكون من أجزاء عديدة. يوصى بشدة بالحفاظ على أحجام الملفات أقل من 2 جيجابايت. حاليًا، يمكن أن تحتوي ملفات obf على أجزاء عديدة تتكون من أجزاء متعددة من نقاط الاهتمام (POI)، وأجزاء متعددة من بيانات التوجيه، وأجزاء متعددة من الخرائط، وأجزاء متعددة من النقل، وأجزاء متعددة من بيانات العناوين. يمكن تمديد هذه القائمة في المستقبل. لدمج أو تقسيم أو حذف بعض الأجزاء من ملف obf، استخدم أداة وحدة التحكم "binary_inspector" المتوفرة مع OsmAndMapCreator.

  • نقاط الاهتمام (POI)، جزء النقل
  • جزء الخريطة
  • جزء العنوان

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

ج: يتم أخذ جميع الأماكن المرئية في OsmAnd كمدن من العقد التي تحتوي على العلامة "place" https://wiki.openstreetmap.org/wiki/Place. حاليًا، يتم استخدام city، town، suburb، village، hamlet.

س: كيف يتعامل منشئ الخرائط مع مضلع منطقة يتم توفيره عبر علاقة ذات boundary=administrative؟ كيف تربط مكانًا معطى كعقدة بحدوده عندما يكون موجودًا في بيانات OSM؟

ج: ببساطة: يعمل حاليًا بالاسم. يحاول منشئ الخرائط زيارة جميع الحدود وإنشاء حدود مغلقة (!) من العلاقة أو من الطرق المنفصلة ويربطها باسم واحد فقط. بعد ذلك، يحاول مطابقة *place* مع *boundary name* باستخدام خوارزمية *contains of*. يوجد أيضًا فحص إضافي إذا كانت تلك الحدود تحتوي على المكان. إذا كانت هناك العديد من الحدود بمستويات إدارية مختلفة بنفس الاسم (تحتوي على بعضها البعض مثل district/town/region لها نفس الاسم)، فسيتم اختيار أعلى مستوى إداري مع مطابقة دقيقة. TODO يجب أن تكون هناك تفاصيل أكثر هنا (حول أحياء المدينة ...) ...

س: أين توجد الوثائق التي تصف مستوى الإدارة الصحيح لبناء ارتباط بعقدة مكان معينة؟ ما هي الدول التي تفضل أي مستوى إداري؟

ج: حاليًا، لا يتم استخدام الارتباط بين علاقة admin_level و admin_centre. لأن عددًا قليلاً فقط من العلاقات توفر هذه المعلومات.

س: كيف يعرف MapCreator أي شارع ينتمي إلى أي مكان؟ هل هناك حالات مختلفة عندما يتم إعطاء مضلع حدودي وعندما لا يوجد؟

ج: هناك العديد من الاستراتيجيات للتحقق ويتم ترتيبها حسب الأولوية بالترتيب التالي:

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

الجزء الأخير غير دقيق للغاية. ولهذا السبب يتم إرفاق العديد من الشوارع بمدينة مجاورة.

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

الأدوات

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

جزء العنوان - سير العمل

توجد هذه العلاقات:

مدينة -> 0..1 حدود

حدود -> 0..** مدينة (تستخدم لتعريف ضاحية المدينة)

كرر جميع عقد OSM وسجلها كمدن إذا كانت العلامة = PLACE موجودة:

  • استخراج المدن (بلدة، مدينة).
  • استخراج القرى (أي شيء آخر).

كرر جميع العلاقات والطرق ذات النوع = حدود وسجل جميع الحدود:

  • تسمى الحدود كيانًا (طريق أو علاقة) بعلامة 'boundary=administrative' أو بعلامة 'place=...'.
  • يجب أن تكون الحدود admin_level > 4 أو لا تحتوي على admin_level.
  • لا ترتبط الحدود دائمًا بمدينة (أو ولاية، ...).
  • يمكن أن تحتوي الحدود على 'admin_center'، 'label' عضو يشير إلى عقدة مدينة.
  • تتطابق الحدود تمامًا بالاسم مع عقدة المدينة وتقع عقدة المدينة ضمن الحدود.
  • تتطابق الحدود بداية أو نهاية أو جزء من سلسلة بالاسم مع عقدة المدينة وتقع عقدة المدينة ضمن الحدود.

يمكن ربط العديد من الحدود بمدينة واحدة. فيما يلي الترتيب الذي يتم به أخذ الحدود الأكثر أهمية وربطها بالمدينة:

  • يتم مطابقة الحدود بالاسم بالضبط وتحتوي على علامة المكان.
  • يتم مطابقة الحدود بالاسم بالضبط وتحتوي على admin_level 8 > 7 > 6 > 9 > 10 > 5... أو لا شيء.
  • تتطابق الحدود مع admin_id.
  • جميع الحالات الأخرى بما في ذلك ترتيب admin_level.

إذا لم يكن للمدينة أي حدود معينة، فسيتم فحص جميع الحدود التي لا تحتوي على مراكز مدن وتحتوي على تلك المدينة، وسيتم تعيين الحدود ذات admin_level >=7.

لكل حدود، قم بإنشاء قائمة بالمدن الموجودة بداخلها.

كرر جميع العلاقات وابحث عن العناوين (Postal_Addresses):

علاقة ذات نوع علامة "address"، وهي "house" أو "a6" نوع العنوان.

ابحث عن علاقة الشارع المرتبطة وأعضاء المنزل.

حاول العثور على المدينة للشارع والمدينة لعنوان المنزل.

ابحث عن المدن (يجب أن نكون قد وجدناها بالفعل في الخطوات السابقة!).

إذا كان لدينا مدينة وشارع، سجلها في قاعدة البيانات:

لتسجيل الشارع، انظر: تسجيل شارع لمدينة

إذا كان الشارع مسجلاً، ونحن نقوم بمعالجة الشارع:

كرر جميع أعضاء العلاقة:

  • ابحث عن الشارع -> اكتب عقد الشارع إلى قاعدة البيانات
  • ابحث عن المنزل -> اكتب المنزل إلى الشارع

إذا كان الشارع مسجلاً، ونحن نقوم بمعالجة المنزل:

  • ابحث عن رقم المنزل
  • ابحث عن حدود المنزل: إذا وجدت، قم بالتخزين: مبنى للشارع

تسجيل الشارع (الشارع، موقع الشارع (los)، المدن):

ملاحظة: قد نسجل شارعًا لعدة مدن = هذا يعني أن الشارع يمكن أن يكون في مناطق متداخلة، ضاحية، مدينة، قرية صغيرة، إلخ... لكل منطقة، نريد تسجيل الشارع الذي يقع فيه.

لكل مدينة:

ابحث عن تسجيل شارع موجود داخل المدينة:

إذا كان الشارع موجودًا:

  • إذا كان جزء المدينة غير معروف -> قم بتحديث جزء المدينة للشارع الموجود
  • حاول العثور على جزء المدينة لشارعنا، وابحث عن الشارع مرة أخرى

إذا لم يكن الشارع موجودًا: (قد يتغير بعد البحث)

  • سجل الشارع للمدينة، جزء المدينة، الموقع، واسم الشارع

ابحث عن أو سجل الشارع

  • ابحث عن المدن القريبة من الشارع
  • إذا كان الشارع في حدود المدينة، أضف المدينة للبحث
  • إذا لم يتم العثور على مدينة، باستخدام الحدود، ابحث عن أقرب مدينة للشارع
  • سجل الشارع: للمدن التي تم العثور عليها

كرر جميع العقد، ثم الطرق، ثم العلاقات (كرر الكيان الرئيسي)

ابحث عن الطرق - الاستيفاءات:

  • لكل استيفاء، ابحث عن أو سجل شارعًا بموقع الاستيفاء
  • لكل عقدتين قم بإنشاء مبنى يمثل الاستيفاء

لأي كيان، ابحث عن علامة addr:housenumber و addr:street (يمكن أن تكون أيضًا استيفاء العقد مرة أخرى!!!):

  • تخطى إذا كان المبنى لهذا الكيان موجودًا بالفعل!
  • ابحث عن أو سجل الشوارع للشارع
  • ابحث عن رقم المنزل
  • إذا كان رقم المنزل يحتوي على '-'، حاول إنشاء رقم منزل مستوفى (هل latlon2 مفقود؟)
  • إذا كان رقم المنزل يحتوي على '/'، حاول البحث عن شارع ثانٍ addr:street2 --> يبدو أنه فقط لـ RU osm:
  • هناك المزيد من الاختلافات لذلك: adr:housenumber2، addr2:street، addr2:housenumber إلخ...
  • لكل شارع، قم بتخزين المنزل الموجود

للطريق الذي يحتوي على علامة - اسم وعلامة - طريق سريع، ولكن بدون addr:housenumber و addr:street:

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

كل علاقة ذات "postal_code"، قم بتخزينها للاستخدام لاحقًا.

ملاحظة: هذا لا يشمل address:type = pc و addr:postalcode

معالجة الرموز البريدية:

  • لكل علاقة رمز بريدي مخزنة
  • لكل عضو بناء، قم بتحديث الرمز البريدي

اكتب الفهرس:

قسم المدن إلى: مدن + بلدات، ضواحي (ضاحية بعلامة is_in)، قرى (ليست مدينة أو بلدة)

اكتب المدن + البلدات باستخدام الضواحي

اقرأ الشارع من المدن + البلدات + الضواحي المناسبة لكل بلدة

  • هنا، قد يكون هناك المزيد من الشوارع بنفس الاسم لمدينة واحدة، في هذه الحالة نحاول العثور على جزء مدينة للشارع (ضاحية)، حيث يقع الشارع. يجب ألا يكون هناك المزيد من الشوارع بنفس الاسم داخل جزء مدينة واحد!

لكل شارع

  • لكل مبنى، سجل/أنشئ/ابحث عن رمز بريدي، سجل الشارع

اكتب القرى

  • نفس المدن...

اكتب الرموز البريدية المستخرجة وشوارعها