32. الأنواع الأساسية في الطوبولوجيا

قبل قراءة هذا المستند، يُرجى مراجعة واحد على الأقل من هذه المصادر:

ورشة العمل التمهيدية: ورشة عمل PostGIS Topology.

الدليل: PostGIS Topology.

طوبولوجيا ISO: الأشكال الهندسية وفق OGC-SFS.

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

32.1. الأنواع

_images/basic_types.png

تعمل الطوبولوجيا الأساسية على ثلاثة أنواع أساسية.

  • العقدة (Node): نقطة ثنائية الأبعاد، كل شيء يبدأ أو ينتهي عندها

  • الحافة (Edge): خط ذو اتجاه يبدأ وينتهي عند عقدة

  • الوجه (Face): مجموعة مغلقة من الخطوط تُشكّل مضلعًا

توجد بعض القواعد التي يجب أن تستوفيها مجموعة من العقد والحواف والأوجه لتكون صالحة، راجع مستند ISO Topology ففيه ملخص جيد جدًا لهذه الشروط؛ والطوبولوجيا التي تتبع جميع القواعد هي طوبولوجيا صالحة.

من المفيد أن تعرف أن PostGIS يحفظ حتى الآن كل هذه المعلومات داخليًا، ولكل نوع معرّف فريد خاص به، وبه يمكننا تحريرها وتغييرها باستخدام الدوال المتاحة؛ فمثلًا باستخدام ST_RemEdgeNewFace يمكنك إزالة حافة وإنشاء وجه جديد.

لكن لا تزال هناك قطعة ناقصة: كيف نقول مثلًا إن لوجهٍ ما سمة معينة؟ ينفّذ PostGIS عدة مفاهيم لتحقيق ذلك مثل الطبقات (Layers) و TopoGeometry و TopoElement.

32.2. الوجه الشامل (Universal Face)

قد يبدو بديهيًا أن نظن أن الأوجه الموجودة هي فقط تلك التي تبنيها الحواف، لكن هناك استثناء واحد: كل الفراغ الأبيض خارج جميع الأوجه هو أيضًا وجه!

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

هذا الوجه لا نهائي وليس له أي حدود.

_images/boros_universal_face.png

معرّف الوجه الشامل هو 0.

32.3. تفسير الحافة

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

تُخزَّن جميع المعلومات المتعلقة بالحواف في الجدول edge_data ضمن مخطط (schema) الطوبولوجيا الخاص بك، فما المعلومات التي نحتاجها في الحواف؟ أساسًا معلومات عقدها وأوجهها، فالحافة هي العنصر الأولي الذي يربط بين الاثنين.

تُسمّى هذه الخطوط حوافًا (Edges) لأنها حواف الأوجه.

32.3.1. اتجاه الحافة، اليسار واليمين

للحواف في الطوبولوجيا منظور واتجاه رؤية محددان، ويجب أن ننظر إليها بالطريقة التالية:

_images/edge_perspective.png

عندما نريد النظر من منظور الحافة يكون ذلك دائمًا من عقدة النهاية إلى حافة البداية، مع النظر دائمًا إلى الحافة نحو الأمام.

_images/edge_left_right.png

للحواف خاصيتا يسار ويمين، وكما نرى فهما معرّفتان باستخدام منظور الحافة: انظر إلى الخط من عقدة البداية إلى عقدة النهاية، وسيكون هناك دائمًا يسار ويمين محددان بوضوح.

لذا انظر إلى الحافة نحو الأمام وسيكون لديك دائمًا جانب أيسر وجانب أيمن.

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

_images/face_directions.png

تفحّص الحواف في الصورة: بينما تتجه جميع الحواف تقريبًا من الأسفل إلى الأعلى ومن اليسار إلى اليمين، هناك حافة برتقالية ذات اتجاه معاكس، لذا يكون جانباها الأيسر والأيمن معكوسين مقارنة بالحواف الأخرى، لكن إذا نظرت إلى الحافة نحو الأمام فسيكون اليمين واليسار صحيحين.

واصل النظر إلى الحافة البرتقالية: على يمينها مضلع تبنيه الحواف، وعلى يسارها الوجه الشامل.

عندما نريد تحليل أي حافة ونحتاج إلى رؤيتها من منظور الحافة، فإننا ننظر إليها دائمًا نحو الأمام، وليس نحو الخلف أبدًا!

ما هي جميع الحواف التالية؟ بالنظر نحو الأمام ننتقل من عقدة البداية إلى عقدة النهاية، فهي جميع الحواف التي تبدأ أو تنتهي عند عقدة النهاية لهذه الحافة!

32.4. بيانات الحافة

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

  • edge_id: المعرّف الفريد للحافة

  • start_node: معرّف العقدة المطابقة لنقطة بداية الحافة

  • end_node: معرّف العقدة المطابقة لنقطة نهاية الحافة

  • left_face: معرّف الوجه الواقع على يسار الحافة

  • right_face: معرّف الوجه الواقع على يمين الحافة

  • geom: الشكل الهندسي للحافة

32.4.1. الحافة التالية المطلقة والحافة التالية (Abs Next Edge & Next Edge)

يحتوي الجدول edge_data على العمودين abs_next_left_edge و abs_next_right_edge، وهنا يصبح تفسيرهما معقدًا بعض الشيء.

حتى الآن رأينا أساسًا خصائص الحافة نفسها وما يقع على جانبيها، أما خصائص الحافة التالية فمختلفة؛ فهي لا تتعلق بالحافة نفسها فقط، بل بالحافة التالية التي تبني الوجه الواقع على اليمين أو اليسار.

منطق right_edge و left_edge متشابه جدًا، لذا سنتعمق أولًا في الحافة اليسرى ثم نعرض اليمنى.

سنستخدم الطوبولوجيا التالية مثالًا:

_images/next_edge_base.png

32.4.1.1. اليسار

لنأخذ مثالًا الحافة 5، فعلى يسارها الوجه 2؛ بالنظر نحو الأمام، ما الحافة التالية التي تبني الوجه 2؟

إنها الحافة 6.

_images/next_left_edge_perspective.png

الأمر المهم جدًا هنا هو المنظور الذي نتتبع به الخطوط؛ فبحسب اتجاه الحافة يكون الأمر كأننا ننظر إلى الوجه في اتجاه عقارب الساعة أو عكسه.

بهذه المعلومات تكون قيمة abs_next_left_edge هي 6.

العمود next_left_edge مطابق تقريبًا لـ abs_next_left_edge، إلا أنه قد يكون سالبًا بحسب المنظور الذي نرى منه الحافة.

إذا تتبعنا منظور الحافة فسيكون لدينا اتجاهان: اتجاه الحافة التالية، واتجاه المنظور على الحافة التالية.

سنستخدم الإشارة التالية في كل حالة:

  • اتجاه المنظور واتجاه الحافة التالية متعاكسان: "-"

  • اتجاه المنظور واتجاه الحافة التالية متماثلان: لا شيء، تبقى القيمة موجبة

بما أن المنظور والحافة 6 لهما الاتجاه نفسه، ستكون قيمة next_left_edge هي 6.

  • abs_next_left_edge: 6

  • next_left_edge: 6

32.4.1.3. حالة الحافة المعزولة

هناك حالة قد تكون مربكة؛ جميع القواعد السابقة تنطبق بالطريقة نفسها، لكن من المفيد إلقاء نظرة عليها.

_images/next_edge_one_edge.png

عندما تكون لدينا حافة لا ترتبط بأي حواف أخرى، فأول ما نلاحظه أن الوجه الأيسر هو نفسه الوجه الأيمن، وهو في هذه الحالة الوجه 0، أي الوجه الشامل.

إذا اتبعنا المنطق السابق، فعلى اليسار يقع الوجه 0، فما الحافة التالية التي تبني الوجه 0؟ في الواقع هناك حافة، وهي الحافة نفسها، ولها أيضًا منظور كما في السابق:

_images/next_edge_one_edge_left.png

إذا تفحّصنا اتجاه المنظور فسننتهي إلى النظر إلى الحافة نفسها لكن في الاتجاه المعاكس، وهذا يعني أن الحافة 1 وحافتها التالية (الحافة 1) لهما اتجاهان متعاكسان.

  • edge_id: 1

  • abs_next_left_edge: 1

  • next_left_edge: -1 (ستكون هذه القيمة سالبة دائمًا عندما ننظر إلى حافة معزولة نحو الأمام)

الأمر نفسه بالنسبة للحافة اليمنى التالية؛ فالحافة التالية ستكون هي نفسها، والذي يتغير فقط هو المنظور:

_images/next_edge_one_edge_right.png

عندما ننظر إلى أي حافة معزولة نحو الخلف، يكون للمنظور دائمًا الاتجاه نفسه الذي للحافة، لذا:

  • edge_id: 1

  • abs_next_right_edge: 1

  • next_right_edge: -1 (ستكون هذه القيمة موجبة دائمًا عندما ننظر إلى حافة معزولة نحو الخلف)

32.4.2. جميع أعمدة edge_data

لقد تفحّصنا بالفعل جميع أعمدة الجدول edge_data:

  • edge_id: المعرّف الفريد للحافة.

  • start_node: معرّف العقدة المطابقة لنقطة بداية الحافة.

  • end_node: معرّف العقدة المطابقة لنقطة نهاية الحافة.

  • left_face: معرّف الوجه الواقع على يسار الحافة.

  • abs_next_left_edge: الحافة التالية التي تبني الوجه الواقع على اليسار.

  • next_left_edge: قيمة abs_next_left_edge مع إشارة سالبة إذا كان الوجه الأيمن واقعًا على يمين الحافة اليسرى التالية.

  • right_face: معرّف الوجه الواقع على يمين الحافة.

  • abs_next_right_edge: الحافة التالية التي تبني الوجه الواقع على اليمين.

  • next_right_edge: قيمة abs_next_right_edge مع إشارة سالبة إذا كان الوجه الأيسر واقعًا على يمين الحافة اليمنى التالية.

  • geom: الشكل الهندسي للحافة.