Replaced ST_MapAlgebraExpr's "nodatavalueexpr" parameter with "nodataval" and datatype changed from text to double precision. This makes this parameter the same as "nodatanodataval" found in ST_MapAlgebra2Expr.

Associated ticket is #866


git-svn-id: http://svn.osgeo.org/postgis/trunk@8110 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
Bborie Park 2011-11-08 00:00:51 +00:00
parent 0f62eb729c
commit 4a340dd97c
4 changed files with 29 additions and 113 deletions

View file

@ -2429,12 +2429,11 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
double newval = 0.0;
char *newexpr = NULL;
char *initexpr = NULL;
char *initndvexpr = NULL;
char *expression = NULL;
char *nodatavaluerepl = NULL;
int hasnodataval = 0;
double nodataval = 0.;
rt_pixtype newpixeltype;
int skipcomputation = 0;
char strnewnodatavalue[50];
char strnewval[50];
int count = 0;
int len = 0;
@ -2443,7 +2442,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
SPITupleTable * tuptable = NULL;
HeapTuple tuple;
char * strFromText = NULL;
bool freemem = FALSE;
POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebraExpr: Starting...");
@ -2646,90 +2644,26 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
/**
* Optimization: If a nodatavaluerepl is provided, recompute the initial
* value. Then, we can initialize the raster with this value and skip the
* Optimization: If a nodataval is provided, use it for newinitialvalue.
* Then, we can initialize the raster with this value and skip the
* computation of nodata values one by one in the main computing loop
**/
if (!PG_ARGISNULL(4)) {
nodatavaluerepl = text_to_cstring(PG_GETARG_TEXT_P(4));
len = strlen("SELECT ") + strlen(nodatavaluerepl);
initndvexpr = (char *)palloc(len + 1);
strncpy(initndvexpr, "SELECT ", strlen("SELECT "));
strncpy(initndvexpr + strlen("SELECT "), strtoupper(nodatavaluerepl),
strlen(nodatavaluerepl));
initndvexpr[len] = '\0';
/*
lwfree(nodatavaluerepl);
nodatavaluerepl = NULL;
*/
/* Replace RAST, if present, for NODATA value, to eval the expression */
if (strstr(initndvexpr, "RAST")) {
sprintf(strnewnodatavalue, "%f", newnodatavalue);
newexpr = replace(initndvexpr, "RAST", strnewnodatavalue, &count);
freemem = TRUE;
}
/* If newexpr reduces to a constant, simply eval it */
else {
newexpr = initndvexpr;
}
POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: initndvexpr = %s", newexpr);
/* Eval the NODATA expression to get new NODATA. Connect with SPI manager
* NOTE: This creates a NEW memory context and makes it current.
*/
SPI_connect();
/**
* Execute the expression for nodata value and store the result as new
* initial value
**/
ret = SPI_execute(newexpr, FALSE, 0);
if (ret != SPI_OK_SELECT || SPI_tuptable == NULL ||
SPI_processed != 1) {
elog(ERROR, "RASTER_mapAlgebraExpr: Invalid construction for nodata "
"expression. Aborting");
if (SPI_tuptable)
SPI_freetuptable(tuptable);
/* Disconnect from SPI manager */
SPI_finish();
PG_RETURN_NULL();
}
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
tuple = tuptable->vals[0];
newinitialvalue = atof(SPI_getvalue(tuple, tupdesc, 1));
SPI_freetuptable(tuptable);
/* Close the connection to SPI manager.
* NOTE: This restores the previous memory context
*/
SPI_finish();
if (freemem)
pfree(newexpr);
hasnodataval = 1;
nodataval = PG_GETARG_FLOAT8(4);
newinitialvalue = nodataval;
POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new initial value = %f",
newinitialvalue);
}
else
hasnodataval = 0;
/**
* Optimization: If the raster is only filled with nodata values return
* right now a raster filled with the nodatavaluerepl
* right now a raster filled with the newinitialvalue
* TODO: Call rt_band_check_isnodata instead?
**/
if (rt_band_get_isnodata_flag(band)) {
@ -2751,8 +2685,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
SET_VARSIZE(pgraster, pgraster->size);
/* Free memory */
if (initndvexpr)
pfree(initndvexpr);
if (initexpr)
pfree(initexpr);
rt_raster_destroy(raster);
@ -2763,13 +2695,10 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
/**
* Optimization: If expression resume to 'RAST' and nodatavaluerepl is NULL
* or also equal to 'RAST', we can just return the band from the original
* raster
* Optimization: If expression resume to 'RAST' and hasnodataval is zero,
* we can just return the band from the original raster
**/
if (initexpr != NULL && !strcmp(initexpr, "SELECT RAST") &&
(nodatavaluerepl == NULL || !strcmp(initndvexpr, "SELECT RAST"))) {
/* (initndvexpr == NULL || !strcmp(initndvexpr, "SELECT RAST"))) { */
if (initexpr != NULL && !strcmp(initexpr, "SELECT RAST") && !hasnodataval) {
POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression resumes to RAST. "
"Returning raster with band %d from original raster", nband);
@ -2792,8 +2721,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
SET_VARSIZE(pgraster, pgraster->size);
if (initndvexpr)
pfree(initndvexpr);
if (initexpr)
pfree(initexpr);
rt_raster_destroy(raster);
@ -2844,8 +2771,7 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
* Compute the new value, set it and we will return after creating the
* new raster
**/
/*if (initndvexpr == NULL) {*/
if (nodatavaluerepl == NULL) {
if (!hasnodataval) {
newinitialvalue = newval;
skipcomputation = 2;
}
@ -2882,8 +2808,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
SET_VARSIZE(pgraster, pgraster->size);
/* Free memory */
if (initndvexpr)
pfree(initndvexpr);
if (initexpr)
pfree(initexpr);
rt_raster_destroy(raster);
@ -2911,8 +2835,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
SET_VARSIZE(pgraster, pgraster->size);
if (initndvexpr)
pfree(initndvexpr);
if (initexpr)
pfree(initexpr);
rt_raster_destroy(raster);
@ -2996,8 +2918,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
pgraster = rt_raster_serialize(newrast);
if (NULL == pgraster) {
/* Free memory allocated out of the current context */
if (initndvexpr)
pfree(initndvexpr);
if (initexpr)
pfree(initexpr);
rt_raster_destroy(raster);
@ -3011,8 +2931,6 @@ Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster serialized");
/* Free memory */
if (initndvexpr)
pfree(initndvexpr);
if (initexpr)
pfree(initexpr);

View file

@ -1589,18 +1589,18 @@ CREATE OR REPLACE FUNCTION st_snaptogrid(rast raster, gridx double precision, gr
-----------------------------------------------------------------------
-- One Raster ST_MapAlgebra
-----------------------------------------------------------------------
-- This function can not be STRICT, because nodatavaluerepl can be NULL (could be just '' though)
-- This function can not be STRICT, because nodataval can be NULL
-- or pixeltype can not be determined (could be st_bandpixeltype(raster, band) though)
CREATE OR REPLACE FUNCTION st_mapalgebraexpr(rast raster, band integer, pixeltype text,
expression text, nodatavaluerepl text DEFAULT NULL)
expression text, nodataval double precision DEFAULT NULL)
RETURNS raster
AS 'MODULE_PATHNAME', 'RASTER_mapAlgebraExpr'
LANGUAGE 'C' IMMUTABLE;
-- This function can not be STRICT, because nodatavaluerepl can be NULL (could be just '' though)
-- This function can not be STRICT, because nodataval can be NULL
-- or pixeltype can not be determined (could be st_bandpixeltype(raster, band) though)
CREATE OR REPLACE FUNCTION st_mapalgebraexpr(rast raster, pixeltype text, expression text,
nodatavaluerepl text DEFAULT NULL)
nodataval double precision DEFAULT NULL)
RETURNS raster
AS $$ SELECT st_mapalgebraexpr($1, 1, $2, $3, $4) $$
LANGUAGE SQL;

View file

@ -1,23 +1,23 @@
-- Test NULL raster
SELECT ST_MapAlgebraExpr(NULL, 1, NULL, 'rast + 20', '2') IS NULL FROM ST_TestRaster(0, 0, -1) rast;
SELECT ST_MapAlgebraExpr(NULL, 1, NULL, 'rast + 20', 2) IS NULL FROM ST_TestRaster(0, 0, -1) rast;
-- Test empty raster
SELECT ST_IsEmpty(ST_MapAlgebraExpr(ST_MakeEmptyRaster(0, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 'rast + 20', '2'));
SELECT ST_IsEmpty(ST_MapAlgebraExpr(ST_MakeEmptyRaster(0, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 'rast + 20', 2));
-- Test hasnoband raster
SELECT ST_HasNoBand(ST_MapAlgebraExpr(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 'rast + 20', '2'));
SELECT ST_HasNoBand(ST_MapAlgebraExpr(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 1, 1, -1), 1, NULL, 'rast + 20', 2));
-- Test hasnodata value
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(ST_SetBandNoDataValue(rast, NULL), 1, NULL, 'rast + 20', '2'), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(ST_SetBandNoDataValue(rast, NULL), 1, NULL, 'rast + 20', 2), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
-- Test nodata value
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, NULL, 'rast + 20', 'rast + 2'), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, NULL, 'rast + 20', 2), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
-- Test 'rast' expression
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, NULL, 'rast', 'rast'), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, NULL, 'rast', 2), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(ST_SetBandNoDataValue(rast, NULL), 1, NULL, 'rast', NULL), 1, 1) FROM ST_TestRaster(0, 0, -1) rast;
-- Test pixeltype
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, '4BUI', 'rast + 20', 'rast + 2'), 1, 1) FROM ST_TestRaster(0, 0, 100) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, '4BUId', 'rast + 20', 'rast + 2'), 1, 1) FROM ST_TestRaster(0, 0, 100) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, '2BUI', 'rast + 20', 'rast + 2'), 1, 1) FROM ST_TestRaster(0, 0, 101) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, '4BUI', 'rast + 20', 2), 1, 1) FROM ST_TestRaster(0, 0, 100) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, '4BUId', 'rast + 20', 2), 1, 1) FROM ST_TestRaster(0, 0, 100) rast;
SELECT ST_Value(rast, 1, 1), ST_Value(ST_MapAlgebraExpr(rast, 1, '2BUI', 'rast + 20', 2), 1, 1) FROM ST_TestRaster(0, 0, 101) rast;

View file

@ -5,10 +5,8 @@ t
NOTICE: Raster does not have the required band. Returning a raster without a band
t
|19
|1
NOTICE: rt_raster_copy_band: Second raster has no band
NOTICE: Could not find raster band of index 1 when getting pixel value. Returning NULL
|
|2
|2
NOTICE: rt_raster_copy_band: Second raster has no band
NOTICE: Could not find raster band of index 1 when getting pixel value. Returning NULL
|