]> granicus.if.org Git - postgis/commitdiff
Added helper user functions for common MapAlgebra operations: Min, Max, Mean, Range...
authorDavid Zwarg <dzwarg@azavea.com>
Wed, 30 Nov 2011 19:26:34 +0000 (19:26 +0000)
committerDavid Zwarg <dzwarg@azavea.com>
Wed, 30 Nov 2011 19:26:34 +0000 (19:26 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8262 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_pg/rtpostgis.sql.in.c
raster/test/regress/Makefile.in
raster/test/regress/create_rt_mapalgebrafctngb_test.sql
raster/test/regress/rt_mapalgebrafctngb.sql
raster/test/regress/rt_mapalgebrafctngb_userfunc.sql [new file with mode: 0644]
raster/test/regress/rt_mapalgebrafctngb_userfunc_expected [new file with mode: 0644]

index c61f0ddbf8579ea38d3291dc5dcf0f4871f79c34..ae0e517a17fc24954e8f4fda27e0a327c334933c 100644 (file)
@@ -1795,6 +1795,157 @@ CREATE OR REPLACE FUNCTION st_mapalgebrafctngb(
     AS 'MODULE_PATHNAME', 'RASTER_mapAlgebraFctNgb'
     LANGUAGE 'C' IMMUTABLE;
 
+-----------------------------------------------------------------------
+-- Neighborhood MapAlgebra processing functions.
+-----------------------------------------------------------------------
+CREATE OR REPLACE FUNCTION st_max4ma(matrix float[][], nodatamode text, variadic args text[])
+    RETURNS float AS
+    $$
+    DECLARE
+        _matrix float[][];
+        max float;
+    BEGIN
+        _matrix := matrix;
+        max := '-Infinity'::float;
+        FOR x in array_lower(_matrix, 1)..array_upper(_matrix, 1) LOOP
+            FOR y in array_lower(_matrix, 2)..array_upper(_matrix, 2) LOOP
+                IF _matrix[x][y] IS NULL THEN
+                    IF NOT nodatamode = 'ignore' THEN
+                        _matrix[x][y] := nodatamode::float;
+                    END IF;
+                END IF;
+                IF max < _matrix[x][y] THEN
+                    max := _matrix[x][y];
+                END IF;
+            END LOOP;
+        END LOOP;
+        RETURN max;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
+
+
+CREATE OR REPLACE FUNCTION st_min4ma(matrix float[][], nodatamode text, variadic args text[])
+    RETURNS float AS
+    $$
+    DECLARE
+        _matrix float[][];
+        min float;
+    BEGIN
+        _matrix := matrix;
+        min := 'Infinity'::float;
+        FOR x in array_lower(_matrix, 1)..array_upper(_matrix, 1) LOOP
+            FOR y in array_lower(_matrix, 2)..array_upper(_matrix, 2) LOOP
+                IF _matrix[x][y] IS NULL THEN
+                    IF NOT nodatamode = 'ignore' THEN
+                        _matrix[x][y] := nodatamode::float;
+                    END IF;
+                END IF;
+                IF min > _matrix[x][y] THEN
+                    min := _matrix[x][y];
+                END IF;
+            END LOOP;
+        END LOOP;
+        RETURN min;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_sum4ma(matrix float[][], nodatamode text, variadic args text[])
+    RETURNS float AS
+    $$
+    DECLARE
+        _matrix float[][];
+        sum float;
+    BEGIN
+        _matrix := matrix;
+        sum := 0;
+        FOR x in array_lower(matrix, 1)..array_upper(matrix, 1) LOOP
+            FOR y in array_lower(matrix, 2)..array_upper(matrix, 2) LOOP
+                IF _matrix[x][y] IS NULL THEN
+                    IF nodatamode = 'ignore' THEN
+                        _matrix[x][y] := 0;
+                    ELSE
+                        _matrix[x][y] := nodatamode::float;
+                    END IF;
+                END IF;
+                sum := sum + _matrix[x][y];
+            END LOOP;
+        END LOOP;
+        RETURN sum;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_mean4ma(matrix float[][], nodatamode text, variadic args text[])
+    RETURNS float AS
+    $$
+    DECLARE
+        _matrix float[][];
+        sum float;
+        count float;
+    BEGIN
+        _matrix := matrix;
+        sum := 0;
+        count := 0;
+        FOR x in array_lower(matrix, 1)..array_upper(matrix, 1) LOOP
+            FOR y in array_lower(matrix, 2)..array_upper(matrix, 2) LOOP
+                IF _matrix[x][y] IS NULL THEN
+                    IF nodatamode = 'ignore' THEN
+                        _matrix[x][y] := 0;
+                    ELSE
+                        _matrix[x][y] := nodatamode::float;
+                        count := count + 1;
+                    END IF;
+                ELSE
+                    count := count + 1;
+                END IF;
+                sum := sum + _matrix[x][y];
+            END LOOP;
+        END LOOP;
+        IF count = 0 THEN
+            RETURN NULL;
+        END IF;
+        RETURN sum / count;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_range4ma(matrix float[][], nodatamode text, variadic args text[])
+    RETURNS float AS
+    $$
+    DECLARE
+        _matrix float[][];
+        min float;
+        max float;
+    BEGIN
+        _matrix := matrix;
+        min := 'Infinity'::float;
+        max := '-Infinity'::float;
+        FOR x in array_lower(matrix, 1)..array_upper(matrix, 1) LOOP
+            FOR y in array_lower(matrix, 2)..array_upper(matrix, 2) LOOP
+                IF _matrix[x][y] IS NULL THEN
+                    IF NOT nodatamode = 'ignore' THEN
+                        _matrix[x][y] := nodatamode::float;
+                    END IF;
+                END IF;
+                IF min > _matrix[x][y] THEN
+                    min = _matrix[x][y];
+                END IF;
+                IF max < _matrix[x][y] THEN
+                    max = _matrix[x][y];
+                END IF;
+            END LOOP;
+        END LOOP;
+        IF max = '-Infinity'::float OR min = 'Infinity'::float THEN
+            RETURN NULL;
+        END IF;
+        RETURN max - min;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
+
+
 -----------------------------------------------------------------------
 -- Get information about the raster
 -----------------------------------------------------------------------
index ebbd41906c4049b8b9e838344da366c3d2e75341..1fce1e272f5dd6964bfe298bc82921725ef3914a 100644 (file)
@@ -92,7 +92,8 @@ TEST_UTILITY = \
        rt_mapalgebrafct_2raster.sql \
     create_rt_mapalgebrafctngb_test.sql \
     rt_mapalgebrafctngb.sql \
-       rt_reclass.sql \
+       rt_mapalgebrafctngb_userfunc.sql \
+    rt_reclass.sql \
        rt_resample.sql \
        rt_asraster.sql \
        $(NULL)
index aa2ec67c2a25654d96507045799a67e3139948fb..b4b323e2d104ffb252343e7f8c8fa853d112f844 100644 (file)
@@ -1,36 +1,6 @@
 --
--- A simple 'callback' user function that sums up all the values in a neighborhood.
+-- A user callback function that nullifies all cells in the resulting raster.
 --
-CREATE OR REPLACE FUNCTION ST_Sum(matrix float[][], nodatamode text, variadic args text[])
-    RETURNS float AS
-    $$
-    DECLARE
-        _matrix float[][];
-        x1 integer;
-        x2 integer;
-        y1 integer;
-        y2 integer;
-        sum float;
-    BEGIN
-        _matrix := matrix;
-        sum := 0;
-        FOR x in array_lower(matrix, 1)..array_upper(matrix, 1) LOOP
-            FOR y in array_lower(matrix, 2)..array_upper(matrix, 2) LOOP
-                IF _matrix[x][y] IS NULL THEN
-                    IF nodatamode = 'ignore' THEN
-                        _matrix[x][y] := 0;
-                    ELSE
-                        _matrix[x][y] := nodatamode::float;
-                    END IF;
-                END IF;
-                sum := sum + _matrix[x][y];
-            END LOOP;
-        END LOOP;
-        RETURN sum;
-    END;
-    $$
-    LANGUAGE 'plpgsql' IMMUTABLE;
-
 CREATE OR REPLACE FUNCTION ST_Nullage(matrix float[][], nodatamode text, VARIADIC args text[])
     RETURNS float AS
     $$
index ec59d8486950f57bc340ad2ccd8ca670d19ba60e..77ebd4e12040163a47594a905d99a9fbbabba93e 100644 (file)
@@ -1,18 +1,18 @@
 -- Tests
 -- Test NULL Raster. Should be true.
-SELECT ST_MapAlgebraFctNgb(NULL, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL) IS NULL FROM ST_TestRasterNgb(0, 0, -1) rast;
+SELECT ST_MapAlgebraFctNgb(NULL, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL) IS NULL FROM ST_TestRasterNgb(0, 0, -1) rast;
 
 -- Test empty Raster. Should be true.
-SELECT ST_IsEmpty(ST_MapAlgebraFctNgb(ST_MakeEmptyRaster(0, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL));
+SELECT ST_IsEmpty(ST_MapAlgebraFctNgb(ST_MakeEmptyRaster(0, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL));
 
 -- Test has no band raster. Should be true
-SELECT ST_HasNoBand(ST_MapAlgebraFctNgb(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL));
+SELECT ST_HasNoBand(ST_MapAlgebraFctNgb(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL));
 
 -- Test huge neighborhood. Original raster returned.
 SELECT
   ST_Value(rast, 2, 2) = 1,
   ST_Value(ST_MapAlgebraFctNgb(
-      rast, 1, NULL, 5, 5, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL
+      rast, 1, NULL, 5, 5, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL
     ), 2, 2) = 1
  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
 
@@ -21,7 +21,7 @@ SELECT
   ST_Value(rast, 2, 2) = 1,
   ST_Value(
     ST_MapAlgebraFctNgb(
-      rast, 1, NULL, -1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL
+      rast, 1, NULL, -1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL
     ), 2, 2) = 1
  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
 
@@ -30,7 +30,7 @@ SELECT
   ST_Value(rast, 2, 2) = 1,
   ST_Value(
     ST_MapAlgebraFctNgb(
-      rast, 1, NULL, 1, -1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL
+      rast, 1, NULL, 1, -1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL
     ), 2, 2) = 1
  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
 
@@ -39,7 +39,7 @@ SELECT
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
     ST_MapAlgebraFctNgb(
-      ST_SetBandNoDataValue(rast, NULL), 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL
+      ST_SetBandNoDataValue(rast, NULL), 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL
     ), 2, 2) = 7
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -47,7 +47,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
   ) IS NULL
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -55,7 +55,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
   ) = 8
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -63,7 +63,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'ignore', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'ignore', NULL), 2, 2
   ) = 8
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -71,7 +71,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'value', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'value', NULL), 2, 2
   ) IS NULL 
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -79,7 +79,7 @@ SELECT
 SELECT 
   ST_Value(rast, 1, 1) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'value', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'value', NULL), 2, 2
   ) = 9
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 1, 1, NULL) AS rast;
 
@@ -87,7 +87,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, '-8', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, '-8', NULL), 2, 2
   ) = 0
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -95,7 +95,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, '120', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, '120', NULL), 2, 2
   ) = 128
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -103,7 +103,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'abcd', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'abcd', NULL), 2, 2
   ) IS NULL
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 2, 2, NULL) AS rast;
 
@@ -111,7 +111,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) = 1, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
   ) = 9
  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
 
@@ -119,7 +119,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) IS NULL, 
   ST_Value(
-    ST_MapAlgebraFctNgb(ST_SetBandNoDataValue(rast, NULL), 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
+    ST_MapAlgebraFctNgb(ST_SetBandNoDataValue(rast, NULL), 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
   ) = -1
  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 0), 2, 2, NULL) AS rast;
 
@@ -127,7 +127,7 @@ SELECT
 SELECT
   ST_Value(rast, 2, 2) = 2,
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, '4BUI', 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, '4BUI', 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
   ) = 15
  FROM ST_SetBandNoDataValue(ST_TestRasterNgb(3, 3, 2), 1, NULL) AS rast;
 
@@ -135,7 +135,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) = 2, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, '4BUId', 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, '4BUId', 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
   ) = 18
  FROM ST_TestRasterNgb(3, 3, 2) AS rast;
 
@@ -143,7 +143,7 @@ SELECT
 SELECT 
   ST_Value(rast, 2, 2) = 1, 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, '2BUI', 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, '2BUI', 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 2, 2
   ) = 3
  FROM ST_SetBandNoDataValue(ST_TestRasterNgb(3, 3, 1), 1, NULL) AS rast;
 
@@ -152,7 +152,7 @@ SELECT
   COUNT(*) = 1
  FROM (SELECT
     (ST_DumpAsPolygons(
-      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL)
+      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL)
     )).*
    FROM ST_TestRasterNgb(5, 5, 1) AS rast) AS foo;
 
@@ -161,7 +161,7 @@ SELECT
   ST_Area(geom) = 8, val = 9
  FROM (SELECT
     (ST_DumpAsPolygons(
-      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL)
+      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL)
     )).*
    FROM ST_SetValue(ST_TestRasterNgb(5, 5, 1), 1, 1, NULL) AS rast) AS foo;
 
@@ -171,7 +171,7 @@ SELECT
   (ST_Area(geom) = 1 AND val = 8) OR (ST_Area(geom) = 8 AND val = 9)
  FROM (SELECT
     (ST_DumpAsPolygons(
-      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'ignore', NULL)
+      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'ignore', NULL)
     )).*
    FROM ST_SetValue(ST_TestRasterNgb(5, 5, 1), 1, 1, NULL) AS rast) AS foo;
 
@@ -187,7 +187,7 @@ SELECT
   ST_Area(ST_BuildArea(ST_InteriorRingN(geom, 1))) = 9
  FROM (SELECT
     (ST_DumpAsPolygons(
-      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL)
+      ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL)
     )).*
    FROM ST_SetValue(ST_TestRasterNgb(7, 7, 1), 4, 4, NULL) AS rast) AS foo;
 
@@ -198,7 +198,7 @@ SELECT
  FROM (SELECT
     (ST_DumpAsPolygons(
       ST_MapAlgebraFctNgb(
-        ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'ignore', NULL), 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'ignore', NULL
+        ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'ignore', NULL), 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'ignore', NULL
       )
     )).*
    FROM ST_TestRasterNgb(5, 5, 1) AS rast) AS foo;
@@ -210,7 +210,7 @@ SELECT
  FROM (SELECT
     (ST_DumpAsPolygons(
       ST_MapAlgebraFctNgb(
-        ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL), 1, NULL, 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, 'NULL', NULL
+        ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL), 1, NULL, 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, 'NULL', NULL
       )
     )).*
    FROM ST_TestRasterNgb(5, 5, 1) AS rast) AS foo;
@@ -228,6 +228,6 @@ SELECT
 -- expect that the cells processed by the neighborhoods would be replaced by the 'nodatamode' parameter value, and not NODATA.
 SELECT 
   ST_Value(
-    ST_MapAlgebraFctNgb(rast, 1, '8BUI', 1, 1, 'ST_Sum(float[][], text, text[])'::regprocedure, '120', NULL), 2, 2
+    ST_MapAlgebraFctNgb(rast, 1, '8BUI', 1, 1, 'ST_Sum4ma(float[][], text, text[])'::regprocedure, '120', NULL), 2, 2
   ) = 200
 FROM ST_SetValue(ST_SetBandNoDataValue(ST_TestRasterNgb(3, 3, 10), 0), 2, 2, 0) AS rast;
diff --git a/raster/test/regress/rt_mapalgebrafctngb_userfunc.sql b/raster/test/regress/rt_mapalgebrafctngb_userfunc.sql
new file mode 100644 (file)
index 0000000..e5e7afc
--- /dev/null
@@ -0,0 +1,98 @@
+-- test st_max4ma, uniform values
+SELECT
+  ST_Value(rast, 2, 2) = 1,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_max4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 1
+  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
+
+-- test st_max4ma, obvious max value
+SELECT
+  ST_Value(rast, 2, 2) = 1,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_max4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 11
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 1, 1, 11) AS rast;
+
+-- test st_max4ma, value substitution
+SELECT
+  ST_Value(rast, 2, 2) = 1,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_max4ma(float[][], text, text[])'::regprocedure, '22', NULL), 2, 2
+  ) = 22 
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 1), 3, 3, NULL) AS rast;
+
+-- test st_min4ma, uniform values
+SELECT
+  ST_Value(rast, 2, 2) = 1,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_min4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 1
+  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
+
+-- test st_min4ma, obvious min value
+SELECT
+  ST_Value(rast, 2, 2) = 11,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_min4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 1
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 11), 1, 1, 1) AS rast;
+
+-- test st_min4ma, value substitution
+SELECT
+  ST_Value(rast, 2, 2) = 22,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_min4ma(float[][], text, text[])'::regprocedure, '2', NULL), 2, 2
+  ) = 2 
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 22), 3, 3, NULL) AS rast;
+
+-- test st_sum4ma happens in rt_mapalgebrafctngb.sql
+
+-- test st_mean4ma, uniform values
+SELECT
+  ST_Value(rast, 2, 2) = 1,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_mean4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 1
+  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
+
+-- test st_mean4ma, obvious min value
+SELECT
+  ST_Value(rast, 2, 2) = 10,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_mean4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 9
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 10), 1, 1, 1) AS rast;
+
+-- test st_mean4ma, value substitution
+SELECT
+  ST_Value(rast, 2, 2) = 10,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_mean4ma(float[][], text, text[])'::regprocedure, '1', NULL), 2, 2
+  ) = 9 
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 10), 3, 3, NULL) AS rast;
+
+-- test st_range4ma, uniform values
+SELECT
+  ST_Value(rast, 2, 2) = 1,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_range4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 0
+  FROM ST_TestRasterNgb(3, 3, 1) AS rast;
+
+-- test st_range4ma, obvious min value
+SELECT
+  ST_Value(rast, 2, 2) = 10,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_range4ma(float[][], text, text[])'::regprocedure, NULL, NULL), 2, 2
+  ) = 9
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 10), 1, 1, 1) AS rast;
+
+-- test st_range4ma, value substitution
+SELECT
+  ST_Value(rast, 2, 2) = 10,
+  ST_Value(
+    ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'st_range4ma(float[][], text, text[])'::regprocedure, '1', NULL), 2, 2
+  ) = 9 
+  FROM ST_SetValue(ST_TestRasterNgb(3, 3, 10), 3, 3, NULL) AS rast;
+
diff --git a/raster/test/regress/rt_mapalgebrafctngb_userfunc_expected b/raster/test/regress/rt_mapalgebrafctngb_userfunc_expected
new file mode 100644 (file)
index 0000000..2608f28
--- /dev/null
@@ -0,0 +1,20 @@
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+NOTICE:  Neighborhood NODATA behavior defaulting to 'ignore'
+t|t
+t|t