GISarabia.org
PostGIS › الدليل الرسمي › 11. مرجع الرستر › 11.12. معالجة الرستر: جبر الخرائط (Map Algebra)
PostGIS 3.6 · Official Manual · ترجمة عربية

ST_MapAlgebra (callback function version)

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

الاسم

ST_MapAlgebra (callback function version) — نسخة دالة الاستدعاء الراجع (callback) - تُعيد رسترًا بنطاق واحد انطلاقًا من رستر مُدخل واحد أو أكثر وفهارس نطاقات ودالة استدعاء راجع واحدة يحددها المستخدم.

المختصر

raster ST_MapAlgebra(rastbandarg[] rastbandargset, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=INTERSECTION, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast, integer[] nband, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=FIRST, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast, integer nband, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=FIRST, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast1, integer nband1, raster rast2, integer nband2, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=INTERSECTION, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast, integer nband, regprocedure callbackfunc, float8[] mask, boolean weighted, text pixeltype=NULL, text extenttype=INTERSECTION, raster customextent=NULL, text[] VARIADIC userargs=NULL);

الوصف

تُعيد رسترًا بنطاق واحد انطلاقًا من رستر مُدخل واحد أو أكثر وفهارس نطاقات ودالة استدعاء راجع واحدة يحددها المستخدم.

rast,rast1,rast2, rastbandargset

الرسترات التي تُقيَّم عليها عملية جبر الخرائط.

تتيح rastbandargset استخدام عملية جبر خرائط على رسترات كثيرة و/أو نطاقات كثيرة. انظر مثال الشكل 1.

nband, nband1, nband2

أرقام نطاقات الرستر المراد تقييمها. يمكن أن يكون nband عددًا صحيحًا أو integer[] يدل على النطاقات. وفي حالة رسترين/نطاقين، nband1 هو النطاق في rast1 وnband2 هو النطاق في rast2.

callbackfunc

يجب أن يكون المعامل callbackfunc اسم دالة SQL أو PL/pgSQL وتوقيعها، محوَّلًا إلى regprocedure. ومن أمثلة دوال PL/pgSQL:

CREATE OR REPLACE FUNCTION sample_callbackfunc(value double precision[][][], position integer[][], VARIADIC userargs text[])
    RETURNS double precision
    AS $$
    BEGIN
        RETURN 0;
    END;
    $$ LANGUAGE 'plpgsql' IMMUTABLE;
                                    

يجب أن تكون لـ callbackfunc ثلاثة وسائط: مصفوفة double precision ثلاثية الأبعاد، ومصفوفة أعداد صحيحة ثنائية الأبعاد، ومصفوفة نصية variadic أحادية البعد. الوسيط الأول value هو مجموعة القيم (بنوع double precision) من جميع الرسترات المُدخلة. والأبعاد الثلاثة (حيث تبدأ الفهارس من 1) هي: رقم الرستر، والصف y، والعمود x. الوسيط الثاني position هو مجموعة مواضع البكسلات من الرستر الناتج والرسترات المُدخلة. البعد الخارجي (حيث تبدأ الفهارس من 0) هو رقم الرستر. والموضع عند الفهرس 0 من البعد الخارجي هو موضع البكسل في الرستر الناتج. ولكل بعد خارجي، يوجد عنصران في البعد الداخلي لـ X وY. أما الوسيط الثالث userargs فهو لتمرير أي وسائط يحددها المستخدم.

يتطلب تمرير وسيط من نوع regprocedure إلى دالة SQL تمرير توقيع الدالة كاملًا، ثم تحويله إلى النوع regprocedure. لتمرير دالة PL/pgSQL المذكورة في المثال أعلاه وسيطًا، تكون تعليمة SQL للوسيط:

'sample_callbackfunc(double precision[], integer[], text[])'::regprocedure
                                    

لاحظ أن الوسيط يحتوي على اسم الدالة وأنواع وسائطها وعلامات اقتباس حول الاسم وأنواع الوسائط، وتحويلًا إلى regprocedure.

mask

مصفوفة (matrix) من الأعداد ذات n بُعد تُستخدم لتصفية الخلايا التي تُمرَّر إلى دالة الاستدعاء الراجع لجبر الخرائط. القيمة 0 تعني أن قيمة الخلية المجاورة يجب أن تُعامَل على أنها no-data، والقيمة 1 تعني أن القيمة يجب أن تُعامَل على أنها بيانات. إذا ضُبط weight على true، فتُستخدم القيم معاملات ضرب تُضرب بها قيمة البكسل في ذلك الموضع من الجوار.

weighted

قيمة منطقية (true/false) تشير إلى ما إذا كان يجب ترجيح قيمة القناع (ضربها في القيمة الأصلية) أم لا (لا ينطبق إلا على النموذج الذي يقبل قناعًا).

pixeltype

إذا مُرِّر pixeltype، فسيكون النطاق الوحيد في الرستر الجديد من ذلك النوع. وإذا مُرِّر pixeltype بقيمة NULL أو أُغفل، فسيكون لنطاق الرستر الجديد نوع البكسل نفسه للنطاق المحدد من الرستر الأول (لأنواع الامتداد: INTERSECTION وUNION وFIRST وCUSTOM) أو للنطاق المحدد من الرستر المناسب (لأنواع الامتداد: SECOND وLAST). عند الشك، حدِّد pixeltype دائمًا.

يجب أن يكون نوع البكسل الناتج للرستر المُخرَج أحد الأنواع المدرجة في ST_BandPixelType أو أن يُغفل أو يُضبط على NULL.

extenttype

القيم الممكنة هي INTERSECTION (الافتراضية) وUNION وFIRST (الافتراضية لأشكال الرستر الواحد) وSECOND وLAST وCUSTOM.

customextent

إذا كان extentype هو CUSTOM، فيجب تقديم رستر لـ customextent. انظر المثال 4 من الشكل 1.

distancex

المسافة بالبكسلات من الخلية المرجعية في اتجاه x. وبذلك يكون عرض المصفوفة الناتجة 2*distancex + 1. إذا لم تُحدَّد فلا تؤخذ في الحسبان إلا الخلية المرجعية (جوار بحجم 0).

distancey

المسافة بالبكسلات من الخلية المرجعية في اتجاه y. ويكون ارتفاع المصفوفة الناتجة 2*distancey + 1 . إذا لم تُحدَّد فلا تؤخذ في الحسبان إلا الخلية المرجعية (جوار بحجم 0).

userargs

الوسيط الثالث لـ callbackfunc مصفوفة من نوع variadic text. تُمرَّر جميع الوسائط النصية اللاحقة إلى callbackfunc المحددة، وتُحتوى في الوسيط userargs.

[ملاحظة]

لمزيد من المعلومات عن الكلمة المفتاحية VARIADIC، يُرجى الرجوع إلى توثيق PostgreSQL وقسم «SQL Functions with Variable Numbers of Arguments» من دوال لغة الاستعلام (SQL).

[ملاحظة]

الوسيط text[] لـ callbackfunc مطلوب، بصرف النظر عمّا إذا اخترت تمرير أي وسائط إلى دالة الاستدعاء الراجع لمعالجتها أم لا.

يقبل الشكل 1 مصفوفة من rastbandarg تتيح استخدام عملية جبر خرائط على رسترات كثيرة و/أو نطاقات كثيرة. انظر مثال الشكل 1.

يعمل الشكلان 2 و3 على نطاق واحد أو أكثر من رستر واحد. انظر مثال الشكلين 2 و3.

يعمل الشكل 4 على رسترين بنطاق واحد لكل رستر. انظر مثال الشكل 4.

متاحة منذ: 2.2.0: إمكانية إضافة قناع

متاحة منذ: 2.1.0

أمثلة: الصيغة 1

رستر واحد، نطاق واحد

WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        ARRAY[ROW(rast, 1)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    

رستر واحد، عدة نطاقات

WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        ARRAY[ROW(rast, 3), ROW(rast, 1), ROW(rast, 3), ROW(rast, 2)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    

عدة رسترات، عدة نطاقات

WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast UNION ALL
    SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI', 300, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        ARRAY[ROW(t1.rast, 3), ROW(t2.rast, 1), ROW(t2.rast, 3), ROW(t1.rast, 2)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
    AND t2.rid = 2
                    

مثال كامل لبلاطات تغطية مع الجوار. لا يعمل هذا الاستعلام إلا مع PostgreSQL 9.1 أو أحدث.

WITH foo AS (
    SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL
    SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, 0, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0) AS rast UNION ALL
    SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, 0, 1, -1, 0, 0, 0), 1, '16BUI', 3, 0) AS rast UNION ALL

    SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -2, 1, -1, 0, 0, 0), 1, '16BUI', 10, 0) AS rast UNION ALL
    SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -2, 1, -1, 0, 0, 0), 1, '16BUI', 20, 0) AS rast UNION ALL
    SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -2, 1, -1, 0, 0, 0), 1, '16BUI', 30, 0) AS rast UNION ALL

    SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -4, 1, -1, 0, 0, 0), 1, '16BUI', 100, 0) AS rast UNION ALL
    SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -4, 1, -1, 0, 0, 0), 1, '16BUI', 200, 0) AS rast UNION ALL
    SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -4, 1, -1, 0, 0, 0), 1, '16BUI', 300, 0) AS rast
)
SELECT
    t1.rid,
    ST_MapAlgebra(
        ARRAY[ROW(ST_Union(t2.rast), 1)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure,
        '32BUI',
        'CUSTOM', t1.rast,
        1, 1
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 4
    AND t2.rid BETWEEN 0 AND 8
    AND ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rid, t1.rast
                    

مثال مشابه للسابق لبلاطات تغطية مع الجوار لكنه يعمل مع PostgreSQL 9.0.

WITH src AS (
    SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL
    SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, 0, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0) AS rast UNION ALL
    SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, 0, 1, -1, 0, 0, 0), 1, '16BUI', 3, 0) AS rast UNION ALL

    SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -2, 1, -1, 0, 0, 0), 1, '16BUI', 10, 0) AS rast UNION ALL
    SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -2, 1, -1, 0, 0, 0), 1, '16BUI', 20, 0) AS rast UNION ALL
    SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -2, 1, -1, 0, 0, 0), 1, '16BUI', 30, 0) AS rast UNION ALL

    SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -4, 1, -1, 0, 0, 0), 1, '16BUI', 100, 0) AS rast UNION ALL
    SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -4, 1, -1, 0, 0, 0), 1, '16BUI', 200, 0) AS rast UNION ALL
    SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -4, 1, -1, 0, 0, 0), 1, '16BUI', 300, 0) AS rast
)
WITH foo AS (
    SELECT
        t1.rid,
        ST_Union(t2.rast) AS rast
    FROM src t1
    JOIN src t2
        ON ST_Intersects(t1.rast, t2.rast)
        AND t2.rid BETWEEN 0 AND 8
    WHERE t1.rid = 4
    GROUP BY t1.rid
), bar AS (
    SELECT
        t1.rid,
        ST_MapAlgebra(
            ARRAY[ROW(t2.rast, 1)]::rastbandarg[],
            'raster_nmapalgebra_test(double precision[], int[], text[])'::regprocedure,
            '32BUI',
            'CUSTOM', t1.rast,
            1, 1
        ) AS rast
    FROM src t1
    JOIN foo t2
        ON t1.rid = t2.rid
)
SELECT
    rid,
    (ST_Metadata(rast)),
    (ST_BandMetadata(rast, 1)),
    ST_Value(rast, 1, 1, 1)
FROM bar;
                    

أمثلة: الشكلان 2 و3

رستر واحد، عدة نطاقات

WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        rast, ARRAY[3, 1, 3, 2]::integer[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    

رستر واحد، نطاق واحد

WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        rast, 2,
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    

أمثلة: الشكل 4

رستران، نطاقان

WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast UNION ALL
    SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI', 300, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        t1.rast, 2,
        t2.rast, 1,
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
    AND t2.rid = 2
                    

أمثلة: استخدام الأقنعة

WITH foo AS (SELECT
   ST_SetBandNoDataValue(
ST_SetValue(ST_SetValue(ST_AsRaster(
        ST_Buffer(
            ST_GeomFromText('LINESTRING(50 50,100 90,100 50)'), 5,'join=bevel'),
            200,200,ARRAY['8BUI'], ARRAY[100], ARRAY[0]), ST_Buffer('POINT(70 70)'::geometry,10,'quad_segs=1') ,50),
  'LINESTRING(20 20, 100 100, 150 98)'::geometry,1),0)  AS rast )
SELECT 'original' AS title, rast
FROM foo
UNION ALL
SELECT 'no mask mean value' AS title, ST_MapAlgebra(rast,1,'ST_mean4ma(double precision[], int[], text[])'::regprocedure) AS rast
FROM foo
UNION ALL
SELECT 'mask only consider neighbors, exclude center' AS title, ST_MapAlgebra(rast,1,'ST_mean4ma(double precision[], int[], text[])'::regprocedure,
    '{{1,1,1}, {1,0,1}, {1,1,1}}'::double precision[], false) As rast
FROM foo

UNION ALL
SELECT 'mask weighted only consider neighbors, exclude center multi other pixel values by 2' AS title, ST_MapAlgebra(rast,1,'ST_mean4ma(double precision[], int[], text[])'::regprocedure,
    '{{2,2,2}, {2,0,2}, {2,2,2}}'::double precision[], true) As rast
FROM foo;
                    

الأصل

متوسط القيمة دون قناع (مماثل لوجود قيم 1 فقط في مصفوفة القناع)

قناع يأخذ في الحسبان الجيران فقط، مع استبعاد المركز

قناع مرجَّح يأخذ في الحسبان الجيران فقط، مع استبعاد المركز وضرب قيم البكسلات الأخرى في 2