Namn

ST_MapAlgebra (callback function version) — Callback function version - Returnerar ett enbandsraster med ett eller flera indataraster, bandindex och en användarspecificerad callback-funktion.

Synopsis

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);

Beskrivning

Returnerar ett enbandsraster med ett eller flera indataraster, bandindex och en användarspecificerad återkallningsfunktion.

rast,rast1,rast2, rastbandargset

Raster på vilka kartalgebraprocessen utvärderas.

rastbandargset gör det möjligt att använda en map algebra-operation på många raster och/eller många band. Se exempel Variant 1.

nband, nband1, nband2

Bandnummer för det raster som ska utvärderas. nband kan vara ett heltal eller ett heltal[] som anger banden. nband1 är band på rast1 och nband2 är band på rast2 för fallet 2 raster/2 band.

callbackfunc

Parametern callbackfunc måste vara namnet och signaturen för en SQL- eller PL/pgSQL-funktion, som kastas till en regprocedure. Ett exempel på PL/pgSQL-funktionsexempel är:

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

callbackfunc måste ha två eller tre argument: en tredimensionell matris av typen double precision, en tvådimensionell heltalsmatris och valfritt en variadisk endimensionell textmatris. Det första argumentet value är uppsättningen värden (som double precision) från alla indataraster. De tre dimensionerna (där index börjar på 1) är: raster nr, rad y och kolumn x. Det andra argumentet position är uppsättningen pixelpositioner från utdatarastret och indatarastren. Den yttre dimensionen (där index börjar på 0) är raster nr. Positionen vid index 0 i den yttre dimensionen är utdatarastrets pixelposition. För varje yttre dimension finns två element i den inre dimensionen för X och Y. Det valfria tredje argumentet userargs används för att föra vidare användarspecificerade argument.

Callbackens returvärde används som värde för utdatapixeln. Om callbacken returnerar NULL sätts utdatapixeln till NODATA när utdatabandet har ett NODATA-värde. Om utdatabandet saknar NODATA-värde utlöser ett NULL-resultat från callbacken ett fel.

För att skicka ett regprocedure-argument till en SQL-funktion krävs att hela funktionssignaturen skickas och sedan kastas till en regprocedure-typ. För att skicka ovanstående exempel på PL / pgSQL-funktion som ett argument är SQL för argumentet:

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

Observera att PostgreSQL-matristyper inte kodar dimensioner i funktionssignaturer, så flerdimensionella callbackargument skrivs som double precision[] och integer[] i regprocedure-signaturen.

mask

En n-dimensionell array (matris) med tal som används för att filtrera vilka celler som skickas till map algebra call-back-funktionen. 0 betyder att ett granncellsvärde ska behandlas som ingen data och 1 betyder att värdet ska behandlas som data. Om weight är satt till true används värdena som multiplikatorer för att multiplicera pixelvärdet för det värdet i grannskapspositionen.

weighted

boolean (true/false) för att ange om ett maskvärde ska viktas (multipliceras med originalvärdet) eller inte (gäller endast proto som tar en mask).

pixeltype

Om pixeltype skickas in kommer det ena bandet i det nya rastret att ha den pixeltypen. Om pixeltype anges som NULL eller utelämnas kommer det nya rasterbandet att ha samma pixeltype som det angivna bandet i det första rastret (för omfattningstyper: INTERSECTION, UNION, FIRST, CUSTOM) eller det angivna bandet i det lämpliga rastret (för omfattningstyper: SECOND, LAST). Om du är osäker, ange alltid pixeltype.

Den resulterande pixeltypen för utdatarastret måste vara en som listas i ST_BandPixelType eller utelämnas eller sättas till NULL.

extenttype

Möjliga värden är INTERSECTION (standard), UNION, FIRST (standard för en rastervariant), SECOND (andra), LAST (sista), CUSTOM (anpassad).

customextent

Om extentype är CUSTOM måste ett raster tillhandahållas för customextent. Se exempel 4 i Variant 1.

distancex

Avståndet i pixlar från referenscellen i x-riktningen. Bredden på den resulterande matrisen skulle alltså vara 2*avståndx + 1. Om inget anges beaktas endast referenscellen (grannskap 0).

distancey

Avståndet i pixlar från referenscellen i y-riktningen. Höjden på den resulterande matrisen blir 2*avståndety + 1. Om inget anges beaktas endast referenscellen (grannskapet 0).

userargs

Om callbackfunc deklarerar ett tredje argument är detta argument en matris av typen variadic text. Alla efterföljande textargument förs vidare till den angivna callbackfunc och ingår i argumentet userargs.

[Notera]

För mer information om VARIADIC-nyckelordet, se PostgreSQL-dokumentationen och avsnittet "SQL-funktioner med variabelt antal argument" i Query Language (SQL) -funktioner.

Variant 1 accepterar en array av rastbandarg som gör det möjligt att använda en map algebra-operation på många raster och/eller många band. Se exempel Variant 1.

Varianterna 2 och 3 arbetar med ett eller flera band i ett raster. Se exempel Variant 2 och 3.

Variant 4 arbetar med två raster med ett band per raster. Se exempel Variant 4.

Tillgänglighet: 2.2.0: Möjlighet att lägga till en mask

Tillgänglighet: 2.1.0

Exempel

Jämför ett omaskerat medelvärde med masker för endast grannar och viktade grannar. Den viktade masken multiplicerar angränsande värden med 2 innan resultatet beräknas.

Kod
WITH foo AS (
    SELECT ST_SetBandNoDataValue(
        ST_SetValue(
            ST_SetValue(
                ST_AsRaster(
                    ST_Buffer('LINESTRING(50 50,100 90,100 50)'::geometry, 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
), variants AS (
    SELECT 'original' AS title, rast
    FROM foo
    UNION ALL
    SELECT 'unmasked mean' AS title,
        ST_MapAlgebra(rast, 1, 'ST_Mean4ma(double precision[], int[], text[])'::regprocedure) AS rast
    FROM foo
    UNION ALL
    SELECT 'neighbor-only mean' 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 'weighted neighbor mean' 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
)
SELECT title, ST_AsPNG(rast) AS image
FROM variants;
Utdata
title                  | image
------------------------+--------------------------------
 original               | PNG image, 200 x 200 pixels
 unmasked mean          | PNG image, 200 x 200 pixels
 neighbor-only mean     | PNG image, 200 x 200 pixels
 weighted neighbor mean | PNG image, 200 x 200 pixels
                    
Figur
Geometry figure for visual-rt-st-mapalgebra-01

Variant 1.

Ett raster, ett band

Kod
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
                    

Ett raster, flera band

Kod
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
                    

Flera raster, flera band

Kod
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
                    

Fullständigt exempel med rutor från en täckning med grannskap.

Kod
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
                    

Exempel som det föregående för rutor från en täckning med grannskap, men med endast grundläggande SQL-funktioner.

Kod
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
), 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[],
            'sample_callbackfunc(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;
                    

Varianter 2 och 3.

Ett raster, flera band

Kod
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
                    

Ett raster, ett band

Kod
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
                    

Variant 4.

Två rasters, två band

Kod
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