ST_MapAlgebraFct
Prev | 12.12. Raster Processing: Map Algebra | Next

## Name

ST_MapAlgebraFct — 2 band version - Creates a new one band raster formed by applying a valid PostgreSQL function on the 2 input raster bands and of pixeltype prodived. Band 1 is assumed if no band is specified. Extent type defaults to INTERSECTION if not specified.

## Synopsis

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

## Description

ST_MapAlgebraFct is deprecated as of 2.1.0. Use ST_MapAlgebra (callback function version) instead.

Creates a new one band raster formed by applying a valid PostgreSQL function specified by the `tworastuserfunc` on the input raster `rast1`, `rast2`. If no `band1` or `band2` is specified, band 1 is assumed. The new raster will have the same georeference, width, and height as the original rasters but will only have one band.

If `pixeltype` is passed in, then the new raster will have a band of that pixeltype. If pixeltype is passed NULL or left out, then the new raster band will have the same pixeltype as the input `rast1` band.

The `tworastuserfunc` 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 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;

The `tworastuserfunc` may accept three or four arguments: a double precision value, a double precision value, an optional integer array, and a variadic text array. The first argument is the value of an individual raster cell in `rast1` (regardless of the raster datatype). The second argument is an individual raster cell value in `rast2`. The third argument is the position of the current processing cell in the form '{x,y}'. The fourth argument indicates that all remaining parameters to ST_MapAlgebraFct shall be passed through to the `tworastuserfunc`.

Passing a regprodedure 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:

    'simple_function(double precision, 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.

The fourth argument to the `tworastuserfunc` is a variadic text array. All trailing text arguments to any ST_MapAlgebraFct call are passed through to the specified `tworastuserfunc`, and are contained in the `userargs` argument.

For more information about the VARIADIC keyword, please refer to the PostgreSQL documentation and the "SQL Functions with Variable Numbers of Arguments" section of Query Language (SQL) Functions.

The text[] argument to the `tworastuserfunc` is required, regardless of whether you choose to pass any arguments to your user function for processing or not.

Availability: 2.0.0

## Example: Overlaying rasters on a canvas as separate bands

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

    -- prep our 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 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;

map bands overlay (canvas) (R: small road, G: circle, B: big road)

## User Defined function that takes extra args

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

user defined with extra args and different bands from same raster

## See Also

ST_MapAlgebraExpr, ST_BandPixelType, ST_GeoReference, ST_SetValue

Prev | Up | Next
ST_MapAlgebraFct | Home | ST_MapAlgebraFctNgb