12.4. ربط البيانات وتحريرها عبر الطبقات

القدرة على ربط البيانات من طبقات مختلفة من المهام الأساسية لبرمجيات نظم المعلومات الجغرافية (GIS). ويمكن أن يستند هذا الربط إلى العلاقة المكانية بين المعالم، أو إلى سماتها المشتركة. يوفر QGIS أدوات للتعامل مع أي من هذه الارتباطات، مثل:

12.4.1. ربط المعالم بين طبقتين

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

لإنشاء ربط على طبقة (يُشار إليها أدناه بـ target layer):

  1. انتقل إلى التبويب Properties ► join Joins للطبقة

  2. انقر على الزر symbologyAdd Add new join. تظهر نافذة الحوار Add vector join.

  3. اختر Join layer التي تريد ربطها بالطبقة المتجهية الهدف

  4. حدد Join field (من join layer) و Target field (من target layer). هذان هما الحقلان المستخدمان لإيجاد المعالم المتطابقة في الطبقتين، لذا يجب أن تكون بينهما قيم مشتركة.

  5. اضغط OK فيُضاف ملخص للمعاملات المحددة إلى لوحة Join.

../../../_images/join_attributes.png

شكل 12.109 ربط جدول بيانات وصفية بطبقة متجهية موجودة

ستنشئ الخطوات السابقة ربطًا تُضاف فيه جميع سمات أول معلم مطابق في طبقة الربط إلى معلم الطبقة الهدف. ويُستخدم المنطق التالي لإقران المعالم أثناء عملية الربط:

  • تُعاد جميع معالم الطبقة الهدف، سواء كان لها تطابق أم لا

  • إذا احتوى الحقل الهدف على قيم مكررة، تُسنَد إلى هذه المعالم المعلمُ نفسه من طبقة الربط.

  • إذا احتوى حقل الربط على قيم مطابقة مكررة، يُختار أول معلم يُجلب فقط.

ملاحظة

يعتمد الربط في QGIS على تطابق حقل واحد، لذا ستحرص في معظم الأحيان على أن تكون القيم في الحقول القابلة للمطابقة فريدة.

يوفر QGIS بعض الخيارات الإضافية لضبط الربط:

  • checkbox Cache join layer in virtual memory: يتيح لك تخزين قيم الطبقة المربوطة مؤقتًا في الذاكرة (دون الأشكال الهندسية) لتسريع عمليات البحث.

  • unchecked Create attribute index on the join field لتسريع عمليات البحث

  • unchecked Dynamic form: يساعد على مزامنة حقول الربط فوريًا وفقًا لـ Target field. وبهذه الطريقة تُحدَّث قيود حقول الربط أيضًا بشكل صحيح. لاحظ أنه معطّل افتراضيًا لأنه قد يستغرق وقتًا طويلًا جدًا إذا كان لديك عدد كبير من المعالم أو عدد هائل من عمليات الربط.

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

    • joinNotEditable: طبقة الربط غير مهيأة لتكون قابلة للتحرير. إذا أردت أن تتمكن من تحرير معالم الربط من جدول البيانات الوصفية للطبقة الهدف، فعليك تحديد الخيار checkbox Editable join layer.

    • joinedLayerNotEditable: طبقة الربط مهيأة جيدًا لتكون قابلة للتحرير، لكن حالتها الحالية للقراءة فقط.

    • joinHasNotUpsertOnEdit: طبقة الربط قابلة للتحرير، لكن آليات المزامنة غير مفعّلة. إذا أردت إضافة معلم تلقائيًا في طبقة الربط عند إنشاء معلم في الطبقة الهدف، فعليك تحديد الخيار checkbox Upsert on edit. وبالمثل، يمكن تفعيل الخيار checkbox Delete cascade إذا أردت حذف معالم الربط تلقائيًا.

  • unchecked Joined fields: بدلًا من إضافة جميع حقول الطبقة المربوطة، يمكنك تحديد مجموعة جزئية منها.

  • unchecked Custom field name prefix للحقول المربوطة، لتجنب تعارض الأسماء

12.4.2. إعداد العلاقات بين طبقات متعددة

على عكس الربط الذي يعرّف صلة واحد إلى واحد بين معالم طبقتين، تساعدك العلاقات على بناء ترابطات بين معالم متعددة عبر طبقتين أو أكثر. ولذلك فإن العلاقات إعدادات على مستوى المشروع، وتُعيَّن في التبويب Project ► Properties ► العلاقات Relations. ومن هناك يمكنك:

  • symbologyAdd Add relation ويمكن أن يكون نوعها:

    ملاحظة

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

  • symbologyAdd Discover relations: يستطيع QGIS اكتشاف العلاقات الموجودة من صيغ قواعد البيانات المدعومة (PostgreSQL وGeoPackage وESRI File Geodatabase، ...). ويمكن أن تكون هذه طريقة جيدة لتسهيل تعريف العلاقات.

  • symbologyRemove Remove relation

../../../_images/project_relations.png

شكل 12.110 تبويب العلاقات

12.4.2.1. علاقات واحد إلى متعدد (1-N)

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

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

../../../_images/regions_with_airports.png

شكل 12.111 منطقة في Alaska مع المطارات

الطبقات والمفاتيح

لا يفرّق QGIS بين الجدول والطبقة المتجهية. فالطبقة المتجهية في الأساس جدول له شكل هندسي. لذا يمكنك إضافة جدولك كطبقة متجهية. ولتوضيح علاقة 1-n، يمكنك تحميل الطبقتين regions و airports من مجموعة البيانات النموذجية. عمليًا، ينتمي كل مطار إلى منطقة واحدة بالضبط، بينما يمكن أن تضم كل منطقة أي عدد من المطارات (علاقة واحد إلى متعدد نموذجية).

إضافةً إلى السمات التي تصف المطارات، تحتوي طبقة المطارات على حقل آخر هو fk_region يعمل كمفتاح أجنبي (إذا كانت لديك قاعدة بيانات، فستحتاج على الأرجح إلى تعريف قيد عليه). سيحتوي الحقل fk_region دائمًا على معرّف منطقة، ويمكن اعتباره مؤشرًا إلى المنطقة التي ينتمي إليها.

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

تعريف علاقات 1-N

أول ما سنفعله هو إعلام QGIS بالعلاقات بين الطبقات. ويتم ذلك من Project ► Properties.... افتح التبويب Relations وانقر على symbologyAdd Add Relation.

  • سيُستخدم Name كعنوان. ويجب أن يكون نصًا مقروءًا للإنسان يصف الغرض من العلاقة. سنسميها ببساطة airport_relation في هذه الحالة.

  • Referenced Layer (Parent) وتُعدّ أيضًا الطبقة الأم، وهي الطبقة ذات المفتاح الأساسي التي يُشار إليها، وهي هنا الطبقة regions. يجب عليك تعريف المفتاح الأساسي للطبقة المشار إليها، وهو ID.

  • Referencing Layer (Child) وتُعدّ أيضًا الطبقة الابنة، وهي الطبقة التي تحتوي على حقل المفتاح الأجنبي. وفي حالتنا هي الطبقة airports. ولهذه الطبقة يجب عليك إضافة حقل مرجعي يشير إلى الطبقة الأخرى، وهو fk_region.

    ملاحظة

    أحيانًا تحتاج إلى أكثر من حقل واحد لتعريف المعالم في طبقة بشكل فريد. ويتطلب إنشاء علاقة مع مثل هذه الطبقة مفتاحًا مركبًا، أي أكثر من زوج واحد من الحقول المتطابقة. استخدم الزر symbologyAdd Add new field pair as part of a composite foreign key لإضافة ما يلزم من الأزواج.

  • سيُستخدم Id لأغراض داخلية ويجب أن يكون فريدًا. قد تحتاج إليه لبناء نماذج مخصصة. إذا تركته فارغًا فسيُولَّد لك معرّف تلقائيًا، لكن يمكنك تعيين معرّف بنفسك ليكون التعامل معه أسهل

  • Relationship strength يعيّن قوة العلاقة بين الطبقة الأم والطبقة الابنة. يعني النوع الافتراضي Association أن الطبقة الأم مرتبطة بالطبقة الابنة فحسب، بينما يتيح لك النوع Composition تكرار المعالم الابنة أيضًا عند تكرار المعالم الأم، وعند حذف معلم تُحذف أبناؤه كذلك، مما يؤدي إلى حذف متتالٍ عبر جميع المستويات (أي تُحذف أبناء الأبناء... أيضًا).

../../../_images/regions_airports_mapping.png

شكل 12.112 إضافة علاقة بين طبقتي المناطق والمطارات

من التبويب Relations يمكنك أيضًا الضغط على الزر symbologyAdd Discover Relation لجلب العلاقات المتاحة من مزوّدي بيانات الطبقات المحمّلة. وهذا ممكن للطبقات المخزنة لدى مزوّدي بيانات مثل PostgreSQL أو SpatiaLite.

النماذج لعلاقات 1-N

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

../../../_images/airport_relation_dataview.png

شكل 12.113 نافذة حوار التعريف للمناطق مع العلاقة بالمطارات

كما ترى، تُعرض جميع المطارات المسندة إلى هذه المنطقة بعينها في جدول. وتتوفر أيضًا بعض الأزرار. لنستعرضها باختصار:

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

  • الزر saveEdits مخصص لحفظ جميع التعديلات في الطبقة الابنة (المطارات).

  • يتيح لك الزر capturePoint رقمنة الشكل الهندسي للمطار في لوحة الخريطة، ويسند المعلم الجديد إلى المنطقة الحالية افتراضيًا. لاحظ أن الأيقونة ستتغير وفقًا لنوع الشكل الهندسي.

  • يضيف الزر newTableRow سجلًا جديدًا إلى جدول البيانات الوصفية لطبقة المطارات، ويسند المعلم الجديد إلى المنطقة الحالية افتراضيًا. ويمكن رسم الشكل الهندسي لاحقًا بأداة الرقمنة Add part.

  • يتيح لك الزر duplicateFeature نسخ معلم ابن أو أكثر ولصقه داخل الطبقة الابنة. ويمكن لاحقًا إسنادها إلى معلم أم مختلف أو تعديل سماتها.

  • يحذف الزر deleteSelectedFeatures المطار (المطارات) المحدد نهائيًا.

  • يفتح الرمز link نافذة حوار جديدة يمكنك فيها اختيار أي مطار موجود ليُسنَد بعد ذلك إلى المنطقة الحالية. وقد يكون هذا مفيدًا إذا أنشأت المطار في المنطقة الخطأ عن طريق الخطأ.

  • يفك الرمز unlink ارتباط المطار (المطارات) المحدد بالمنطقة الحالية، فيتركه فعليًا غير مُسنَد (تُعيَّن قيمة المفتاح الأجنبي إلى NULL).

  • باستخدام الزر zoomToSelected يمكنك تكبير الخريطة إلى المعالم الابنة المحددة.

  • يبدّل الزران formView و openTable الموجودان على اليمين بين عرض الجدول وعرض النموذج للمعالم الابنة المرتبطة.

إذا استخدمت مصمّم السحب والإفلات لمعلم المناطق، يمكنك اختيار الأدوات المتاحة. بل يمكنك تحديد ما إذا كان سيُفتح نموذج جديد عند إضافة معلم جديد باستخدام الخيار Force hide form on add feature. انتبه إلى أن هذا الخيار يقتضي أن تأخذ السمات غير الفارغة (not null) قيمة افتراضية صالحة لكي يعمل بشكل صحيح.

../../../_images/airport_relation_formproperties.png

شكل 12.114 مصمّم السحب والإفلات لتهيئة أدوات علاقة المناطق والمطارات

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

  1. اختر openTable Open Attribute Table للطبقة المرجِعة.

  2. حدد السجل الذي أُضيف سابقًا ضمن نموذج المعلم للطبقة المشار إليها.

  3. استخدم أداة الرقمنة addPart Add Part لإرفاق شكل هندسي بسجل جدول البيانات الوصفية المحدد.

إذا كنت تعمل على جدول المطارات، فإن عنصر الواجهة Relation Reference يُهيَّأ تلقائيًا للحقل fk_region (الحقل المستخدم لإنشاء العلاقة)، انظر عنصر الواجهة Relation Reference.

في نموذج المطار سترى الزر formView على الجانب الأيمن من الحقل fk_region: إذا نقرت على الزر فسيُفتح نموذج طبقة المناطق. يتيح لك عنصر الواجهة هذا فتح نماذج المعالم الأم المرتبطة بسهولة وسرعة.

../../../_images/airport_attributes.png

شكل 12.115 نافذة حوار التعريف للمطار مع العلاقة بالمناطق

يتضمن عنصر الواجهة Relation Reference أيضًا خيارًا لتضمين نموذج الطبقة الأم داخل نموذج الطبقة الابنة. وهو متاح في القائمة Properties ► Attributes Form لطبقة المطارات: حدد الحقل fk_region وفعّل الخيار Show embedded form.

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

../../../_images/airport_attributes_expanded.png

علاوة على ذلك، إذا فعّلت وضع التحرير لطبقة المطارات، فإن الحقل fk_region يتمتع أيضًا بوظيفة الإكمال التلقائي: أثناء الكتابة سترى جميع قيم الحقل id لطبقة المناطق. وهنا يمكن رقمنة مضلع لطبقة المناطق باستخدام الزر symbologyAdd إذا اخترت الخيار Allow adding new features في القائمة Properties ► Attributes Form لطبقة المطارات.

يمكن أيضًا استخدام الطبقة الابنة في الأداة تحديد المعالم حسب القيمة لتحديد معالم الطبقة الأم بناءً على سمات أبنائها.

في شكل 12.116، تُحدَّد جميع المناطق التي يزيد فيها متوسط ارتفاع المطارات عن 500 متر فوق مستوى سطح البحر.

ستجد أن العديد من دوال التجميع المختلفة متاحة في النموذج.

../../../_images/relation_select_by_value.png

شكل 12.116 تحديد المعالم الأم بقيم الأبناء

12.4.2.2. علاقات متعدد إلى متعدد (N-M)

علاقات N-M هي علاقات متعدد إلى متعدد بين جدولين. على سبيل المثال، الطبقتان airports و airlines: يستقبل المطار عدة شركات طيران، وتطير شركة الطيران إلى عدة مطارات.

تُنشئ شيفرة SQL هذه الجداول الثلاثة التي نحتاجها لعلاقة N-M في مخطط PostgreSQL باسم locations. يمكنك تشغيل الشيفرة باستخدام Database ► DB Manager… لـ PostgreSQL أو أدوات خارجية مثل pgAdmin. يخزن جدول airports الطبقة airports، ويخزن جدول airline الطبقة airlines. وفي كلا الجدولين استُخدمت حقول قليلة للتوضيح. أما الجزء الدقيق فهو الجدول airports_airlines. نحتاج إليه لسرد جميع شركات الطيران لجميع المطارات (أو العكس). ويُعرف هذا النوع من الجداول بـ الجدول المحوري (pivot table). وتفرض القيود في هذا الجدول ألا يُربط مطار بشركة طيران إلا إذا كان كلاهما موجودًا مسبقًا في طبقته.

CREATE SCHEMA locations;

CREATE TABLE locations.airports
(
   id serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   airport_name text NOT NULL,
   CONSTRAINT airports_pkey PRIMARY KEY (id)
);

CREATE INDEX airports_geom_idx ON locations.airports USING gist (geom);

CREATE TABLE locations.airlines
(
   id serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   airline_name text NOT NULL,
   CONSTRAINT airlines_pkey PRIMARY KEY (id)
);

CREATE INDEX airlines_geom_idx ON locations.airlines USING gist (geom);

CREATE TABLE locations.airports_airlines
(
   id serial NOT NULL,
   airport_fk integer NOT NULL,
   airline_fk integer NOT NULL,
   CONSTRAINT airports_airlines_pkey PRIMARY KEY (id),
   CONSTRAINT airports_airlines_airport_fk_fkey FOREIGN KEY (airport_fk)
      REFERENCES locations.airports (id)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      DEFERRABLE INITIALLY DEFERRED,
   CONSTRAINT airports_airlines_airline_fk_fkey FOREIGN KEY (airline_fk)
      REFERENCES locations.airlines (id)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      DEFERRABLE INITIALLY DEFERRED
 );

بدلًا من PostgreSQL يمكنك أيضًا استخدام GeoPackage. وفي هذه الحالة يمكن إنشاء الجداول الثلاثة يدويًا باستخدام Database ► DB Manager…. لا توجد مخططات (schemas) في GeoPackage، لذا لا حاجة إلى البادئة locations.

لا يمكن إنشاء قيود المفاتيح الأجنبية في الجدول airports_airlines باستخدام Table ► Create Table… أو Table ► Edit Table…، لذا يجب إنشاؤها باستخدام Database ► SQL Window…. لا يدعم GeoPackage عبارات ADD CONSTRAINT، لذا يجب إنشاء الجدول airports_airlines على خطوتين:

  1. أنشئ الجدول بالحقل id فقط باستخدام Table ► Create Table…

  2. باستخدام Database ► SQL Window…، اكتب شيفرة SQL هذه ونفّذها:

    ALTER TABLE airports_airlines
       ADD COLUMN airport_fk INTEGER
       REFERENCES airports (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
       DEFERRABLE INITIALLY DEFERRED;
    
    ALTER TABLE airports_airlines
       ADD COLUMN airline_fk INTEGER
       REFERENCES airlines (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
       DEFERRABLE INITIALLY DEFERRED;
    

بعد ذلك يجب عليك في QGIS إعداد علاقتي واحد إلى متعدد كما شُرح أعلاه:

  • علاقة بين الجدول airlines والجدول المحوري؛

  • وعلاقة ثانية بين الجدول airports والجدول المحوري.

الطريقة الأسهل للقيام بذلك (لـ PostgreSQL فقط) هي استخدام Discover Relations في Project ► Properties ► Relations. سيقرأ QGIS تلقائيًا جميع العلاقات في قاعدة بياناتك، وكل ما عليك هو تحديد العلاقتين اللتين تحتاجهما. تذكّر تحميل الجداول الثلاثة في مشروع QGIS أولًا.

../../../_images/airports_airlines_relation.png

شكل 12.117 العلاقات والاكتشاف التلقائي

إذا أردت حذف airport أو airline، فلن يحذف QGIS السجل (السجلات) المرتبطة في الجدول airports_airlines. ستتولى قاعدة البيانات هذه المهمة إذا حددنا القيود الصحيحة عند إنشاء الجدول المحوري كما في المثال الحالي.

ملاحظة

دمج علاقة N-M مع مجموعة المعاملات التلقائية

يجب عليك تفعيل وضع المعاملات (transaction mode) في Project Properties ► Data Sources ► عند العمل في مثل هذا السياق. إذ يجب أن يتمكن QGIS من إضافة صف (صفوف) أو تحديثها في جميع الجداول (شركات الطيران والمطارات والجداول المحورية).

أخيرًا، علينا اختيار التعددية (cardinality) الصحيحة في Layer Properties ► Attributes Form للطبقتين airports و airlines. للأولى يجب اختيار الخيار airlines (id)، وللثانية الخيار airports (id).

../../../_images/airports_airlines_relation_formproperties.png

شكل 12.118 تعيين تعددية العلاقة

يمكنك الآن ربط مطار بشركة طيران (أو شركة طيران بمطار) باستخدام Add child feature أو Link existing child feature في النماذج الفرعية. سيُدرج سجل تلقائيًا في الجدول airports_airlines.

../../../_images/add_airport_airline.png

شكل 12.119 علاقة N-M بين المطارات وشركات الطيران

ملاحظة

استخدام التعددية Many to one relation

أحيانًا لا يكون إخفاء الجدول المحوري في علاقة N-M مرغوبًا، والسبب الرئيسي هو وجود سمات في العلاقة لا يمكن أن تأخذ قيمًا إلا عند إنشاء العلاقة. إذا كانت جداولك تحتوي على حقل شكل هندسي، فقد يكون من المفيد تفعيل الخيار On map identification (Layer Properties ► Attributes Form ► Available widgets ► Fields) لحقول المفاتيح الأجنبية في الجدول المحوري.

ملاحظة

المفتاح الأساسي للجدول المحوري

تجنّب استخدام حقول متعددة في المفتاح الأساسي للجدول المحوري. يفترض QGIS وجود مفتاح أساسي واحد، لذا لن يعمل قيد مثل constraint airports_airlines_pkey primary key (airport_fk, airline_fk).

12.4.2.3. العلاقات متعددة الأشكال

الغرض

العلاقات متعددة الأشكال (Polymorphic) حالة خاصة من علاقات 1-N، تحتوي فيها طبقة مرجِعة واحدة (طبقة المستندات) على المعالم الخاصة بعدة طبقات مشار إليها. ويختلف ذلك عن العلاقات العادية التي تتطلب طبقة مرجِعة مختلفة لكل طبقة مشار إليها. ويتحقق وجود طبقة مرجِعة واحدة (طبقة المستندات) بإضافة عمود إضافي layer_field في الطبقة المرجِعة (طبقة المستندات) يخزن معلومات لتعريف الطبقة المشار إليها. وفي أبسط صوره، تُدرج الطبقة المرجِعة (طبقة المستندات) في هذا الحقل اسم الطبقة المشار إليها فقط.

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

تخيّل أننا ذاهبون إلى الحديقة ونريد التقاط صور لأنواع مختلفة من plants و animals نراها هناك. ولكل نبات أو حيوان عدة صور مرتبطة به، فإذا استخدمنا علاقات 1:N العادية لتخزين الصور، فسنحتاج إلى جدولين منفصلين، animal_images و plant_images. قد لا يمثّل هذا مشكلة لجدولين، لكن تخيّل لو أردنا التقاط صور منفصلة للفطريات والطيور وغيرها.

تحل العلاقات متعددة الأشكال هذه المشكلة، إذ تُخزَّن جميع المعالم المرجِعة في الجدول نفسه documents. ولكل معلم تُخزَّن الطبقة المشار إليها في الحقل referenced_layer، ومعرّف المعلم المشار إليه في الحقل referenced_id.

تعريف العلاقات متعددة الأشكال

أولًا، أعلِم QGIS بالعلاقات متعددة الأشكال بين الطبقات. ويتم ذلك من Project ► Properties.... افتح التبويب Relations وانقر على السهم الصغير المتجه للأسفل بجوار الزر symbologyAdd Add Relation، حتى تتمكن من اختيار الخيار Add Polymorphic Relation من القائمة المنسدلة التي تظهر.

../../../_images/polymorphic_relation_properties.png

شكل 12.120 إضافة علاقة متعددة الأشكال باستخدام الطبقة documents كطبقة مرجِعة والطبقتين animals و plants كطبقتين مشار إليهما.

  • سيُستخدم Id لأغراض داخلية ويجب أن يكون فريدًا. قد تحتاج إليه لبناء نماذج مخصصة. إذا تركته فارغًا فسيُولَّد لك معرّف تلقائيًا، لكن يمكنك تعيين معرّف بنفسك ليكون التعامل معه أسهل

  • Referencing Layer (Child) وتُعدّ أيضًا الطبقة الابنة، وهي الطبقة التي تحتوي على حقل المفتاح الأجنبي. وفي حالتنا هي الطبقة documents. ولهذه الطبقة يجب عليك إضافة حقل مرجعي يشير إلى الطبقة الأخرى، وهو referenced_id.

    ملاحظة

    أحيانًا تحتاج إلى أكثر من حقل واحد لتعريف المعالم في طبقة بشكل فريد. ويتطلب إنشاء علاقة مع مثل هذه الطبقة مفتاحًا مركبًا، أي أكثر من زوج واحد من الحقول المتطابقة. استخدم الزر symbologyAdd Add new field pair as part of a composite foreign key لإضافة ما يلزم من الأزواج.

  • Layer Field هو الحقل في الجدول المرجِع الذي يخزن نتيجة تقييم تعبير الطبقة، أي الجدول المشار إليه الذي ينتمي إليه هذا المعلم. وفي مثالنا سيكون هذا هو الحقل referenced_layer.

  • Layer expression يُقيَّم إلى معرّف فريد للطبقة. ويمكن أن يكون اسم الطبقة @layer_name، أو معرّف الطبقة @layer_id، أو اسم جدول الطبقة decode_uri(@layer, 'table') أو أي شيء يمكنه تعريف الطبقة بشكل فريد.

  • Relationship strength يعيّن قوة العلاقات المولّدة بين الطبقة الأم والطبقة الابنة. يعني النوع الافتراضي Association أن الطبقة الأم مرتبطة بالطبقة الابنة فحسب، بينما يتيح لك النوع Composition تكرار المعالم الابنة أيضًا عند تكرار المعالم الأم، وعند حذف معلم تُحذف أبناؤه كذلك، مما يؤدي إلى حذف متتالٍ عبر جميع المستويات (أي تُحذف أبناء الأبناء... أيضًا).

  • Referenced Layers وتُعدّ أيضًا الطبقات الأم، وهي الطبقات ذات المفتاح الأساسي التي يُشار إليها، وهي هنا الطبقتان plants و animals. يجب عليك تعريف المفتاح الأساسي للطبقات المشار إليها من القائمة المنسدلة، وهو fid. لاحظ أن تعريف مفتاح أساسي صالح يتطلب أن يكون في جميع الطبقات المشار إليها حقل بهذا الاسم. وإذا لم يوجد مثل هذا الحقل فلا يمكنك حفظ العلاقة متعددة الأشكال.

بعد إضافتها، يمكن تحرير العلاقة متعددة الأشكال عبر بند القائمة Edit Polymorphic Relation.

../../../_images/polymorphic_relations.png

شكل 12.121 معاينة العلاقة متعددة الأشكال المنشأة حديثًا وعلاقاتها الابنة للحيوانات والنباتات.

يستخدم المثال أعلاه مخطط قاعدة البيانات التالي:

CREATE SCHEMA park;

CREATE TABLE park.animals
(
   fid serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   animal_species text NOT NULL,
   CONSTRAINT animals_pkey PRIMARY KEY (fid)
);

CREATE INDEX animals_geom_idx ON park.animals USING gist (geom);

CREATE TABLE park.plants
(
   fid serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   plant_species text NOT NULL,
   CONSTRAINT plants_pkey PRIMARY KEY (fid)
);

CREATE INDEX plants_geom_idx ON park.plants USING gist (geom);

CREATE TABLE park.documents
(
   fid serial NOT NULL,
   referenced_layer text NOT NULL,
   referenced_id integer NOT NULL,
   image_filename text NOT NULL,
   CONSTRAINT documents_pkey PRIMARY KEY (fid)
);

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

12.4.2.4. العلاقات المخزنة في مجموعة البيانات

إلى جانب العلاقات المذكورة أعلاه التي تُنشأ في خصائص المشروع وتنطبق على المشروع النشط فقط، يستطيع QGIS أيضًا قراءة العلاقات على مستوى قاعدة البيانات، أي الروابط المعرَّفة بين الطبقات في مجموعة البيانات. وهذا مدعوم لمزوّدي قواعد البيانات مثل PostgreSQL وSpatiaLite وGeoPackage وESRI FileGeodatabase. عند تحميل مثل هذه الطبقات الأم والابنة في مشروع، يستطيع QGIS اكتشاف إعدادات العلاقة تلقائيًا وملء التبويب Project ► Project properties ► Relations بالشكل المناسب. ويمكن أيضًا تشغيل ذلك باستخدام الزر symbologyAdd Discover relations.

بالنسبة لبعض أنواع البيانات (مثل GeoPackage أو SpatiaLite أو ESRI FileGeodatabase)، يتيح QGIS أيضًا إنشاء العلاقات بين الجداول في قاعدة البيانات وتحريرها. ويمكن إدارة ذلك عبر Browser Panel. من Browser panel، انقر بزر الفأرة الأيمن على مدخل قاعدة البيانات، واختر New relationship...، ثم املأ الخيارات التالية في نافذة الحوار الجديدة:

  • Name: عيّن اسم العلاقة الجديدة.

  • Cardinality: حدّد عدديّة (Cardinality) العلاقة.

  • Strength: حدّد قوة العلاقة.

  • ضمن مجموعة Tables، عيّن الجدولين Parent (الأب) و Child (الابن).

  • ضمن مجموعة Fields، عيّن Parent field و Child field.

  • ضمن قسم Advanced، يمكنك تعيين ما يلي حسب نوع قاعدة البيانات:

    • Related table type:

      • features: لجداول المعالم القياسية.

      • media: للجداول التي تخزّن ملفات الوسائط.

      • simple_attributes: للجداول ذات البيانات الوصفية البسيطة.

      • attributes: للجداول ذات البيانات الوصفية المعقدة.

      • tiles: للجداول التي تخزّن بيانات البلاطات.

    • Forward label: اسم يعرّف العلاقة تعريفًا فريدًا عند التنقل من الجدول الأب إلى الجدول الابن.

    • Reverse label: اسم يعرّف العلاقة تعريفًا فريدًا عند التنقل من الجدول الابن إلى الجدول الأب.

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

يمكن تحرير العلاقات الموجودة أو حذفها بالنقر بزر الفأرة الأيمن على العلاقة في لوحة المتصفح (Browser Panel).

../../../_images/browser_panel_relationships.png

شكل 12.122 إدارة العلاقات المخزّنة في مجموعة البيانات من لوحة المتصفح

12.4.3. تخزين مورد خارجي وجلبه

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

12.4.3.1. ضبط تخزين خارجي

لإعداد تخزين خارجي، عليك أولًا ضبطه من خصائص نموذج البيانات الوصفية للطبقة المتجهية، واختيار عنصر الواجهة Attachment.

../../../_images/external_storage_configuration.png

شكل 12.123 تحرير تخزين خارجي من نوع WebDAV لحقل معيّن

من عنصر الواجهة Attachment، عليك أولًا اختيار Storage type:

  • Select Existing File: عنوان URL الهدف موجود مسبقًا. عند اختيار مورد لا تُجرى أي عملية تخزين، بل تُحدَّث السمة بعنوان URL فقط.

  • Simple Copy: تُخزَّن نسخة من المورد في وجهة على قرص (قد تكون نظام ملفات محليًا أو مشتركًا عبر الشبكة)، وتُحدَّث السمة بمسار النسخة.

  • WebDAV Storage: يُرفع المورد إلى خادم HTTP يدعم بروتوكول WebDAV، وتُحدَّث السمة بعنوان URL الخاص به. وتدعم برمجيات استضافة الملفات مثل Nextcloud و Pydio وغيرها هذا البروتوكول.

  • AWS S3: يُرفع المورد إلى خادم يدعم بروتوكول AWS Simple Storage Service، وتُحدَّث السمة بعنوان URL الخاص به. وتدعم Amazon Web Service وبرمجية الاستضافة MinIO هذا البروتوكول.

بعد ذلك، عليك إعداد المعامل Store URL، الذي يوفر عنوان URL المستخدم عند الحاجة إلى تخزين مورد جديد. ويمكن إعداد تعبير باستخدام عنصر واجهة التجاوز المعرّف بالبيانات للحصول على قيم محددة وفقًا لسمات المعلم.

يمكن استخدام المتغير @selected_file_path في ذلك التعبير، وهو يمثل المسار المطلق للملف الذي اختاره المستخدم (باستخدام أداة اختيار الملفات أو السحب والإفلات).

ملاحظة

عند استخدام التخزين الخارجي WebDAV أو AWS S3، إذا انتهى عنوان URL بالرمز "/" فإنه يُعدّ مجلدًا، ويُلحق اسم الملف المختار به للحصول على عنوان URL النهائي.

إذا تطلّب نظام التخزين الخارجي ذلك، يمكن ضبط المصادقة.

ملاحظة

لاستخدام التخزين الخارجي AWS S3، يجب أن تستخدم نوع مصادقة AWS S3.

12.4.3.2. استخدام تخزين خارجي

بعد الضبط، يمكنك اختيار ملف محلي باستخدام الزر ... عند تحرير سمة أحد المعالم. واعتمادًا على نوع التخزين المضبوط، سيُخزَّن الملف على نظام التخزين الخارجي (إلا إذا اختير Select existing file) ويُحدَّث الحقل بعنوان URL للمورد الجديد.

../../../_images/external_storage_store.png

شكل 12.124 تخزين ملف في تخزين خارجي من نوع WebDAV

ملاحظة

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

استخدم الزر taskCancel Cancel لإلغاء عملية التخزين. ويمكن ضبط عارض باستخدام Integrated document viewer بحيث يُجلب المورد تلقائيًا من نظام التخزين الخارجي ويُعرض مباشرةً أسفل عنوان URL. وتشير الأيقونة warning أعلاه إلى تعذّر جلب المورد من نظام التخزين الخارجي، وفي هذه الحالة قد تظهر تفاصيل إضافية في سجل لوحة الرسائل.