]> granicus.if.org Git - postgis/commitdiff
Added positional parameters to 1 raster version of ST_MapAlgebraFct. Closes #1525
authorDavid Zwarg <dzwarg@azavea.com>
Tue, 7 Feb 2012 19:25:08 +0000 (19:25 +0000)
committerDavid Zwarg <dzwarg@azavea.com>
Tue, 7 Feb 2012 19:25:08 +0000 (19:25 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9070 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_pg/rt_pg.c
raster/test/regress/create_rt_mapalgebra_test.sql
raster/test/regress/drop_rt_mapalgebra_test.sql
raster/test/regress/rt_mapalgebrafct.sql
raster/test/regress/rt_mapalgebrafct_expected

index 04fb35cce8d8ca32a9513d3eeb32edb8bb241df0..bd940888ce74201d78067def3cbd3ff62ab6c1de 100644 (file)
@@ -3187,6 +3187,7 @@ Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
     FunctionCallInfoData cbdata;
     Datum tmpnewval;
     char * strFromText = NULL;
+    int k = 0;
 
     POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebraFct: STARTING...");
 
@@ -3403,8 +3404,8 @@ Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
         PG_RETURN_NULL();
     }
     /* function should have correct # of args */
-    else if (cbinfo.fn_nargs != 2) {
-        elog(ERROR, "RASTER_mapAlgebraFct: Function does not have two input parameters");
+    else if (cbinfo.fn_nargs < 2 || cbinfo.fn_nargs > 3) {
+        elog(ERROR, "RASTER_mapAlgebraFct: Function does not have two or three input parameters");
 
         rt_raster_destroy(raster);
         rt_raster_destroy(newrast);
@@ -3412,6 +3413,11 @@ Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
         PG_RETURN_NULL();
     }
 
+    if (cbinfo.fn_nargs == 2)
+        k = 1;
+    else 
+        k = 2;
+
     if (func_volatile(oid) == 'v') {
         elog(NOTICE, "Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
     }
@@ -3422,7 +3428,7 @@ Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
 #else
     InitFunctionCallInfoData(cbdata, &cbinfo, 2, InvalidOid, NULL, NULL);
 #endif
-    memset(cbdata.argnull, FALSE, 2);
+    memset(cbdata.argnull, FALSE, cbinfo.fn_nargs);
     
     /* check that the function isn't strict if the args are null. */
     if (PG_ARGISNULL(4)) {
@@ -3435,11 +3441,11 @@ Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
             PG_RETURN_NULL();
         }
 
-        cbdata.arg[1] = (Datum)NULL;
-        cbdata.argnull[1] = TRUE;
+        cbdata.arg[k] = (Datum)NULL;
+        cbdata.argnull[k] = TRUE;
     }
     else {
-        cbdata.arg[1] = PG_GETARG_DATUM(4);
+        cbdata.arg[k] = PG_GETARG_DATUM(4);
     }
 
     /**
@@ -3528,6 +3534,20 @@ Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
                     cbdata.arg[0] = Float8GetDatum(r);
                 }
 
+                /* Add pixel positions if callback has proper # of args */
+                if (cbinfo.fn_nargs == 3) {
+                    Datum d[2];
+                    ArrayType *a;
+
+                    d[0] = Int32GetDatum(x+1);
+                    d[1] = Int32GetDatum(y+1);
+
+                    a = construct_array(d, 2, INT4OID, sizeof(int4), true, 'i');
+
+                    cbdata.argnull[1] = FALSE;
+                    cbdata.arg[1] = PointerGetDatum(a);
+                }
+
                 POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraFct: (%dx%d), r = %f",
                     x, y, r);
                    
index 416b7ebd83b64c5c7f8591b484c6a8f5fbd69b66..599c28f8b4f0741976b92f82d1b21eee6cc65773 100644 (file)
@@ -62,3 +62,31 @@ CREATE OR REPLACE FUNCTION raster_polynomial(pixel FLOAT, VARIADIC args TEXT[])
     END;
     $$
     LANGUAGE 'plpgsql' IMMUTABLE;
+
+ CREATE OR REPLACE FUNCTION raster_x_plus_arg(pixel FLOAT, pos INT[], VARIADIC args TEXT[])
+    RETURNS FLOAT AS
+    $$
+    DECLARE
+        x float := 0;
+    BEGIN
+        IF NOT args[1] IS NULL THEN
+            x := args[1]::float;
+        END IF;
+        RETURN pixel + pos[1] + x;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
+
+ CREATE OR REPLACE FUNCTION raster_y_plus_arg(pixel FLOAT, pos INT[], VARIADIC args TEXT[])
+    RETURNS FLOAT AS
+    $$
+    DECLARE
+        x float := 0;
+    BEGIN
+        IF NOT args[1] IS NULL THEN
+            x := args[1]::float;
+        END IF;
+        RETURN pixel + pos[2] + x;
+    END;
+    $$
+    LANGUAGE 'plpgsql' IMMUTABLE;
index 332a660269c9c180e373637123c9731ec9aed081..245ee3422a397bda32fd4fc48eae01ff7ef11bd0 100644 (file)
@@ -3,3 +3,5 @@ DROP FUNCTION raster_plus_twenty(pixel FLOAT, VARIADIC args TEXT[]);
 DROP FUNCTION raster_plus_arg1(pixel FLOAT, VARIADIC args TEXT[]);
 DROP FUNCTION raster_polynomial(pixel FLOAT, VARIADIC args TEXT[]);
 DROP FUNCTION raster_nullage(pixel FLOAT, VARIADIC args TEXT[]);
+DROP FUNCTION raster_x_plus_arg(pixel FLOAT, pos INT[], VARIADIC args TEXT[]);
+DROP FUNCTION raster_y_plus_arg(pixel FLOAT, pos INT[], VARIADIC args TEXT[]);
index b14daedc023fa85b26fb0e0377470349b0d2381a..e7437a9635c7d8965d3dfed4fec0562f100b77f9 100644 (file)
@@ -30,3 +30,6 @@ SELECT ST_Value(rast, 1, 1) * 21 + 14, ST_Value(ST_MapAlgebraFct(rast, 1, NULL,
 
 -- Test null return from a user function = NODATA cell value
 SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraFct(rast, 1, NULL, 'raster_nullage(float, text[])'::regprocedure), 1, 1) FROM ST_TestRaster(0, 0, 100) AS rast;
+
+SELECT ST_Value(rast, 3, 8) + 13 + 3, ST_Value(ST_MapAlgebraFct(rast, 1, NULL, 'raster_x_plus_arg(float, int[], text[])'::regprocedure, '13'), 3, 8) FROM ST_TestRaster(0, 0, 100) AS rast;
+SELECT ST_Value(rast, 3, 8) + 13 + 8, ST_Value(ST_MapAlgebraFct(rast, 1, NULL, 'raster_y_plus_arg(float, int[], text[])'::regprocedure, '13'), 3, 8) FROM ST_TestRaster(0, 0, 100) AS rast;
index 38f4eaaf414323cfdb61ad0853c1d4220921c135..ad9058ca670fd2fa97ba52441fd9e268f583518d 100644 (file)
@@ -120,3 +120,5 @@ NOTICE:  Pixel value is null.
 213|213
 6314|6314
 100|
+116|116
+121|121