GISarabia.org
PostGIS 3.6 · Official Manual · ترجمة عربية

فصل 10. إدارة بيانات الرستر واستعلاماتها وتطبيقاتها

الصفحة الأصلية بالإنجليزية postgis.net ↗

فصل 10. إدارة بيانات الرستر واستعلاماتها وتطبيقاتها

10.1. تحميل الرستر وإنشاؤه

في معظم حالات الاستخدام، ستُنشئ رستر PostGIS بتحميل ملفات رستر موجودة باستخدام مُحمِّل الرستر المرفق raster2pgsql.

10.1.1. استخدام raster2pgsql لتحميل الرستر

raster2pgsql ملف تنفيذي لتحميل الرستر يحوّل صيغ الرستر التي تدعمها GDAL إلى SQL مناسب للتحميل في جدول رستر PostGIS. وهو قادر على تحميل مجلدات من ملفات الرستر، وكذلك إنشاء عروض مصغّرة (overviews) للرستر.

بما أن raster2pgsql يُترجَم غالبًا كجزء من PostGIS (ما لم تترجم مكتبة GDAL الخاصة بك)، فستكون أنواع الرستر التي يدعمها الملف التنفيذي هي نفسها المترجَمة في مكتبة GDAL التابعة. للحصول على قائمة بأنواع الرستر التي يدعمها raster2pgsql لديك، استخدم الخيار -G.

[ملاحظة]

عند إنشاء عروض مصغّرة بمُعامل محدد من مجموعة رستر متحاذية، قد لا تتحاذى العروض المصغّرة. زُر http://trac.osgeo.org/postgis/ticket/1764 للاطلاع على مثال لا تتحاذى فيه العروض المصغّرة.

10.1.1.1. مثال على الاستخدام

قد تبدو جلسة نموذجية تستخدم المُحمِّل لإنشاء ملف إدخال ورفعه مقسّمًا إلى بلاطات بحجم 100x100 على النحو الآتي:

# -s use srid 4326
# -I create spatial index
# -C use standard raster constraints
# -M vacuum analyze after load
# *.tif load all these files
# -F include a filename column in the raster table
# -t tile the output 100x100
# public.demelevation load into this table
raster2pgsql -s 4326 -I -C -M -F -t 100x100 *.tif public.demelevation 
> elev.sql

# -d connect to this database
# -f read this file after connecting
psql -d gisdb -f elev.sql
[ملاحظة]

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

يمكن إجراء التحويل والرفع في خطوة واحدة باستخدام أنابيب UNIX:

raster2pgsql -s 4326 -I -C -M *.tif -F -t 100x100 public.demelevation | psql -d gisdb

تحميل بلاطات رستر جوية بالأمتار وفق نظام Massachusetts state plane إلى مخطط يُسمى aerial، وإنشاء عرض كامل وجداول عروض مصغّرة بالمستويين 2 و4، واستخدام وضع النسخ (copy) للإدراج (دون ملف وسيط، مباشرة إلى قاعدة البيانات)، و-e لعدم فرض تنفيذ كل شيء في معاملة (مفيد إذا أردت رؤية البيانات في الجداول فورًا دون انتظار). تقسيم الرستر إلى بلاطات بحجم 128x128 بكسل وتطبيق قيود الرستر. استخدام وضع النسخ بدلًا من الإدراج في الجدول. (-F) تضمين حقل يُسمى filename لحفظ اسم الملف الذي قُطعت منه البلاطات.

raster2pgsql -I -C -e -Y -F -s 26986 -t 128x128  -l 2,4 bostonaerials2008/*.jpg aerials.boston | psql -U postgres -d gisdb -h localhost -p 5432
--get a list of raster types supported:
raster2pgsql -G

يُخرج الأمر -G قائمة تشبه

Available GDAL raster formats:
  Virtual Raster
  GeoTIFF
  National Imagery Transmission Format
  Raster Product Format TOC format
  ECRG TOC format
  Erdas Imagine Images (.img)
  CEOS SAR Image
  CEOS Image
  ...
  Arc/Info Export E00 GRID
  ZMap Plus Grid
  NOAA NGS Geoid Height Grids

10.1.1.2. خيارات raster2pgsql

-?

عرض شاشة المساعدة. ستُعرض المساعدة أيضًا إذا لم تمرر أي وسائط.

-G

طباعة صيغ الرستر المدعومة.

(c|a|d|p) هذه خيارات متنافية:

-c

إنشاء جدول جديد وملؤه بالرستر، هذا هو الوضع الافتراضي

-a

إلحاق الرستر بجدول موجود.

-d

حذف الجدول وإنشاء جدول جديد وملؤه بالرستر

-p

وضع التحضير، إنشاء الجدول فقط.

معالجة الرستر: تطبيق القيود للتسجيل السليم في فهارس الرستر

-C

تطبيق قيود الرستر -- srid وحجم البكسل وغيرها لضمان تسجيل الرستر تسجيلًا سليمًا في العرض raster_columns.

-x

تعطيل ضبط قيد الامتداد الأقصى. لا يُطبَّق إلا إذا استُخدم الخيار -C أيضًا.

-r

ضبط القيود (التفرد المكاني وبلاطات التغطية) للتقسيم المنتظم إلى كتل. لا يُطبَّق إلا إذا استُخدم الخيار -C أيضًا.

معالجة الرستر: مُعاملات اختيارية تُستخدم للتعامل مع مجموعة بيانات الرستر المُدخلة

-s <SRID>

تعيين SRID محدد للرستر الناتج. إذا لم يُحدَّد أو كان صفرًا، فستُفحص البيانات الوصفية للرستر لتحديد SRID مناسب.

-b BAND

فهرس (يبدأ من 1) النطاق المراد استخراجه من الرستر. لأكثر من فهرس نطاق، افصل بينها بفاصلة (,). إذا لم يُحدَّد، فستُستخرج جميع نطاقات الرستر.

-t TILE_SIZE

تقطيع الرستر إلى بلاطات تُدرج كل منها في صف من الجدول. يُعبَّر عن TILE_SIZE بالصيغة WIDTHxHEIGHT أو يُضبط على القيمة "auto" للسماح للمُحمِّل بحساب حجم بلاطة مناسب باستخدام الرستر الأول وتطبيقه على جميع الرستر.

-P

حشو البلاطات الواقعة في أقصى اليمين وأقصى الأسفل لضمان أن تكون لجميع البلاطات العرض والارتفاع نفسيهما.

-R, --register

تسجيل الرستر كرستر في نظام الملفات (out-db).

تُخزَّن في قاعدة البيانات البيانات الوصفية للرستر ومسار موقعه فقط (وليس البكسلات).

-l OVERVIEW_FACTOR

إنشاء عرض مصغّر (overview) للرستر. لأكثر من مُعامل، افصل بينها بفاصلة (,). يتبع اسم جدول العرض المصغّر النمط o_overview factor_table، حيث overview factor عنصر نائب لمُعامل العرض المصغّر العددي، ويُستبدل table باسم الجدول الأساسي. يُخزَّن العرض المصغّر المُنشأ في قاعدة البيانات ولا يتأثر بالخيار -R. لاحظ أن ملف sql المُولَّد سيحتوي على الجدول الرئيسي وجداول العروض المصغّرة معًا.

-N NODATA

قيمة NODATA المستخدمة للنطاقات التي لا تملك قيمة NODATA.

مُعاملات اختيارية تُستخدم للتعامل مع كائنات قاعدة البيانات

-f COLUMN

تحديد اسم عمود الرستر الهدف، والقيمة الافتراضية 'rast'

-F

إضافة عمود يحمل اسم الملف

-n COLUMN

تحديد اسم عمود اسم الملف. يستلزم -F.

-q

إحاطة معرّفات PostgreSQL بعلامات اقتباس.

-I

إنشاء فهرس GiST على عمود الرستر.

-M

تنفيذ vacuum analyze على جدول الرستر.

-k

الإبقاء على البلاطات الفارغة وتخطي فحوص قيمة NODATA لكل نطاق رستر. لاحظ أنك توفر وقت الفحص، لكن قد ينتهي بك الأمر بعدد أكبر بكثير من الصفوف عديمة الفائدة في قاعدة بياناتك، ولا تُعلَّم تلك الصفوف كبلاطات فارغة.

-T tablespace

تحديد مساحة الجداول (tablespace) للجدول الجديد. لاحظ أن الفهارس (بما فيها المفتاح الأساسي) ستظل تستخدم مساحة الجداول الافتراضية ما لم يُستخدم الخيار -X أيضًا.

-X tablespace

تحديد مساحة الجداول (tablespace) للفهرس الجديد للجدول. ينطبق ذلك على المفتاح الأساسي، وعلى الفهرس المكاني إذا استُخدم الخيار -I.

-Y max_rows_per_copy=50

استخدام تعليمات copy بدلًا من تعليمات insert. ويمكن اختياريًا تحديد max_rows_per_copy؛ والقيمة الافتراضية 50 عند عدم التحديد.

-e

تنفيذ كل تعليمة على حدة، دون استخدام معاملة.

-E ENDIAN

التحكم في ترتيب البايتات (endianness) للإخراج الثنائي المُولَّد للرستر؛ حدد 0 لـ XDR و1 لـ NDR (الافتراضي)؛ لا يُدعم حاليًا سوى إخراج NDR

-V version

تحديد إصدار صيغة الإخراج. القيمة الافتراضية 0. ولا يُدعم في الوقت الحالي سوى 0.

10.1.2. إنشاء الرستر باستخدام دوال الرستر في PostGIS

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

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

    CREATE TABLE myrasters(rid serial primary key, rast raster);
  2. توجد دوال كثيرة تساعد على تحقيق هذا الهدف. إذا كنت تُنشئ رستر غير مشتق من رستر آخر، فستبدأ بـ ST_MakeEmptyRaster، متبوعة بـ ST_AddBand

    يمكنك أيضًا إنشاء رستر من الأشكال الهندسية. ولتحقيق ذلك ستستخدم ST_AsRaster ربما مصحوبة بدوال أخرى مثل ST_Union أو ST_MapAlgebraFct أو أي من عائلة دوال جبر الخرائط الأخرى.

    توجد خيارات أكثر بكثير لإنشاء جداول رستر جديدة من جداول موجودة. على سبيل المثال، يمكنك إنشاء جدول رستر بإسقاط مختلف عن جدول موجود باستخدام ST_Transform

  3. بعد الانتهاء من الملء الأولي لجدولك، ستحتاج إلى إنشاء فهرس مكاني على عمود الرستر بشيء مثل:

    CREATE INDEX myrasters_rast_st_convexhull_idx ON myrasters USING gist( ST_ConvexHull(rast) );

    لاحظ استخدام ST_ConvexHull لأن معظم عوامل الرستر مبنية على الغلاف المحدب للرستر.

    [ملاحظة]

    كانت إصدارات رستر PostGIS السابقة للإصدار 2.0 مبنية على الغلاف بدلًا من الغلاف المحدب. ولكي تعمل الفهارس المكانية بشكل سليم، ستحتاج إلى حذفها واستبدالها بفهرس مبني على الغلاف المحدب.

  4. تطبيق قيود الرستر باستخدام AddRasterConstraints

10.1.3. استخدام رستر سحابي "out db"

تستخدم الأداة raster2pgsql مكتبة GDAL للوصول إلى بيانات الرستر، ويمكنها الاستفادة من ميزة أساسية في GDAL: القدرة على القراءة من رستر مخزّن عن بُعد في "مخازن الكائنات" السحابية (مثل AWS S3 وGoogle Cloud Storage).

يتطلب الاستخدام الفعال للرستر المخزّن سحابيًا استخدام صيغة "مُحسَّنة للسحابة". وأشهرها وأوسعها استخدامًا صيغة "GeoTIFF المُحسَّنة للسحابة". أما استخدام صيغة غير سحابية، مثل JPEG أو TIFF غير مقسّم إلى بلاطات، فسيؤدي إلى أداء ضعيف جدًا، لأن النظام سيضطر إلى تنزيل الرستر بأكمله في كل مرة يحتاج فيها إلى الوصول إلى جزء منه.

أولًا، حمّل الرستر إلى التخزين السحابي الذي تختاره. وبعد تحميله سيكون لديك URI للوصول إليه، إما URI من نوع "http"، أو أحيانًا URI خاص بالخدمة (مثل "s3://bucket/object"). وللوصول إلى الحاويات غير العامة، ستحتاج إلى تقديم خيارات إعداد GDAL لمصادقة اتصالك. لاحظ أن هذا الأمر يقرأ من الرستر السحابي ويكتب إلى قاعدة البيانات.

AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxx \
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
raster2pgsql \
  -s 990000 \
  -t 256x256 \
  -I \
  -R \
  /vsis3/your.bucket.com/your_file.tif \
  your_table \
  | psql your_db

بعد تحميل الجدول، تحتاج إلى منح قاعدة البيانات إذنًا بالقراءة من الرستر البعيد، بضبط إعدادين: postgis.enable_outdb_rasters وpostgis.gdal_enabled_drivers.

SET postgis.enable_outdb_rasters = true;
SET postgis.gdal_enabled_drivers TO 'ENABLE_ALL';
    

لجعل التغييرات دائمة، اضبطها مباشرة على قاعدة بياناتك. ستحتاج إلى إعادة الاتصال حتى تسري الإعدادات الجديدة.

ALTER DATABASE your_db SET postgis.enable_outdb_rasters = true;
ALTER DATABASE your_db SET postgis.gdal_enabled_drivers TO 'ENABLE_ALL';
    

بالنسبة إلى الرستر غير العام، قد تضطر إلى تقديم مفاتيح وصول للقراءة من الرستر السحابي. ويمكن ضبط المفاتيح نفسها التي استخدمتها في استدعاء raster2pgsql لاستخدامها داخل قاعدة البيانات، عبر الإعداد postgis.gdal_vsi_options. لاحظ أنه يمكن ضبط عدة خيارات بفصل أزواج key=value بمسافات.

SET postgis.gdal_vsi_options = 'AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

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

10.2. فهارس الرستر

يأتي PostGIS مرفقًا بعرضين (view) لفهرسة الرستر. يستخدم كلا العرضين المعلومات المضمَّنة في قيود جداول الرستر. ونتيجة لذلك تظل عروض الفهرسة متسقة دائمًا مع بيانات الرستر في الجداول لأن القيود مُطبَّقة.

  1. raster_columns يُفهرس هذا العرض جميع أعمدة جداول الرستر في قاعدة بياناتك.

  2. raster_overviews يُفهرس هذا العرض جميع أعمدة جداول الرستر في قاعدة بياناتك التي تعمل كعروض مصغّرة لجدول أدق تفصيلًا. وتُولَّد جداول من هذا النوع عند استخدام الخيار -l أثناء التحميل.

10.2.1. فهرس أعمدة الرستر

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

إذا لم تُنشئ جداولك باستخدام المُحمِّل أو نسيت تحديد الخيار -C أثناء التحميل، يمكنك فرض القيود لاحقًا باستخدام AddRasterConstraints حتى يسجّل الفهرس raster_columns المعلومات المشتركة عن بلاطات الرستر لديك.

  • r_table_catalog قاعدة البيانات التي يوجد فيها الجدول. ستكون دائمًا قاعدة البيانات الحالية.

  • r_table_schema مخطط قاعدة البيانات الذي ينتمي إليه جدول الرستر.

  • r_table_name جدول الرستر

  • r_raster_column العمود في الجدول r_table_name الذي من النوع raster. لا شيء في PostGIS يمنعك من امتلاك عدة أعمدة رستر في الجدول الواحد، لذا من الممكن أن يُدرج جدول رستر عدة مرات بعمود رستر مختلف في كل مرة.

  • srid معرّف النظام المرجعي المكاني للرستر. ينبغي أن يكون مُدخلًا في قسم 4.5, “الأنظمة المرجعية المكانية”.

  • scale_x مقياس التحويل بين الإحداثيات المكانية الهندسية والبكسل. لا يتوفر إلا إذا كانت لجميع البلاطات في عمود الرستر القيمة نفسها لـ scale_x وكان هذا القيد مُطبَّقًا. راجع ST_ScaleX لمزيد من التفاصيل.

  • scale_y مقياس التحويل بين الإحداثيات المكانية الهندسية والبكسل. لا يتوفر إلا إذا كانت لجميع البلاطات في عمود الرستر القيمة نفسها لـ scale_y وكان قيد scale_y مُطبَّقًا. راجع ST_ScaleY لمزيد من التفاصيل.

  • blocksize_x عرض (عدد البكسلات أفقيًا) كل بلاطة رستر. راجع ST_Width لمزيد من التفاصيل.

  • blocksize_y عرض (عدد البكسلات رأسيًا) كل بلاطة رستر. راجع ST_Height لمزيد من التفاصيل.

  • same_alignment قيمة منطقية تكون true إذا كانت لجميع بلاطات الرستر المحاذاة نفسها. راجع ST_SameAlignment لمزيد من التفاصيل.

  • regular_blocking إذا كان لعمود الرستر قيدا التفرد المكاني وبلاطات التغطية، فستكون القيمة TRUE. وإلا فستكون FALSE.

  • num_bands عدد النطاقات في كل بلاطة من مجموعة الرستر لديك. وهي المعلومات نفسها التي يوفرها ST_NumBands

  • pixel_types مصفوفة تحدد نوع البكسل لكل نطاق. سيكون عدد عناصر هذه المصفوفة مساويًا لعدد النطاقات. وأنواع البكسل واحدة مما يلي المعرّف في ST_BandPixelType.

  • nodata_values مصفوفة من الأعداد مزدوجة الدقة تدل على nodata_value لكل نطاق. سيكون عدد عناصر هذه المصفوفة مساويًا لعدد النطاقات. تحدد هذه الأعداد قيمة البكسل لكل نطاق التي ينبغي تجاهلها في معظم العمليات. وهي معلومات مشابهة لما يوفره ST_BandNoDataValue.

  • out_db مصفوفة من الأعلام المنطقية تُبيّن ما إذا كانت بيانات نطاقات الرستر محفوظة خارج قاعدة البيانات. سيكون عدد عناصر هذه المصفوفة مساويًا لعدد النطاقات.

  • extent هذا هو امتداد جميع صفوف الرستر في مجموعة الرستر لديك. إذا كنت تخطط لتحميل مزيد من البيانات التي ستغيّر امتداد المجموعة، فستحتاج إلى تشغيل الدالة DropRasterConstraints قبل التحميل ثم إعادة تطبيق القيود باستخدام AddRasterConstraints بعد التحميل.

  • spatial_index قيمة منطقية تكون true إذا كان لعمود الرستر فهرس مكاني.

10.2.2. العروض المصغّرة للرستر

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

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

[ملاحظة]

لا تُكرّر المعلومات في raster_overviews المعلومات الموجودة في raster_columns. إذا احتجت إلى المعلومات المتعلقة بجدول عرض مصغّر الموجودة في raster_columns، يمكنك ربط raster_overviews وraster_columns معًا للحصول على المجموعة الكاملة من المعلومات التي تحتاجها.

السببان الرئيسيان للعروض المصغّرة هما:

  1. تمثيل منخفض الدقة للجداول الأساسية يُستخدم عادةً للتصغير السريع للخرائط.

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

يحتوي الفهرس raster_overviews على أعمدة المعلومات التالية.

  • o_table_catalog قاعدة البيانات التي يوجد فيها جدول النظرة العامة. ستكون دائمًا قاعدة البيانات الحالية.

  • o_table_schema مخطط (schema) قاعدة البيانات الذي ينتمي إليه جدول رستر النظرة العامة.

  • o_table_name اسم جدول النظرة العامة للرستر

  • o_raster_column عمود الرستر في جدول النظرة العامة.

  • r_table_catalog قاعدة البيانات التي يوجد فيها جدول الرستر الذي تخدمه هذه النظرة العامة. ستكون دائمًا قاعدة البيانات الحالية.

  • r_table_schema مخطط (schema) قاعدة البيانات الذي ينتمي إليه جدول الرستر الذي تخدمه هذه النظرة العامة.

  • r_table_name جدول الرستر الذي تخدمه هذه النظرة العامة.

  • r_raster_column عمود الرستر الذي يخدمه عمود النظرة العامة هذا.

  • overview_factor - هذا هو مستوى الهرم لجدول النظرة العامة. كلما ارتفع الرقم انخفضت دقة الجدول. إذا أُعطيت أداة raster2pgsql مجلدًا من الصور، فإنها تحسب نظرة عامة لكل ملف صورة وتحمّلها كلًّا على حدة. يُفترض المستوى 1 وهو دائمًا الملف الأصلي. في المستوى 2 تمثّل كل بلاطة 4 بلاطات من الأصل. فعلى سبيل المثال، إذا كان لديك مجلد من ملفات صور بحجم 5000x5000 بكسل واخترت تقطيعها إلى 125x125، فسيحتوي جدولك الأساسي لكل ملف صورة على (5000*5000)/(125*125) سجلًا = 1600، وسيحتوي جدولك o_2 (l=2) على ceiling(1600/Power(2,2)) = 400 صف، وسيحتوي o_3 (l=3) على ceiling(1600/Power(2,3) ) = 200 صف. إذا لم تكن أبعاد البكسلات قابلة للقسمة على حجم البلاطات، فستحصل على بعض البلاطات المتبقية (بلاطات غير ممتلئة بالكامل). لاحظ أن كل بلاطة نظرة عامة تولّدها raster2pgsql تحتوي على عدد البكسلات نفسه الذي في البلاطة الأصلية، لكنها بدقة أقل بحيث يمثّل كل بكسل منها (Power(2,overview_factor) بكسل من الأصل).

10.3. بناء تطبيقات مخصصة باستخدام PostGIS Raster

إن توفير PostGIS raster لدوال SQL تعرض الرستر بصيغ صور معروفة يمنحك خيارات كثيرة لعرضها. فعلى سبيل المثال يمكنك استخدام OpenOffice / LibreOffice للعرض كما هو موضح في عرض رسوميات PostGIS Raster باستخدام تقارير LibreOffice Base. إضافة إلى ذلك يمكنك استخدام طيف واسع من اللغات كما هو موضح في هذا القسم.

10.3.1. مثال PHP للإخراج باستخدام ST_AsPNG بالاقتران مع دوال رستر أخرى

في هذا القسم سنوضح كيفية استخدام مشغّل PHP لـ PostgreSQL وعائلة الدوال ST_AsGDALRaster لإخراج النطاقات 1 و2 و3 من رستر إلى تدفق طلب PHP يمكن بعد ذلك تضمينه في وسم html من نوع img src.

يوضح الاستعلام النموذجي كيفية الجمع بين مجموعة كبيرة من دوال الرستر لجلب جميع البلاطات التي تتقاطع مع مستطيل محيط معيّن بنظام wgs 84، ثم دمج البلاطات المتقاطعة معًا باستخدام ST_Union مع إعادة جميع النطاقات، والتحويل إلى الإسقاط الذي يحدده المستخدم باستخدام ST_Transform، ثم إخراج النتائج بصيغة png باستخدام ST_AsPNG.

يمكنك استدعاء ما يلي باستخدام

http://mywebserver/test_raster.php?srid=2249

للحصول على صورة الرستر بنظام Massachusetts state plane بوحدة القدم.


<?php
/** contents of test_raster.php **/
$conn_str ='dbname=mydb host=localhost port=5432 user=myuser password=mypwd';
$dbconn = pg_connect($conn_str);
header('Content-Type: image/png');
/**If a particular projection was requested use it otherwise use mass state plane meters **/
if (!empty( $_REQUEST['srid'] ) &amp;&amp; is_numeric( $_REQUEST['srid']) ){
                $input_srid = intval($_REQUEST['srid']);
}
else { $input_srid = 26986; }
/** The set bytea_output may be needed for PostgreSQL 9.0+, but not for 8.4 **/
$sql = "set bytea_output='escape';
SELECT ST_AsPNG(ST_Transform(
                        ST_AddBand(ST_Union(rast,1), ARRAY[ST_Union(rast,2),ST_Union(rast,3)])
                                ,$input_srid) ) As new_rast
 FROM aerials.boston
        WHERE
         ST_Intersects(rast, ST_Transform(ST_MakeEnvelope(-71.1217, 42.227, -71.1210, 42.218,4326),26986) )";
$result = pg_query($sql);
$row = pg_fetch_row($result);
pg_free_result($result);
if ($row === false) return;
echo pg_unescape_bytea($row[0]);
?>

10.3.2. مثال ASP.NET C# للإخراج باستخدام ST_AsPNG بالاقتران مع دوال رستر أخرى

في هذا القسم سنوضح كيفية استخدام مشغّل Npgsql لـ PostgreSQL في .NET وعائلة الدوال ST_AsGDALRaster لإخراج النطاقات 1 و2 و3 من رستر إلى تدفق طلب PHP يمكن بعد ذلك تضمينه في وسم html من نوع img src.

ستحتاج في هذا التمرين إلى مشغّل npgsql لـ PostgreSQL في .NET، ويمكنك الحصول على أحدث إصدار منه من http://npgsql.projects.postgresql.org/. ما عليك سوى تنزيل أحدث إصدار ووضعه في مجلد bin الخاص بتطبيق ASP.NET وستكون جاهزًا.

يوضح الاستعلام النموذجي كيفية الجمع بين مجموعة كبيرة من دوال الرستر لجلب جميع البلاطات التي تتقاطع مع مستطيل محيط معيّن بنظام wgs 84، ثم دمج البلاطات المتقاطعة معًا باستخدام ST_Union مع إعادة جميع النطاقات، والتحويل إلى الإسقاط الذي يحدده المستخدم باستخدام ST_Transform، ثم إخراج النتائج بصيغة png باستخدام ST_AsPNG.

هذا هو المثال نفسه الوارد في قسم 10.3.1, “مثال PHP للإخراج باستخدام ST_AsPNG بالاقتران مع دوال رستر أخرى” لكنه مُنفّذ بلغة C#.

يمكنك استدعاء ما يلي باستخدام

http://mywebserver/TestRaster.ashx?srid=2249

للحصول على صورة الرستر بنظام Massachusetts state plane بوحدة القدم.

 -- web.config connection string section --
<connectionStrings>
    <add name="DSN"
        connectionString="server=localhost;database=mydb;Port=5432;User Id=myuser;password=mypwd"/>
</connectionStrings>
// Code for TestRaster.ashx
<%@ WebHandler Language="C#" Class="TestRaster" %>
using System;
using System.Data;
using System.Web;
using Npgsql;

public class TestRaster : IHttpHandler
{
        public void ProcessRequest(HttpContext context)
        {

                context.Response.ContentType = "image/png";
                context.Response.BinaryWrite(GetResults(context));

        }

        public bool IsReusable {
                get { return false; }
        }

        public byte[] GetResults(HttpContext context)
        {
                byte[] result = null;
                NpgsqlCommand command;
                string sql = null;
                int input_srid = 26986;
        try {
                    using (NpgsqlConnection conn = new NpgsqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DSN"].ConnectionString)) {
                            conn.Open();

                if (context.Request["srid"] != null)
                {
                    input_srid = Convert.ToInt32(context.Request["srid"]);
                }
                sql = @"SELECT ST_AsPNG(
                            ST_Transform(
                                        ST_AddBand(
                                ST_Union(rast,1), ARRAY[ST_Union(rast,2),ST_Union(rast,3)])
                                                    ,:input_srid) ) As new_rast
                        FROM aerials.boston
                                WHERE
                                    ST_Intersects(rast,
                                    ST_Transform(ST_MakeEnvelope(-71.1217, 42.227, -71.1210, 42.218,4326),26986) )";
                            command = new NpgsqlCommand(sql, conn);
                command.Parameters.Add(new NpgsqlParameter("input_srid", input_srid));


                            result = (byte[]) command.ExecuteScalar();
                conn.Close();
                        }

                }
        catch (Exception ex)
        {
            result = null;
            context.Response.Write(ex.Message.Trim());
        }
                return result;
        }
}

10.3.3. تطبيق Java للطرفية يُخرج نتيجة استعلام رستر كملف صورة

هذا تطبيق Java بسيط للطرفية يأخذ استعلامًا يُعيد صورة واحدة ويُخرجها إلى ملف محدد.

يمكنك تنزيل أحدث مشغّلات JDBC لـ PostgreSQL من http://jdbc.postgresql.org/download.html

يمكنك ترجمة الشيفرة التالية باستخدام أمر مشابه لما يلي:

set env CLASSPATH .:..\postgresql-9.0-801.jdbc4.jar
javac SaveQueryImage.java
jar cfm SaveQueryImage.jar Manifest.txt *.class

واستدعاؤه من سطر الأوامر بأمر مشابه لما يلي

java -jar SaveQueryImage.jar "SELECT ST_AsPNG(ST_AsRaster(ST_Buffer(ST_Point(1,5),10, 'quad_segs=2'),150, 150, '8BUI',100));" "test.png" 
-- Manifest.txt --
Class-Path: postgresql-9.0-801.jdbc4.jar
Main-Class: SaveQueryImage
// Code for SaveQueryImage.java
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.io.*;

public class SaveQueryImage {
  public static void main(String[] argv) {
      System.out.println("Checking if Driver is registered with DriverManager.");

      try {
        //java.sql.DriverManager.registerDriver (new org.postgresql.Driver());
        Class.forName("org.postgresql.Driver");
      }
      catch (ClassNotFoundException cnfe) {
        System.out.println("Couldn't find the driver!");
        cnfe.printStackTrace();
        System.exit(1);
      }

      Connection conn = null;

      try {
        conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydb","myuser", "mypwd");
        conn.setAutoCommit(false);

        PreparedStatement sGetImg = conn.prepareStatement(argv[0]);

        ResultSet rs = sGetImg.executeQuery();

                FileOutputStream fout;
                try
                {
                        rs.next();
                        /** Output to file name requested by user **/
                        fout = new FileOutputStream(new File(argv[1]) );
                        fout.write(rs.getBytes(1));
                        fout.close();
                }
                catch(Exception e)
                {
                        System.out.println("Can't create file");
                        e.printStackTrace();
                }

        rs.close();
                sGetImg.close();
        conn.close();
      }
      catch (SQLException se) {
        System.out.println("Couldn't connect: print out a stack trace and exit.");
        se.printStackTrace();
        System.exit(1);
      }
  }
}

10.3.4. استخدام PLPython لتفريغ الصور عبر SQL

هذه دالة مخزّنة بلغة plpython تنشئ ملفًا في مجلد الخادم لكل سجل. تتطلب أن يكون plpython مثبتًا لديك. يُفترض أن تعمل جيدًا مع كل من plpythonu وplpython3u.

CREATE OR REPLACE FUNCTION write_file (param_bytes bytea, param_filepath text)
RETURNS text
AS $$
f = open(param_filepath, 'wb+')
f.write(param_bytes)
return param_filepath
$$ LANGUAGE plpythonu;
--write out 5 images to the PostgreSQL server in varying sizes
-- note the postgresql daemon account needs to have write access to folder
-- this echos back the file names created;
 SELECT write_file(ST_AsPNG(
        ST_AsRaster(ST_Buffer(ST_Point(1,5),j*5, 'quad_segs=2'),150*j, 150*j, '8BUI',100)),
         'C:/temp/slices'|| j || '.png')
         FROM generate_series(1,5) As j;

     write_file
---------------------
 C:/temp/slices1.png
 C:/temp/slices2.png
 C:/temp/slices3.png
 C:/temp/slices4.png
 C:/temp/slices5.png

10.3.5. إخراج الرستر باستخدام PSQL

للأسف لا تمتلك PSQL وظيفة مدمجة سهلة الاستخدام لإخراج البيانات الثنائية. هذا حلٌّ التفافي يعتمد على دعم PostgreSQL القديم نسبيًا للكائنات الكبيرة (large objects). للاستخدام، شغّل أولًا سطر أوامر psql متصلًا بقاعدة بياناتك.

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

SELECT oid, lowrite(lo_open(oid, 131072), png) As num_bytes
 FROM
 ( VALUES (lo_create(0),
   ST_AsPNG( (SELECT rast FROM aerials.boston WHERE rid=1) )
  ) ) As v(oid,png);
-- you'll get an output something like --
   oid   | num_bytes
---------+-----------
 2630819 |     74860

-- next note the oid and do this replacing the c:/test.png to file path location
-- on your local computer
 \lo_export 2630819 'C:/temp/aerial_samp.png'

-- this deletes the file from large object storage on db
SELECT lo_unlink(2630819);