فصل 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
في مناسبات كثيرة، ستحتاج إلى إنشاء الرستر وجداول الرستر داخل قاعدة البيانات مباشرة. وتوجد وفرة من الدوال لذلك. الخطوات العامة الواجب اتباعها هي:
-
إنشاء جدول يحتوي على عمود رستر لحفظ سجلات الرستر الجديدة، ويمكن تحقيق ذلك بما يلي:
CREATE TABLE myrasters(rid serial primary key, rast raster);
-
توجد دوال كثيرة تساعد على تحقيق هذا الهدف. إذا كنت تُنشئ رستر غير مشتق من رستر آخر، فستبدأ بـ ST_MakeEmptyRaster، متبوعة بـ ST_AddBand
يمكنك أيضًا إنشاء رستر من الأشكال الهندسية. ولتحقيق ذلك ستستخدم ST_AsRaster ربما مصحوبة بدوال أخرى مثل ST_Union أو ST_MapAlgebraFct أو أي من عائلة دوال جبر الخرائط الأخرى.
توجد خيارات أكثر بكثير لإنشاء جداول رستر جديدة من جداول موجودة. على سبيل المثال، يمكنك إنشاء جدول رستر بإسقاط مختلف عن جدول موجود باستخدام ST_Transform
-
بعد الانتهاء من الملء الأولي لجدولك، ستحتاج إلى إنشاء فهرس مكاني على عمود الرستر بشيء مثل:
CREATE INDEX myrasters_rast_st_convexhull_idx ON myrasters USING gist( ST_ConvexHull(rast) );
لاحظ استخدام ST_ConvexHull لأن معظم عوامل الرستر مبنية على الغلاف المحدب للرستر.
كانت إصدارات رستر PostGIS السابقة للإصدار 2.0 مبنية على الغلاف بدلًا من الغلاف المحدب. ولكي تعمل الفهارس المكانية بشكل سليم، ستحتاج إلى حذفها واستبدالها بفهرس مبني على الغلاف المحدب.
-
تطبيق قيود الرستر باستخدام 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) لفهرسة الرستر. يستخدم كلا العرضين المعلومات المضمَّنة في قيود جداول الرستر. ونتيجة لذلك تظل عروض الفهرسة متسقة دائمًا مع بيانات الرستر في الجداول لأن القيود مُطبَّقة.
-
raster_columnsيُفهرس هذا العرض جميع أعمدة جداول الرستر في قاعدة بياناتك. -
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 على أعمدة المعلومات التالية.
-
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'] ) && 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);