9. الأشكال الهندسية¶
9.1. مقدمة¶
في القسم السابق، حمّلنا مجموعة متنوعة من البيانات. وقبل أن نبدأ العمل على بياناتنا، لنلقِ نظرة على بعض الأمثلة الأبسط. في pgAdmin، اختر مرة أخرى قاعدة البيانات nyc وافتح أداة استعلام SQL. الصق مثال SQL هذا في نافذة محرر SQL في pgAdmin (بعد حذف أي نص قد يكون موجودًا افتراضيًا) ثم نفّذه.
CREATE TABLE geometries (name varchar, geom geometry);
INSERT INTO geometries VALUES
('Point', 'POINT(0 0)'),
('Linestring', 'LINESTRING(0 0, 1 1, 2 1, 2 2)'),
('Polygon', 'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
('PolygonWithHole', 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))'),
('Collection', 'GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))');
SELECT name, ST_AsText(geom) FROM geometries;
ينشئ المثال أعلاه (CREATE) جدولًا ( geometries ) ثم يُدرج (INSERT) خمسة أشكال هندسية: نقطة، وخطًا، ومضلعًا، ومضلعًا به ثقب، ومجموعة. وأخيرًا تُحدَّد (SELECT) الصفوف المُدرجة وتُعرض في لوحة المخرجات.
9.2. جداول البيانات الوصفية (Metadata)¶
التزامًا بمواصفة Simple Features for SQL ( SFSQL )، يوفّر PostGIS جدولين لتتبع أنواع الأشكال الهندسية المتاحة في قاعدة بيانات معينة والإبلاغ عنها.
الجدول الأول،
spatial_ref_sys، يعرّف جميع الأنظمة المرجعية المكانية المعروفة لقاعدة البيانات، وسنصفه بمزيد من التفصيل لاحقًا.الجدول الثاني (وهو في الواقع عرض view)،
geometry_columns، يقدّم قائمة بجميع «المعالم» (المعرَّفة بأنها كائنات ذات سمات هندسية)، والتفاصيل الأساسية لتلك المعالم.
لنلقِ نظرة على الجدول geometry_columns في قاعدة بياناتنا. الصق هذا الأمر في أداة الاستعلام كما فعلت سابقًا:
SELECT * FROM geometry_columns;
توفّر
f_table_catalogوf_table_schemaوf_table_nameالاسم المؤهَّل الكامل لجدول المعالم الذي يحتوي على شكل هندسي معين. ولأن PostgreSQL لا يستخدم الكتالوجات، فإنf_table_catalogيكون فارغًا عادةً.f_geometry_columnهو اسم العمود الذي يحتوي على الشكل الهندسي؛ وبالنسبة لجداول المعالم التي تحتوي على عدة أعمدة هندسية، سيكون هناك سجل واحد لكل عمود.يحدد
coord_dimensionوsridعلى الترتيب أبعاد الشكل الهندسي (ثنائي أو ثلاثي أو رباعي الأبعاد) ومعرّف النظام المرجعي المكاني الذي يشير إلى الجدولspatial_ref_sys.يحدد العمود
typeنوع الشكل الهندسي كما هو موضح أدناه؛ وقد رأينا حتى الآن النوعين Point و Linestring.
من خلال الاستعلام عن هذا الجدول، تستطيع عملاء GIS ومكتباته معرفة ما يمكن توقعه عند استرجاع البيانات، وإجراء أي إسقاط أو معالجة أو عرض لازم دون الحاجة إلى فحص كل شكل هندسي.
ملاحظة
هل بعض جداول
nycلديك أو جميعها ليس لهاsridيساوي 26918؟ من السهل إصلاح ذلك بتحديث الجدول.
ALTER TABLE nyc_neighborhoods
ALTER COLUMN geom
TYPE Geometry(MultiPolygon, 26918)
USING ST_SetSRID(geom, 26918);
9.3. تمثيل كائنات العالم الحقيقي¶
تحدد مواصفة Simple Features for SQL ( SFSQL )، وهي المعيار التوجيهي الأصلي لتطوير PostGIS، كيفية تمثيل كائن من العالم الحقيقي. فبأخذ شكل متصل ورقمنته بدقة ثابتة، نحصل على تمثيل مقبول للكائن. كانت SFSQL تتعامل مع التمثيلات ثنائية الأبعاد فقط، ثم وسّع PostGIS ذلك ليشمل التمثيلات الثلاثية والرباعية الأبعاد؛ ومؤخرًا عرّفت مواصفة SQL-Multimedia Part 3 ( SQL/MM ) رسميًا تمثيلها الخاص.
يحتوي جدول المثال لدينا على مزيج من أنواع الأشكال الهندسية المختلفة. ويمكننا جمع معلومات عامة عن كل كائن باستخدام دوال تقرأ البيانات الوصفية للشكل الهندسي.
ST_GeometryType(geometry) تُعيد نوع الشكل الهندسي
ST_NDims(geometry) تُعيد عدد أبعاد الشكل الهندسي
ST_SRID(geometry) تُعيد رقم معرّف النظام المرجعي المكاني للشكل الهندسي
SELECT name, ST_GeometryType(geom), ST_NDims(geom), ST_SRID(geom)
FROM geometries;
name | st_geometrytype | st_ndims | st_srid
-----------------+-----------------------+----------+---------
Point | ST_Point | 2 | 0
Polygon | ST_Polygon | 2 | 0
PolygonWithHole | ST_Polygon | 2 | 0
Collection | ST_GeometryCollection | 2 | 0
Linestring | ST_LineString | 2 | 0
9.3.1. النقاط¶
تمثل النقطة المكانية موقعًا واحدًا على الأرض. وتُمثَّل هذه النقطة بإحداثي واحد (ثنائي أو ثلاثي أو رباعي الأبعاد). تُستخدم النقاط لتمثيل الكائنات عندما لا تكون التفاصيل الدقيقة، كالشكل والحجم، مهمة عند مقياس الرسم المستهدف. على سبيل المثال، يمكن وصف المدن على خريطة العالم بأنها نقاط، بينما قد تمثّل خريطةُ ولايةٍ واحدة المدنَ على شكل مضلعات.
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Point';
POINT(0 0)
من الدوال المكانية الخاصة بالعمل مع النقاط:
ST_X(geometry) تُعيد الإحداثي X
ST_Y(geometry) تُعيد الإحداثي Y
وهكذا يمكننا قراءة الإحداثيات من نقطة كما يلي:
SELECT ST_X(geom), ST_Y(geom)
FROM geometries
WHERE name = 'Point';
جدول محطات مترو مدينة نيويورك ( nyc_subway_stations ) مجموعة بيانات ممثلة بالنقاط. سيُعيد استعلام SQL التالي الشكل الهندسي المرتبط بنقطة واحدة (في العمود ST_AsText ).
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
LIMIT 1;
9.3.2. الخطوط (Linestrings)¶
الخط (linestring) مسار بين مواقع، ويتخذ شكل سلسلة مرتبة من نقطتين أو أكثر. تُمثَّل الطرق والأنهار عادةً على شكل خطوط. يُقال إن الخط مغلق إذا بدأ وانتهى عند النقطة نفسها، ويُقال إنه بسيط إذا لم يعبر نفسه أو يلامسها (باستثناء نقطتي طرفيه إذا كان مغلقًا). ويمكن أن يكون الخط مغلقًا و بسيطًا معًا.
حُمّلت شبكة شوارع نيويورك ( nyc_streets ) في وقت سابق من ورشة العمل. تحتوي مجموعة البيانات هذه على تفاصيل مثل الاسم والنوع. وقد يتكون شارع واحد في العالم الحقيقي من خطوط عديدة، يمثل كل منها مقطعًا من الطريق له سمات مختلفة.
سيُعيد استعلام SQL التالي الشكل الهندسي المرتبط بخط واحد (في العمود ST_AsText ).
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Linestring';
LINESTRING(0 0, 1 1, 2 1, 2 2)
من الدوال المكانية الخاصة بالعمل مع الخطوط:
ST_Length(geometry) تُعيد طول الخط
ST_StartPoint(geometry) تُعيد الإحداثي الأول على شكل نقطة
ST_EndPoint(geometry) تُعيد الإحداثي الأخير على شكل نقطة
ST_NPoints(geometry) تُعيد عدد الإحداثيات في الخط
إذن طول الخط لدينا هو:
SELECT ST_Length(geom)
FROM geometries
WHERE name = 'Linestring';
3.41421356237309
9.3.3. المضلعات¶
المضلع تمثيل لمساحة. تُمثَّل الحدود الخارجية للمضلع بحلقة (ring)، وهذه الحلقة خط مغلق وبسيط في آنٍ واحد كما عُرِّف أعلاه. كما تُمثَّل الثقوب داخل المضلع بحلقات أيضًا.
تُستخدم المضلعات لتمثيل الكائنات التي يكون حجمها وشكلها مهمين. فحدود المدن والحدائق ومساقط المباني والمسطحات المائية تُمثَّل جميعها عادةً كمضلعات عندما يكون مقياس الرسم كبيرًا بما يكفي لرؤية مساحتها. وقد تُمثَّل الطرق والأنهار أحيانًا كمضلعات.
سيُعيد استعلام SQL التالي الشكل الهندسي المرتبط بمضلع واحد (في العمود ST_AsText ).
SELECT ST_AsText(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
ملاحظة
بدلًا من استخدام العلامة = في الشرط WHERE، نستخدم المعامل LIKE لإجراء عملية مطابقة نصية. ربما اعتدت على الرمز ``*`` كحرف بدل (glob) لمطابقة الأنماط، لكن في SQL يُستخدم الرمز ``%``، مع المعامل LIKE لإخبار النظام بإجراء المطابقة بأحرف البدل.
POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))
POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))
المضلع الأول له حلقة واحدة فقط، أما الثاني فله «ثقب» داخلي. تتضمن معظم أنظمة الرسوميات مفهوم «المضلع»، لكن أنظمة GIS تنفرد نسبيًا بالسماح للمضلعات بأن تحتوي صراحةً على ثقوب.
من الدوال المكانية الخاصة بالعمل مع المضلعات:
ST_Area(geometry) تُعيد مساحة المضلعات
ST_NRings(geometry) تُعيد عدد الحلقات (عادةً 1، وأكثر إن وُجدت ثقوب)
ST_ExteriorRing(geometry) تُعيد الحلقة الخارجية على شكل خط
ST_InteriorRingN(geometry,n) تُعيد حلقة داخلية محددة على شكل خط
ST_Perimeter(geometry) تُعيد طول جميع الحلقات
يمكننا حساب مساحة المضلعات لدينا باستخدام دالة المساحة:
SELECT name, ST_Area(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
Polygon 1
PolygonWithHole 99
لاحظ أن مساحة المضلع ذي الثقب تساوي مساحة الغلاف الخارجي (مربع 10x10) مطروحًا منها مساحة الثقب (مربع 1x1).
9.3.4. المجموعات¶
هناك أربعة أنواع من المجموعات، تجمع عدة أشكال هندسية بسيطة في مجموعات.
MultiPoint، مجموعة من النقاط
MultiLineString، مجموعة من الخطوط
MultiPolygon، مجموعة من المضلعات
GeometryCollection، مجموعة غير متجانسة من أي أشكال هندسية (بما في ذلك مجموعات أخرى)
المجموعات مفهوم آخر يظهر في برمجيات GIS أكثر مما يظهر في برمجيات الرسوميات العامة. وهي مفيدة لنمذجة كائنات العالم الحقيقي مباشرةً ككائنات مكانية. على سبيل المثال، كيف ننمذج قطعة أرض يقسمها حق مرور؟ على شكل MultiPolygon، بجزء على كل جانب من حق المرور.
تحتوي المجموعة في مثالنا على مضلع ونقطة:
SELECT name, ST_AsText(geom)
FROM geometries
WHERE name = 'Collection';
GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))
من الدوال المكانية الخاصة بالعمل مع المجموعات:
ST_NumGeometries(geometry) تُعيد عدد الأجزاء في المجموعة
ST_GeometryN(geometry,n) تُعيد الجزء المحدد
ST_Area(geometry) تُعيد المساحة الكلية لجميع الأجزاء المضلعة
ST_Length(geometry) تُعيد الطول الكلي لجميع الأجزاء الخطية
9.4. إدخال الأشكال الهندسية وإخراجها¶
داخل قاعدة البيانات، تُخزَّن الأشكال الهندسية على القرص بتنسيق لا يستخدمه إلا برنامج PostGIS. ولكي تتمكن البرامج الخارجية من إدراج أشكال هندسية مفيدة واسترجاعها، يجب تحويلها إلى تنسيق تفهمه التطبيقات الأخرى. لحسن الحظ، يدعم PostGIS إخراج الأشكال الهندسية واستقبالها بعدد كبير من التنسيقات:
النص المعروف Well-known text ( WKT )
ST_GeomFromText(text, srid) تُعيد
geometryST_AsText(geometry) تُعيد
textST_AsEWKT(geometry) تُعيد
text
الثنائي المعروف Well-known binary ( WKB )
ST_GeomFromWKB(bytea) تُعيد
geometryST_AsBinary(geometry) تُعيد
byteaST_AsEWKB(geometry) تُعيد
bytea
لغة الترميز الجغرافية Geographic Mark-up Language ( GML )
ST_GeomFromGML(text) تُعيد
geometryST_AsGML(geometry) تُعيد
text
لغة الترميز Keyhole Mark-up Language ( KML )
ST_GeomFromKML(text) تُعيد
geometryST_AsKML(geometry) تُعيد
text
-
ST_AsGeoJSON(geometry) تُعيد
text
الرسوميات المتجهية القابلة للتحجيم Scalable Vector Graphics ( SVG )
ST_AsSVG(geometry) تُعيد
text
الاستخدام الأكثر شيوعًا للدالة البانية (constructor) هو تحويل التمثيل النصي لشكل هندسي إلى تمثيل داخلي:
لاحظ أنه بالإضافة إلى المعامل النصي الذي يحمل تمثيل الشكل الهندسي، لدينا أيضًا معامل رقمي يحدد SRID الخاص بالشكل الهندسي.
يعرض استعلام SQL التالي مثالًا على تمثيل WKB (استدعاء encode() مطلوب لتحويل المخرجات الثنائية إلى صيغة ASCII لطباعتها):
SELECT encode(
ST_AsBinary(ST_GeometryFromText('LINESTRING(0 0,1 0)')),
'hex');
01020000000200000000000000000000000000000000000000000000000000f03f0000000000000000
لأغراض ورشة العمل هذه، سنواصل استخدام WKT لضمان قدرتك على قراءة الأشكال الهندسية التي نعرضها وفهمها. أما في معظم العمليات الفعلية، مثل عرض البيانات في تطبيق GIS، أو نقل البيانات إلى خدمة ويب، أو معالجة البيانات عن بُعد، فإن WKB هو التنسيق المفضّل.
بما أن WKT و WKB عُرِّفا في مواصفة SFSQL، فإنهما لا يتعاملان مع الأشكال الهندسية الثلاثية أو الرباعية الأبعاد. ولهذه الحالات عرّف PostGIS تنسيقي Extended Well Known Text (EWKT) و Extended Well Known Binary (EWKB)، اللذين يوفران إمكانات التنسيق نفسها في WKT و WKB مع إضافة الأبعاد.
إليك مثالًا على خط ثلاثي الأبعاد بصيغة WKT:
SELECT ST_AsText(ST_GeometryFromText('LINESTRING(0 0 0,1 0 0,1 1 2)'));
LINESTRING Z (0 0 0,1 0 0,1 1 2)
لاحظ أن التمثيل النصي يتغير! وذلك لأن روتين إدخال النص في PostGIS متساهل فيما يستقبله، إذ يستقبل
EWKB المرمَّز بالنظام الست عشري،
النص المعروف الموسَّع (extended well-known text)، و
النص المعروف وفق معيار ISO.
أما من جهة الإخراج، فإن الدالة ST_AsText متحفظة، ولا تُخرج إلا النص المعروف وفق معيار ISO.
بالإضافة إلى الدالة ST_GeometryFromText، هناك طرق أخرى كثيرة لإنشاء أشكال هندسية من النص المعروف أو من مدخلات بتنسيق مشابه:
-- Using ST_GeomFromText with the SRID parameter
SELECT ST_GeomFromText('POINT(2 2)',4326);
-- Using ST_GeomFromText without the SRID parameter
SELECT ST_SetSRID(ST_GeomFromText('POINT(2 2)'),4326);
-- Using a ST_Make* function
SELECT ST_SetSRID(ST_MakePoint(2, 2), 4326);
-- Using PostgreSQL casting syntax and ISO WKT
SELECT ST_SetSRID('POINT(2 2)'::geometry, 4326);
-- Using PostgreSQL casting syntax and extended WKT
SELECT 'SRID=4326;POINT(2 2)'::geometry;
بالإضافة إلى دوال الإخراج للصيغ المختلفة (WKT، WKB، GML، KML، JSON، SVG)، يمتلك PostGIS أيضًا دوال استقبال لأربع منها (WKT، WKB، GML، KML). تستخدم معظم التطبيقات دوال إنشاء الأشكال الهندسية من WKT أو WKB، لكن الدوال الأخرى تعمل أيضًا. إليك مثالًا يستقبل GML ويُخرج JSON:
SELECT ST_AsGeoJSON(ST_GeomFromGML('<gml:Point><gml:coordinates>1,1</gml:coordinates></gml:Point>'));
9.5. التحويل من النص¶
سلاسل WKT التي رأيناها حتى الآن كانت من النوع 'text'، وكنا نحوّلها إلى النوع 'geometry' باستخدام دوال PostGIS مثل ST_GeomFromText().
يتضمن PostgreSQL صياغة مختصرة تتيح تحويل البيانات من نوع إلى آخر، وهي صياغة التحويل (casting)، oldata::newtype. فعلى سبيل المثال، يحوّل تعليمة SQL هذه عددًا من النوع double إلى سلسلة نصية.
SELECT 0.9::text;
وفي مثال أقل بساطة، يحوّل SQL هذا سلسلة WKT إلى geometry:
SELECT 'POINT(0 0)'::geometry;
ملاحظة جديرة بالانتباه عند استخدام التحويل لإنشاء الأشكال الهندسية: ما لم تحدد SRID، ستحصل على شكل هندسي ذي SRID غير معروف. يمكنك تحديد SRID باستخدام الصيغة «الموسّعة» من النص المعروف، التي تتضمن كتلة SRID في البداية:
SELECT 'SRID=4326;POINT(0 0)'::geometry;
من الشائع جدًا استخدام صيغة التحويل عند العمل مع WKT، وكذلك مع أعمدة geometry و geography (انظر الإحداثيات الجغرافية (Geography) ).
9.6. قائمة الدوال¶
ST_Area: تُعيد مساحة السطح إذا كان مضلعًا أو مضلعًا متعددًا. بالنسبة للنوع "geometry" تكون المساحة بوحدات SRID، وبالنسبة للنوع "geography" تكون بالمتر المربع.
ST_AsText: تُعيد تمثيل Well-Known Text (WKT) للشكل الهندسي geometry/geography دون البيانات الوصفية لـ SRID.
ST_AsBinary: تُعيد تمثيل Well-Known Binary (WKB) للشكل الهندسي geometry/geography دون البيانات الوصفية لـ SRID.
ST_EndPoint: تُعيد النقطة الأخيرة من شكل هندسي LINESTRING على شكل POINT.
ST_AsEWKB: تُعيد تمثيل Well-Known Binary (WKB) للشكل الهندسي مع البيانات الوصفية لـ SRID.
ST_AsEWKT: تُعيد تمثيل Well-Known Text (WKT) للشكل الهندسي مع البيانات الوصفية لـ SRID.
ST_AsGeoJSON: تُعيد الشكل الهندسي كعنصر GeoJSON.
ST_AsGML: تُعيد الشكل الهندسي كعنصر GML بالإصدار 2 أو 3.
ST_AsKML: تُعيد الشكل الهندسي كعنصر KML. لها عدة صيغ. الإصدار الافتراضي=2، والدقة الافتراضية=15.
ST_AsSVG: تُعيد الشكل الهندسي كبيانات مسار SVG عند تمرير كائن geometry أو geography.
ST_ExteriorRing: تُعيد خطًا يمثل الحلقة الخارجية لشكل هندسي من النوع POLYGON. تُعيد NULL إذا لم يكن الشكل الهندسي مضلعًا. لا تعمل مع MULTIPOLYGON
ST_GeometryN: تُعيد الشكل الهندسي ذا الترتيب N (بدءًا من 1) إذا كان الشكل الهندسي من النوع GEOMETRYCOLLECTION أو MULTIPOINT أو MULTILINESTRING أو MULTICURVE أو MULTIPOLYGON. وإلا تُعيد NULL.
ST_GeomFromGML: تأخذ كمُدخل تمثيل GML للشكل الهندسي وتُخرج كائن geometry في PostGIS.
ST_GeomFromKML: تأخذ كمُدخل تمثيل KML للشكل الهندسي وتُخرج كائن geometry في PostGIS
ST_GeomFromText: تُعيد قيمة ST_Geometry محددة من تمثيل Well-Known Text (WKT).
ST_GeomFromWKB: تنشئ نسخة من شكل هندسي من تمثيل Well-Known Binary (WKB) ومن SRID اختياري.
ST_GeometryType: تُعيد نوع الشكل الهندسي لقيمة ST_Geometry.
ST_InteriorRingN: تُعيد الحلقة الخطية الداخلية ذات الترتيب N لشكل هندسي مضلع. تُعيد NULL إذا لم يكن الشكل الهندسي مضلعًا أو كانت N خارج النطاق.
ST_Length: تُعيد الطول ثنائي الأبعاد للشكل الهندسي إذا كان خطًا أو خطًا متعددًا. يكون الطول لـ geometry بوحدات النظام المرجعي المكاني، ولـ geography بالأمتار (الشكل الإهليلجي الافتراضي)
ST_NDims: تُعيد بُعد الإحداثيات للشكل الهندسي كعدد صحيح صغير. القيم هي: 2 أو 3 أو 4.
ST_NPoints: تُعيد عدد النقاط (الرؤوس) في شكل هندسي.
ST_NRings: إذا كان الشكل الهندسي مضلعًا أو مضلعًا متعددًا، تُعيد عدد الحلقات.
ST_NumGeometries: إذا كان الشكل الهندسي من النوع GEOMETRYCOLLECTION (أو MULTI*) تُعيد عدد الأشكال الهندسية، وإلا تُعيد NULL.
ST_Perimeter: تُعيد قياس طول حدود قيمة ST_Surface أو ST_MultiSurface. (Polygon، Multipolygon)
ST_SRID: تُعيد معرّف النظام المرجعي المكاني لقيمة ST_Geometry كما هو معرَّف في الجدول spatial_ref_sys.
ST_StartPoint: تُعيد النقطة الأولى من شكل هندسي LINESTRING على شكل POINT.
ST_X: تُعيد الإحداثي X للنقطة، أو NULL إن لم يكن متاحًا. يجب أن يكون المُدخل نقطة.
ST_Y: تُعيد الإحداثي Y للنقطة، أو NULL إن لم يكن متاحًا. يجب أن يكون المُدخل نقطة.