ST_MapAlgebra (callback function version) — Die Version mit der Rückruffunktion - Gibt für einen oder mehrere Eingaberaster einen Raster mit einem Band, den Bandindizes und einer vom Anwender vorgegebenen Rückruffunktion zurück.
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)
;
Gibt für einen oder mehrere Eingaberaster einen Raster mit einem Band, den Bandindizes und einer vom Anwender vorgegebenen Rückruffunktion zurück.
Raster die mit der Map Algebra Operation ausgewertet werden.
rastbandargset
ermöglicht die Anwendung einer Map Algebra Operation auf viele Raster und/oder viele Bänder. Siehe das Beispiel zu Variante 1.
Die Nummern der Rasterbänder, die ausgewertet werden sollen. Die Bänder können über "nband" als Integer oder Integer[] angegeben werden. Bei der Variante mit 2 Raster steht "nband1" für die Bänder von "rast1" und nband2 für die Bänder von rast2.
The callbackfunc
parameter must be the name and signature of an SQL or PL/pgSQL function, cast to a regprocedure. An example PL/pgSQL function example is:
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;
The callbackfunc
must have three arguments: a 3-dimension double precision array, a 2-dimension integer array and a variadic 1-dimension text array. The first argument value
is the set of values (as double precision) from all input rasters. The three dimensions (where indexes are 1-based) are: raster #, row y, column x. The second argument position
is the set of pixel positions from the output raster and input rasters. The outer dimension (where indexes are 0-based) is the raster #. The position at outer dimension index 0 is the output raster's pixel position. For each outer dimension, there are two elements in the inner dimension for X and Y. The third argument userargs
is for passing through any user-specified arguments.
Passing a regprocedure argument to a SQL function requires the full function signature to be passed, then cast to a regprocedure type. To pass the above example PL/pgSQL function as an argument, the SQL for the argument is:
'sample_callbackfunc(double precision[], integer[], text[])'::regprocedure
Note that the argument contains the name of the function, the types of the function arguments, quotes around the name and argument types, and a cast to a regprocedure.
Ein n-dimensionales Feld (Matrix) von Zahlen, das verwendet wird um Zellen für die "Map Algebra"-Rückruffunktion zu filtern. 0 bedeutet, dass ein Nachbarzellwert wie NODATA behandelt werden soll. 1 bedeutet, dass dieser Wert als Datum behandelt werden soll. Wenn der Parameter "weighted" (gewichtet) TRUE ist, dann werden diese Werte als Multiplikatoren für die Pixelwerte in der Nachbarschaft verwendet.
Boolesche Variable (TRUE/FALSE), die angibt ob ein Wert der Maske gewichtet (mit dem ursprünglichen Wert multipliziert) werden soll oder nicht (gilt nur für den ersten, der die Maske übernimmt).
Wenn pixeltype
angegeben ist, dann hat das Band des neuen Rasters diesen Pixeltyp. Wenn für den Pixeltyp NULL oder kein Wert übergeben wird, dann hat das neue Rasterband denselben Pixeltyp wie das angegebene Band des ersten Raster (für die Lagevergleiche: INTERSECTION, UNION, FIRST, CUSTOM), oder wie das spezifizierte Band des entsprechenden Rasters (für die Lagevergleiche:SECOND, LAST). Im Zweifelsfall sollten Sie den pixeltype
immer angeben.
Der resultierende Pixeltyp des Zielraster muss entweder aus ST_BandPixelType sein, weggelassen oder auf NULL gesetzt werden.
Mögliche Werte sind INTERSECTION (standardmäßig), UNION, FIRST (standardmäßig für Einzelraster-Varianten), SECOND, LAST, CUSTOM.
Wenn extentype
CUSTOM ist, dann muss ein Raster für customextent
übergeben werden. Siehe Beispiel 4 von Variante 1.
Der Abstand in Pixel von der Referenzzelle in X-Richtung. Die Breite der resultierenden Matrix ergibt sich aus 2*distancex + 1
. Wenn nicht angegeben, dann wird nur die Referenzzelle berücksichtigt (keine Nachbarschaft/"neighborhood of 0").
Die Entfernung der Pixel zur Referenzzelle in Y-Richtung. Die Höhe der resultierenden Matrix ergibt sich aus 2*distancey + 1
. Wenn nicht angegeben, dann wird nur die Referenzzelle berücksichtigt (keine Nachbarschaft/"neighborhood of 0").
Der dritte Übergabewert an die Rückruffunktion callbackfunc
ist ein Feld mit dem Datentyp variadic text. Die an diesen Datentyp angehängten Parameter werden an die callbackfunc
durchgereicht und sind in dem Übergabewert userargs
enthalten.
Für nähere Information zu dem Schlüsselwort VARIADIC, sehen Sie bitte die PostgreSQL Dokumentation und den Abschnitt "SQL Functions with Variable Numbers of Arguments" unter Query Language (SQL) Functions. |
Der Übergabewert text[] an die Rückruffunktion |
Variante 1 nimmt ein Feld an rastbandarg
entgegen, wodurch die Anwendung einer Map Algebra Operation auf mehrere Raster und/oder mehrere Bänder ermöglicht wird. Siehe das Beispiel zu Variante 1.
Die Varianten 2 und 3 führen die Operation auf einem oder mehreren Bändern eines Raster aus. Siehe die Beispiele mit Variante 2 und 3.
Die Variante 4 führt die Operationen an zwei Raster mit einem Band pro Raster aus. Siehe das Beispiel mit Variante 4.
Verfügbarkeit: 2.2.0: Möglichkeit eine Maske hinzuzufügen
Verfügbarkeit: 2.1.0
Ein Raster, ein Band
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
Ein Raster, mehrere Bänder
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
Mehrere Raster, mehrere Bänder
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
Ein vollständiges Beispiel mit Coveragekacheln und Nachbarschaft. Diese Abfrage funktioniert nur mit PostgreSQL 9.1 oder höher.
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
Das selbe Beispiel wie vorher, mit Coveragekacheln und Nachbarschaft, das aber auch mit PostgreSQL 9.0 funktioniert.
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;
Ein Raster, mehrere Bänder
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
Ein Raster, ein Band
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
Zwei Raster, zwei Bänder
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 otehr 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;
|
|
|
|