16. إسقاط البيانات

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

سبق أن صادفنا الإسقاطات عندما حمّلنا بيانات nyc. (تذكّر ذلك الـ SRID 26918 المزعج). لكنك تحتاج أحيانًا إلى التحويل وإعادة الإسقاط بين الأنظمة المرجعية المكانية. يتضمن PostGIS دعمًا مدمجًا لتغيير إسقاط البيانات باستخدام الدالة ST_Transform(geometry, srid). ولإدارة معرّفات الأنظمة المرجعية المكانية للأشكال الهندسية، يوفر PostGIS الدالتين ST_SRID(geometry) و ST_SetSRID(geometry, srid).

يمكننا التأكد من SRID بياناتنا باستخدام الدالة ST_SRID:

SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
26918

وما تعريف "26918"؟ كما رأينا في "قسم تحميل البيانات"، يوجد التعريف في الجدول spatial_ref_sys. بل يوجد فيه تعريفان اثنان. تعريف "النص المعروف" (WKT) موجود في العمود srtext، وهناك تعريف ثانٍ بصيغة "proj.4" في العمود proj4text.

SELECT * FROM spatial_ref_sys WHERE srid = 26918;

سيحاول محرك إعادة الإسقاط في PostGIS إيجاد أفضل إسقاط من الجدول spatial_ref_sys:

  • auth_name / auth_srid إذا وجدت مكتبة proj "اسم جهة" (authority name) و"srid الجهة" (authority srid) صالحين في فهرسها الداخلي، فستستخدمهما لتوليد تعريف الإسقاط.

  • srtext إذا تمكنت proj من تحليل srtext وتكوين كائن تعريف منه، فستستخدمه.

  • proj4text أخيرًا، ستحاول proj معالجة proj4text.

يعني كل هذا التكرار أن كل ما تحتاجه لإنشاء إسقاط جديد في PostGIS هو سلسلة srtext صالحة أو سلسلة proj4text صالحة. وجميع أزواج اسم الجهة/الرمز الشائعة محمّلة في الجدول افتراضيًا.

إذا كان لديك الخيار عند إنشاء إسقاط مخصص، فاملأ العمود srtext، لأن هذا العمود تستخدمه أيضًا برامج خارجية مثل GeoServer و QGIS و FME وغيرها.

16.1. مقارنة البيانات

يحدد الإحداثي وSRID معًا موقعًا على الكرة الأرضية. فبدون SRID يكون الإحداثي مجرد مفهوم مجرد. ويُعرَّف المستوى الإحداثي "الديكارتي" بأنه نظام إحداثيات "مسطح" موضوع على سطح الأرض. ولأن دوال PostGIS تعمل على مستوى كهذا، تتطلب عمليات المقارنة أن يكون الشكلان الهندسيان ممثّلين بقيمة SRID نفسها.

إذا مرّرت أشكالًا هندسية بقيم SRID مختلفة فستحصل ببساطة على خطأ:

SELECT ST_Equals(
         ST_GeomFromText('POINT(0 0)', 4326),
         ST_GeomFromText('POINT(0 0)', 26918)
         );
ERROR:  ST_Equals: Operation on mixed SRID geometries (Point, 4326) != (Point, 26918)

ملاحظة

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

16.2. تحويل البيانات

إذا عدنا إلى تعريف proj4 الخاص بـ SRID 26918، فسنرى أن إسقاط العمل لدينا هو UTM (Universal Transverse Mercator) للنطاق 18، ووحدة القياس فيه هي المتر.

SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
PROJCS["NAD83 / UTM zone 18N",
  GEOGCS["NAD83",
    DATUM["North_American_Datum_1983",
      SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],
      TOWGS84[0,0,0,0,0,0,0],
      AUTHORITY["EPSG","6269"]],
    PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],
    AUTHORITY["EPSG","4269"]],
  PROJECTION["Transverse_Mercator"],
  PARAMETER["latitude_of_origin",0],
  PARAMETER["central_meridian",-75],
  PARAMETER["scale_factor",0.9996],
  PARAMETER["false_easting",500000],
  PARAMETER["false_northing",0],
  UNIT["metre",1,AUTHORITY["EPSG","9001"]],
  AXIS["Easting",EAST],AXIS["Northing",NORTH],
  AUTHORITY["EPSG","26918"]]

لنحوّل بعض البيانات من إسقاط العمل لدينا إلى إحداثيات جغرافية، وتُعرف أيضًا بـ "خط الطول/خط العرض".

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

أكثر قيم SRID شيوعًا للإحداثيات الجغرافية هي 4326، وتقابل "خط الطول/خط العرض على الشكل الإهليلجي WGS84". يمكنك الاطلاع على التعريف هنا:

يمكنك أيضًا جلب التعريفات من الجدول spatial_ref_sys:

SELECT srtext FROM spatial_ref_sys WHERE srid = 4326;
GEOGCS["WGS 84",
  DATUM["WGS_1984",
    SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],
    AUTHORITY["EPSG","6326"]],
  PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
  UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],
  AUTHORITY["EPSG","4326"]]

لنحوّل إحداثيات محطة المترو 'Broad St' إلى إحداثيات جغرافية:

SELECT ST_AsText(ST_Transform(geom,4326))
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(-74.01067146887341 40.70710481558761)

إذا حمّلت بيانات أو أنشأت شكلًا هندسيًا جديدًا دون تحديد SRID، فستكون قيمة SRID هي 0. تذكّر في الأشكال الهندسية أننا لم نحدد SRID عند إنشاء الجدول geometries. إذا استعلمنا قاعدة بياناتنا، فيُتوقع أن تكون قيمة SRID لجميع جداول nyc_ هي 26918، بينما أخذ الجدول geometries القيمة الافتراضية 0.

لعرض قيمة SRID المعيّنة لجدول ما، استعلم الجدول geometry_columns في قاعدة البيانات.

SELECT f_table_name AS name, srid
FROM geometry_columns;
        name         | srid
---------------------+-------
 nyc_census_blocks   | 26918
 nyc_homicides       | 26918
 nyc_neighborhoods   | 26918
 nyc_streets         | 26918
 nyc_subway_stations | 26918
 geometries          |     0

لكن إذا كنت تعرف ما يُفترض أن تكون عليه قيمة SRID للإحداثيات، فيمكنك تعيينها لاحقًا باستخدام ST_SetSRID على الشكل الهندسي. وبعدها ستتمكن من تحويل الشكل الهندسي إلى أنظمة أخرى.

SELECT ST_AsText(
    ST_Transform(
      ST_SetSRID(geom,26918),
      4326)
    )
  FROM geometries;

16.3. قائمة الدوال

ST_AsText: تُرجع تمثيل النص المعروف (WKT) للشكل الهندسي (geometry/geography) دون بيانات SRID الوصفية.

ST_SetSRID(geometry, srid): تعيّن قيمة SRID لشكل هندسي إلى قيمة عددية صحيحة محددة.

ST_SRID(geometry): تُرجع معرّف النظام المرجعي المكاني لـ ST_Geometry كما هو معرّف في الجدول spatial_ref_sys.

ST_Transform(geometry, srid): تُرجع شكلًا هندسيًا جديدًا حُوّلت إحداثياته إلى SRID المشار إليه بالمعامل العددي الصحيح.