ST_MapAlgebraFct — Version à 2 bandes - Crée un nouveau raster à une bande formé par l'application d'une fonction PostgreSQL valide sur les 2 bandes d'entrée du raster et sur le type de pixel fourni. La bande 1 est utilisée si aucune bande n'est spécifiée. Le type d'étendue INTERSECTION est utilisé si non spécifié.
raster ST_MapAlgebraFct(raster rast1, raster rast2, regprocedure tworastuserfunc, text pixeltype=same_as_rast1, text extenttype=INTERSECTION, text[] VARIADIC userargs);
raster ST_MapAlgebraFct(raster rast1, integer band1, raster rast2, integer band2, regprocedure tworastuserfunc, text pixeltype=same_as_rast1, text extenttype=INTERSECTION, text[] VARIADIC userargs);
|
|
|
ST_MapAlgebraFct est obsolète depuis 2.1.0. Utilisez plutôt ST_MapAlgebra (callback function version). |
Crée un nouveau raster à une bande formé par l'application d'une fonction PostgreSQL valide spécifiée par tworastuserfunc sur les rasters d'entrée rast1, rast2. Si aucune bande band1 ou band2 n'est spécifiée, la bande 1 est utilisée. Le nouveau raster aura la même géoréférence, la même largeur et la même hauteur que les rasters originaux, mais il n'aura qu'une seule bande.
Si pixeltype est fourni, le nouveau raster aura une bande de ce type de pixel. Si pixeltype est NULL ou omis, la nouvelle bande raster aura le même type de pixel que la bande d'entrée de rast1.
Le paramètre tworastuserfunc 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 simple_function_for_two_rasters(pixel1 FLOAT, pixel2 FLOAT, pos INTEGER[], VARIADIC args TEXT[])
RETURNS FLOAT
AS $$ BEGIN
RETURN 0.0;
END; $$
LANGUAGE 'plpgsql' IMMUTABLE;
La tworastuserfunc peut accepter trois ou quatre arguments : une valeur de double précision, une valeur de double précision, un tableau d'entiers facultatif et un tableau de texte variable. Le premier argument est la valeur d'une cellule matricielle individuelle dans rast1 (quel que soit le type de données matricielles). Le deuxième argument est la valeur d'une cellule de trame individuelle dans rast2. Le troisième argument est la position de la cellule de traitement actuelle sous la forme '{x,y}'. Le quatrième argument indique que tous les paramètres restants de ST_MapAlgebraFct doivent être transmis au tworastuserfunc.
Passer un argument de type regprodedure à 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 :
'simple_function(double precision, 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.
Le quatrième paramètre de la fonction tworastuserfunc est un tableau variadic text . Tous les arguments textuels supplémentaires de l'appel à ST_MapAlgebraFct sont transmis à tworastuserfunc, et sont contenus dans l'argument userargs.
|
|
|
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. |
|
|
|
Le paramètre text[] de la fonction |
Disponibilité : 2.0.0
The deprecated two-raster callback form can often be expressed with the modern two-raster ST_MapAlgebra (callback function version) expression variant. This build-time example renders two input rasters and their averaged overlap.
WITH canvas AS (
SELECT ST_AddBand(
ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
1, '8BUI', 0, 0
) AS rast
), inputs AS (
SELECT
ST_AsRaster(ST_Buffer(ST_Point(30, 40), 25), rast, '8BUI', 80, 0)
AS raster_1,
ST_AsRaster(ST_Buffer(ST_Point(50, 40), 25), rast, '8BUI', 220, 0)
AS raster_2
FROM canvas
), variants AS (
SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
UNION ALL
SELECT 'raster 2', raster_2 FROM inputs
UNION ALL
SELECT 'averaged', ST_MapAlgebra(
raster_1, 1,
raster_2, 1,
'([rast1] + [rast2]) / 2',
'8BUI',
'UNION'
) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;
title | image ----------+------------------------- raster 2 | PNG image, 50 x 50 pixels raster 1 | PNG image, 50 x 50 pixels averaged | PNG image, 70 x 50 pixels
Define our user defined function.
CREATE OR REPLACE FUNCTION raster_mapalgebra_union(
rast1 double precision,
rast2 double precision,
pos integer[],
VARIADIC userargs text[]
)
RETURNS double precision
AS $$
DECLARE
BEGIN
CASE
WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
RETURN ((rast1 + rast2)/2.);
WHEN rast1 IS NULL AND rast2 IS NULL THEN
RETURN NULL;
WHEN rast1 IS NULL THEN
RETURN rast2;
ELSE
RETURN rast1;
END CASE;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql' IMMUTABLE COST 1000;
Prepare a test table of rasters.
DROP TABLE IF EXISTS map_shapes;
CREATE TABLE map_shapes(rid serial PRIMARY KEY, rast raster, bnum integer, descrip text);
INSERT INTO map_shapes(rast,bnum, descrip)
WITH mygeoms
AS ( SELECT 2 As bnum, ST_Buffer(ST_Point(90,90),30) As geom, 'circle' As descrip
UNION ALL
SELECT 3 AS bnum,
ST_Buffer(ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'), 15) As geom, 'big road' As descrip
UNION ALL
SELECT 1 As bnum,
ST_Translate(ST_Buffer(ST_GeomFromText('LINESTRING(60 50,150 150,150 50)'), 8,'join=bevel'), 10,-6) As geom, 'small road' As descrip
),
-- define our canvas to be 1 to 1 pixel to geometry
canvas
AS ( SELECT ST_AddBand(
ST_MakeEmptyRaster(
250,
250,
ST_XMin(e)::integer,
ST_YMax(e)::integer,
1, -1, 0, 0),
'8BUI'::text,
0) As rast
FROM (SELECT ST_Extent(geom) As e,
Max(ST_SRID(geom)) As srid
from mygeoms
) As foo
)
-- return our rasters aligned with our canvas
SELECT ST_AsRaster(m.geom, canvas.rast, '8BUI', 240) As rast, bnum, descrip
FROM mygeoms AS m CROSS JOIN canvas
UNION ALL
SELECT canvas.rast, 4, 'canvas'
FROM canvas;
Map algebra on single-band rasters and then collect the result with ST_AddBand.
INSERT INTO map_shapes(rast,bnum,descrip)
SELECT ST_AddBand(ST_AddBand(rasts[1], rasts[2]),rasts[3]), 4, 'map bands overlay fct union (canvas)'
FROM (SELECT ARRAY(SELECT ST_MapAlgebraFct(
m1.rast,
m2.rast,
'raster_mapalgebra_union(double precision, double precision, integer[], text[])'::regprocedure,
'8BUI',
'FIRST')
FROM map_shapes As m1 CROSS JOIN map_shapes As m2
WHERE m1.descrip = 'canvas' AND m2.descrip <
> 'canvas' ORDER BY m2.bnum) As rasts) As foo;
A compact, executable callback example. The source rasters and their averaged overlap are rendered at build time.
CREATE OR REPLACE FUNCTION pg_temp.raster_average(
value_1 double precision,
value_2 double precision,
position integer[],
VARIADIC userargs text[]
) RETURNS double precision
LANGUAGE SQL IMMUTABLE
AS 'SELECT COALESCE(($1 + $2) / 2.0, $1, $2)';
WITH canvas AS (
SELECT ST_AddBand(
ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
1, '8BUI', 0, 0
) AS rast
), inputs AS (
SELECT
ST_AsRaster(ST_Buffer(ST_Point(30, 40), 25), rast, '8BUI', 80, 0)
AS raster_1,
ST_AsRaster(ST_Buffer(ST_Point(50, 40), 25), rast, '8BUI', 220, 0)
AS raster_2
FROM canvas
), variants AS (
SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
UNION ALL
SELECT 'raster 2', raster_2 FROM inputs
UNION ALL
SELECT 'averaged', ST_MapAlgebraFct(
raster_1,
raster_2,
'pg_temp.raster_average(double precision,double precision,integer[],text[])'::regprocedure,
'8BUI',
'UNION'
) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;
title | image ----------+--------------------------- raster 2 | PNG image, 50 x 50 pixels raster 1 | PNG image, 50 x 50 pixels averaged | PNG image, 70 x 50 pixels
CREATE OR REPLACE FUNCTION raster_mapalgebra_userargs(
rast1 double precision,
rast2 double precision,
pos integer[],
VARIADIC userargs text[]
)
RETURNS double precision
AS $$
DECLARE
BEGIN
CASE
WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
RETURN least(userargs[1]::integer,(rast1 + rast2)/2.);
WHEN rast1 IS NULL AND rast2 IS NULL THEN
RETURN userargs[2]::integer;
WHEN rast1 IS NULL THEN
RETURN greatest(rast2, random()*userargs[3]::integer)::integer;
ELSE
RETURN greatest(rast1, random()*userargs[4]::integer)::integer;
END CASE;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql' VOLATILE COST 1000;
SELECT ST_MapAlgebraFct(
m1.rast,
1,
m1.rast,
3,
'raster_mapalgebra_userargs(double precision, double precision, integer[], text[])'::regprocedure,
'8BUI',
'INTERSECT',
'100', '200', '200', '0')
FROM map_shapes As m1
WHERE m1.descrip = 'map bands overlay fct union (canvas)';
The generated callback figure above demonstrates the raster alignment and overlap used by this variant; the exact callback result remains available as text.
ST_MapAlgebraExpr, ST_BandPixelType, ST_GeoReference, ST_SetValue