Name

ST_MapAlgebra (callback function version) — Version avec fonction de rappel - Retourne un raster à une bande à partir d'un ou plusieurs rasters d'entrée, d'index de bandes et d'une fonction de rappel spécifiée par l'utilisateur.

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

Description

Retourne un raster à une bande à partir d'un ou plusieurs rasters d'entrée, d'index de bandes et d'une fonction de rappel spécifiée par l'utilisateur.

rast,rast1,rast2, rastbandargset

Rasters sur lesquels le traitement d'algèbre cartographique est évalué.

rastbandargset permet d'utiliser une opération d'algèbre cartographique sur plusieurs rasters et/ou plusieurs bandes. Voir l'exemple Variante 1.

nband, nband1, nband2

Numéros de bande du raster à évaluer. nband peut être un entier ou un tableau d'entiers désignant les bandes. nband1 est la bande sur rast1 et nband2 est la bande sur rast2 pour le cas de 2 rasters/2 bandes.

callbackfunc

Le paramètre callbackfunc doit être le nom et la signature d'une fonction SQL ou PL/pgSQL, transformée en une regprocedure. Un exemple de fonction PL/pgSQL est le suivant :

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;
                                    

Le callbackfunc doit avoir trois arguments : un tableau de double précision à 3 dimensions, un tableau d'entiers à 2 dimensions et un tableau de texte variadique à 1 dimension. Le premier argument valeur est l'ensemble des valeurs (en double précision) de toutes les matrices d'entrée. Les trois dimensions (où les index sont basés sur 1) sont : trame #, ligne y, colonne x. Le deuxième argument position est l'ensemble des positions des pixels de la trame de sortie et des trames d'entrée. La dimension extérieure (où les indices sont basés sur 0) est la trame #. La position à l'indice 0 de la dimension extérieure est la position en pixels de la trame de sortie. Pour chaque dimension extérieure, il y a deux éléments dans la dimension intérieure pour X et Y. Le troisième argument userargs sert à transmettre les arguments spécifiés par l'utilisateur.

Passer un argument de type regprocedure à une fonction SQL nécessite de passer la signature complète de la fonction, puis de la convertir en un type regprocedure. Pour passer la fonction PL/pgSQL ci-dessus en tant qu'argument, le code SQL de l'argument est le suivant :

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

Notez que l'argument contient le nom de la fonction, les types des arguments de la fonction, des guillemets autour du nom et des types d'arguments, ainsi qu'un cast vers un regprocedure.

mask

Un tableau à n dimensions (matrice) de nombres utilisés pour filtrer les cellules transmises à la fonction de rappel de l'algèbre cartographique. 0 signifie que la valeur d'une cellule voisine doit être traitée comme une absence de données et 1 signifie que la valeur doit être traitée comme une donnée. Si weight est définit à true, les valeurs sont utilisées comme multiplicateurs pour multiplier la valeur du pixel par cette valeur dans la position de voisinage.

weighted

booléen (true/false) indiquant si la valeur d'un masque doit être pondérée (multipliée par la valeur originale) ou non (ne s'applique qu'aux variantes qui prennent un masque).

pixeltype

Si pixeltype est spécifié, l'unique bande du nouveau raster sera de ce type de pixel. Si pixeltype est NULL ou omis, la nouvelle bande du raster aura le même pixeltype que la bande spécifiée du premier raster (pour les types d'étendue : INTERSECTION, UNION, FIRST, CUSTOM) ou que la bande spécifiée du raster approprié (pour les types d'étendue : SECOND, LAST). En cas de doute, spécifiez toujours pixeltype.

Le type de pixel résultant du raster de sortie doit correspondre à l'un des types énumérés dans ST_BandPixelType, ou être omis ou défini à NULL.

extenttype

Les valeurs possibles sont INTERSECTION (par défaut), UNION, FIRST (premier, par défaut pour les variantes à un seul raster), SECOND, LAST (dernier), CUSTOM (personnalisé).

customextent

Si extentype est CUSTOM, un raster doit être spécifié par le paramètre customextent. Voir l'exemple 4 de la variante 1.

distancex

La distance en pixels de la cellule de référence dans la direction x. La largeur de la matrice résultante sera donc 2*distancex + 1. Si elle n'est pas spécifiée, seule la cellule de référence est prise en compte (voisinage de 0).

distancey

La distance en pixels de la cellule de référence dans la direction y. La hauteur de la matrice résultante sera 2*distancey + 1 Si elle n'est pas spécifiée, seule la cellule de référence est prise en compte (voisinage de 0).

userargs

Le troisième paramètre de la fonction callbackfunc est un tableau variadic text . Tous les arguments textuels supplémentaires sont transmis à callbackfunc, et sont contenus dans l'argument userargs.

[Note]

Pour plus d'informations sur le mot-clé VARIADIC, veuillez vous référer à la documentation PostgreSQL et à la section "SQL Functions with Variable Numbers of Arguments" de Query Language (SQL) Functions.

[Note]

Le paramètre text[] de la fonction callbackfunc est obligatoire, que vous choisissiez ou non de transmettre des arguments à la fonction de rappel.

La variante 1 accepte un tableau de rastbandarg permettant l'utilisation d'une opération d'algèbre cartographique sur de nombreux masters et/ou de nombreuses bandes. Voir l'exemple de la variante 1.

Les variantes 2 et 3 agissent sur une ou plusieurs bandes d'un même raster. Voir l'exemple des variantes 2 et 3.

La variante 4 utilise deux rasters avec une bande par raster. Voir l'exemple de la variante 4.

Disponibilité : 2.2.0 : Possibilité d'ajouter un masque

Disponibilité : 2.1.0

Exemples : Variante 1

Un raster, une bande

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
                    

Un raster, plusieurs bandes

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
                    

Plusieurs rasters, plusieurs bandes

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
                    

Exemple complet avec les tuiles d'une couverture avec voisinage. Cette requête ne fonctionne qu'avec PostgreSQL 9.1 ou plus.

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
                    

Exemple identique au précédent pour les tuiles d'une couverture avec voisinage, mais fonctionne avec 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;
                    

Exemples : Variantes 2 et 3

Un raster, plusieurs bandes

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
                    

Un raster, une bande

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
                    

Exemples : Variante 4

Deux rasters, deux bandes

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
                    

Exemples : Utilisation de masques

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;
                    

original

valeur moyenne, sans masque (ce qui revient à avoir que des 1 dans la matrice du masque)

masque uniquement sur les voisins, en excluant le centre

masque pondéré, uniquement sur les voisins en excluant le centre, multiplier les autres pixels par 2