From 4c2ed59e356ed026dc60e8b0c32acf110ed8abd3 Mon Sep 17 00:00:00 2001 From: David Zwarg Date: Tue, 7 Feb 2012 19:25:08 +0000 Subject: [PATCH] Added positional parameters to 1 raster version of ST_MapAlgebraFct. Closes #1525 git-svn-id: http://svn.osgeo.org/postgis/trunk@9070 b70326c6-7e19-0410-871a-916f4a2858ee --- raster/rt_pg/rt_pg.c | 32 +++++++++++++++---- .../regress/create_rt_mapalgebra_test.sql | 28 ++++++++++++++++ .../test/regress/drop_rt_mapalgebra_test.sql | 2 ++ raster/test/regress/rt_mapalgebrafct.sql | 3 ++ raster/test/regress/rt_mapalgebrafct_expected | 2 ++ 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c index 04fb35cce..bd940888c 100644 --- a/raster/rt_pg/rt_pg.c +++ b/raster/rt_pg/rt_pg.c @@ -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); diff --git a/raster/test/regress/create_rt_mapalgebra_test.sql b/raster/test/regress/create_rt_mapalgebra_test.sql index 416b7ebd8..599c28f8b 100644 --- a/raster/test/regress/create_rt_mapalgebra_test.sql +++ b/raster/test/regress/create_rt_mapalgebra_test.sql @@ -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; diff --git a/raster/test/regress/drop_rt_mapalgebra_test.sql b/raster/test/regress/drop_rt_mapalgebra_test.sql index 332a66026..245ee3422 100644 --- a/raster/test/regress/drop_rt_mapalgebra_test.sql +++ b/raster/test/regress/drop_rt_mapalgebra_test.sql @@ -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[]); diff --git a/raster/test/regress/rt_mapalgebrafct.sql b/raster/test/regress/rt_mapalgebrafct.sql index b14daedc0..e7437a963 100644 --- a/raster/test/regress/rt_mapalgebrafct.sql +++ b/raster/test/regress/rt_mapalgebrafct.sql @@ -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; diff --git a/raster/test/regress/rt_mapalgebrafct_expected b/raster/test/regress/rt_mapalgebrafct_expected index 38f4eaaf4..ad9058ca6 100644 --- a/raster/test/regress/rt_mapalgebrafct_expected +++ b/raster/test/regress/rt_mapalgebrafct_expected @@ -120,3 +120,5 @@ NOTICE: Pixel value is null. 213|213 6314|6314 100| +116|116 +121|121 -- 2.50.1