From 48aa18980ecb89d72c5d3190a66360c430e674bd Mon Sep 17 00:00:00 2001 From: Bborie Park Date: Tue, 31 Jul 2012 23:44:08 +0000 Subject: [PATCH] Added ST_SetValues for setting an area defined by x, y, width and height to one value. Also added function parameter "keepnodata". git-svn-id: http://svn.osgeo.org/postgis/trunk@10147 b70326c6-7e19-0410-871a-916f4a2858ee --- raster/rt_pg/rt_pg.c | 32 +++++++++++++++++++++++++++++++- raster/rt_pg/rtpostgis.sql.in.c | 24 +++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c index a1f9f6cb3..dabb75134 100644 --- a/raster/rt_pg/rt_pg.c +++ b/raster/rt_pg/rt_pg.c @@ -2507,7 +2507,12 @@ Datum RASTER_setPixelValuesArray(PG_FUNCTION_ARGS) int numpixval = 0; int dimpixval[2] = {1, 1}; int dimnoset[2] = {1, 1}; + int hasnodata = FALSE; double nodataval = 0; + bool keepnodata = FALSE; + + int rtn = 0; + double val = 0; int i = 0; int j = 0; @@ -2789,6 +2794,10 @@ Datum RASTER_setPixelValuesArray(PG_FUNCTION_ARGS) } #endif + /* keepnodata flag */ + if (!PG_ARGISNULL(6)) + keepnodata = PG_GETARG_BOOL(6); + /* get band */ band = rt_raster_get_band(raster, nband - 1); if (!band) { @@ -2800,7 +2809,8 @@ Datum RASTER_setPixelValuesArray(PG_FUNCTION_ARGS) /* get band nodata info */ /* has NODATA, use NODATA */ - if (rt_band_get_hasnodata_flag(band)) + hasnodata = rt_band_get_hasnodata_flag(band); + if (hasnodata) nodataval = rt_band_get_nodata(band); /* no NODATA, use min possible value */ else @@ -2824,6 +2834,26 @@ Datum RASTER_setPixelValuesArray(PG_FUNCTION_ARGS) continue; } + /* if hasnodata = TRUE and keepnodata = TRUE, inspect pixel value */ + if (hasnodata && keepnodata) { + rtn = rt_band_get_pixel(band, pixval[i].x, pixval[i].y, &val); + if (rtn != 0) { + elog(ERROR, "Cannot get value of pixel. Returning NULL"); + pfree(pixval); + rt_raster_destroy(raster); + PG_FREE_IF_COPY(pgraster, 0); + PG_RETURN_NULL(); + } + + /* pixel value = NODATA, skip */ + if ( + FLT_EQ(val, nodataval) || + rt_band_clamped_value_is_nodata(band, val) == 1 + ) { + continue; + } + } + if (pixval[i].nodata) rt_band_set_pixel(band, pixval[i].x, pixval[i].y, nodataval); else diff --git a/raster/rt_pg/rtpostgis.sql.in.c b/raster/rt_pg/rtpostgis.sql.in.c index 995de9350..bef1cf47a 100644 --- a/raster/rt_pg/rtpostgis.sql.in.c +++ b/raster/rt_pg/rtpostgis.sql.in.c @@ -2921,12 +2921,34 @@ CREATE OR REPLACE FUNCTION st_setvalues( nband integer, x integer, y integer, newvalueset double precision[][], - noset boolean[][] DEFAULT NULL + noset boolean[][] DEFAULT NULL, + keepnodata boolean DEFAULT FALSE ) RETURNS raster AS 'MODULE_PATHNAME', 'RASTER_setPixelValuesArray' LANGUAGE 'c' IMMUTABLE; +-- cannot be STRICT as newvalue can be NULL +CREATE OR REPLACE FUNCTION st_setvalues( + rast raster, + nband integer, + x integer, y integer, + width integer, height integer, + newvalue double precision, + keepnodata boolean DEFAULT FALSE +) + RETURNS raster AS + $$ + BEGIN + IF width <= 0 OR height <= 0 THEN + RAISE EXCEPTION 'Values for width and height must be greater than zero'; + RETURN NULL; + END IF; + RETURN st_setvalues($1, $2, $3, $4, array_fill(newvalue::double precision, ARRAY[height, width]::int[]), NULL, $8); + END; + $$ + LANGUAGE 'plpgsql' IMMUTABLE; + ----------------------------------------------------------------------- -- Raster Processing Functions ----------------------------------------------------------------------- -- 2.40.0