16.5. الدرس: إنشاء الأشكال الهندسية

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

هدف هذا الدرس: فهم أفضل لكيفية إنشاء الكيانات المكانية مباشرة في PostgreSQL.

16.5.1. إنشاء الخطوط (Linestrings)

بالعودة إلى قاعدة البيانات address، لنجعل جدول الشوارع مطابقًا للجداول الأخرى؛ أي أن يكون له قيد على الشكل الهندسي، وفهرس، وإدخال في الجدول geometry_columns.

16.5.2. جرّب بنفسك: ★★☆

  • عدّل الجدول streets بحيث يحتوي على عمود شكل هندسي من النوع ST_LineString.

  • لا تنسَ إجراء التحديث المصاحب على جدول أعمدة الأشكال الهندسية!

  • أضف أيضًا قيدًا يمنع إضافة أي أشكال هندسية ليست من النوع LINESTRING أو فارغة (null).

  • أنشئ فهرسًا مكانيًا على عمود الشكل الهندسي الجديد

لنُدرج الآن خطًا في جدول الشوارع. في هذه الحالة سنحدّث سجل شارع موجود:

update streets
set geom = 'SRID=4326;LINESTRING(20 -33, 21 -34, 24 -33)'
where streets.id=2;

ألقِ نظرة على النتائج في QGIS. (قد تحتاج إلى النقر بزر الفأرة الأيمن على طبقة الشوارع في لوحة 'Layers'، واختيار 'Zoom to layer extent'.)

أنشئ الآن مزيدًا من إدخالات الشوارع، بعضها في QGIS وبعضها من سطر الأوامر.

16.5.3. إنشاء المضلعات

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

insert into cities (name, geom)
values ('Tokyo', 'SRID=4326;POLYGON((10 -10, 5 -32, 30 -27, 10 -10))');

ملاحظة

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

insert into cities (name, geom)
values ('Tokyo Outer Wards',
        'SRID=4326;POLYGON((20 10, 20 20, 35 20, 20 10),
                           (-10 -30, -5 0, -15 -15, -10 -30))'
        );

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

16.5.4. تمرين: ربط المدن بالأشخاص

في هذا التمرين عليك القيام بما يلي:

  • احذف جميع البيانات من جدول الأشخاص.

  • أضف إلى جدول الأشخاص عمود مفتاح أجنبي يشير إلى المفتاح الأساسي لجدول المدن.

  • استخدم QGIS لالتقاط (رسم) بعض المدن.

  • استخدم SQL لإدراج بعض سجلات الأشخاص الجديدة، مع التأكد من أن لكل منها شارعًا ومدينة مرتبطين به.

يجب أن يبدو مخطط جدول الأشخاص المحدّث تقريبًا هكذا:

\d people

Table "public.people"
   Column   |         Type          |                      Modifiers
 -----------+-----------------------+--------------------------------------------
  id        | integer               | not null
            |                       | default nextval('people_id_seq'::regclass)
  name      | character varying(50) |
  house_no  | integer               | not null
  street_id | integer               | not null
  phone_no  | character varying     |
  geom      | geometry              |
  city_id   | integer               | not null
Indexes:
  "people_pkey" PRIMARY KEY, btree (id)
  "people_name_idx" btree (name)
Check constraints:
  "people_geom_point_chk" CHECK (st_geometrytype(geom) =
                       'ST_Point'::text OR geom IS NULL)
Foreign-key constraints:
  "people_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cities(id)
  "people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)

16.5.5. نظرة على المخطط

يجب أن يبدو المخطط الآن هكذا:

../../../_images/final_schema.png

16.5.6. جرّب بنفسك: ★★★

أنشئ حدود المدن بحساب أصغر غلاف محدب (convex hull) لجميع العناوين في كل مدينة وحساب نطاق عازل حول تلك المنطقة.

16.5.7. الوصول إلى الكائنات الفرعية

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

  • حوّل حدود المضلع إلى خط:

    select st_boundary(geom) from myPolygonTable;
    
  • حدد نقطة الرأس الأول للخط الناتج:

    select st_startpoint(myGeometry)
    from (
        select st_boundary(geom) as myGeometry
        from myPolygonTable) as foo;
    

16.5.8. معالجة البيانات

يدعم PostGIS جميع الدوال المتوافقة مع معيار OGC SFS/MM، وتبدأ جميع هذه الدوال بـ ST_.

16.5.9. القص

لقص جزء فرعي من بياناتك يمكنك استخدام الدالة ST_INTERSECT(). ولتجنب الأشكال الهندسية الفارغة، استخدم:

where not st_isempty(st_intersection(a.geom, b.geom))
../../../_images/qgis_001.png
select st_intersection(a.geom, b.geom), b.*
from clip as a, road_lines as b
where not st_isempty(st_intersection(st_setsrid(a.geom,32734),
  b.geom));
../../../_images/qgis_002.png

16.5.10. بناء أشكال هندسية من أشكال هندسية أخرى

تريد إنشاء خط من جدول نقاط معين. يُحدَّد ترتيب النقاط بواسطة id الخاص بها. ويمكن أن تكون طريقة الترتيب الأخرى طابعًا زمنيًا، مثل الذي تحصل عليه عند التقاط نقاط المسار بجهاز استقبال GPS.

../../../_images/qgis_006.png

لإنشاء خط من طبقة نقاط جديدة اسمها 'points'، يمكنك تشغيل الأمر التالي:

select ST_LineFromMultiPoint(st_collect(geom)), 1 as id
from (
  select geom
  from points
  order by id
) as foo;

لترى كيف يعمل دون إنشاء طبقة جديدة، يمكنك أيضًا تشغيل هذا الأمر على الطبقة 'people'، وإن كان ذلك بالطبع لا معنى عمليًا له في الواقع.

../../../_images/qgis_007.png

16.5.11. تنظيف الأشكال الهندسية

يمكنك الحصول على مزيد من المعلومات حول هذا الموضوع في هذه التدوينة.

16.5.12. الفروق بين الجداول

لاكتشاف الفرق بين جدولين لهما البنية نفسها، يمكنك استخدام الكلمة المفتاحية EXCEPT في PostgreSQL:

select * from table_a
except
select * from table_b;

ستحصل نتيجةً لذلك على جميع السجلات من table_a غير المخزنة في table_b.

16.5.13. مساحات الجداول (Tablespaces)

يمكنك تحديد المكان الذي يخزن فيه postgres بياناته على القرص بإنشاء مساحات الجداول (tablespaces):

CREATE TABLESPACE homespace LOCATION '/home/pg';

عند إنشاء قاعدة بيانات، يمكنك بعد ذلك تحديد مساحة الجداول التي ستُستخدم، مثلًا:

createdb --tablespace=homespace t4a

16.5.14. الخلاصة

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