From: Bborie Park Date: Wed, 3 Oct 2012 23:07:09 +0000 (+0000) Subject: Addition of flag nbnodata to rt_raster_iterator() thus allowing some X-Git-Tag: 2.1.0beta2~585 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fdc512a4f2a65d1cc77232690a2ac582c638cb48;p=postgis Addition of flag nbnodata to rt_raster_iterator() thus allowing some memory savings from ST_Union(raster) git-svn-id: http://svn.osgeo.org/postgis/trunk@10373 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/raster/rt_core/rt_api.c b/raster/rt_core/rt_api.c index e093d101c..70b32f20c 100644 --- a/raster/rt_core/rt_api.c +++ b/raster/rt_core/rt_api.c @@ -13000,6 +13000,7 @@ _rti_param_populate( int *allnull, int *allempty ) { int i = 0; + int hasband = 0; _param->count = itrcount; _param->distance.x = distancex; @@ -13055,16 +13056,24 @@ _rti_param_populate( } /* check band number */ - if (!rt_raster_has_band(itrset[i].raster, itrset[i].nband)) { - rterror("_rti_param_populate: Band %d not found for raster %d", itrset[i].nband, i); - return 0; + hasband = rt_raster_has_band(itrset[i].raster, itrset[i].nband); + if (!hasband) { + if (!itrset[i].nbnodata) { + rterror("_rti_param_populate: Band %d not found for raster %d", itrset[i].nband, i); + return 0; + } + else { + RASTER_DEBUGF(4, "Band %d not found for raster %d. Using NODATA", itrset[i].nband, i); + } } _param->raster[i] = itrset[i].raster; - _param->band[i] = rt_raster_get_band(itrset[i].raster, itrset[i].nband); - if (_param->band[i] == NULL) { - rterror("_rti_param_populate: Unable to get band %d for raster %d", itrset[i].nband, i); - return 0; + if (hasband) { + _param->band[i] = rt_raster_get_band(itrset[i].raster, itrset[i].nband); + if (_param->band[i] == NULL) { + rterror("_rti_param_populate: Unable to get band %d for raster %d", itrset[i].nband, i); + return 0; + } } /* init offset */ @@ -13545,7 +13554,7 @@ rt_raster_iterator( ); /* init values and NODATA for use with empty rasters */ - if (allempty > 0 && !_rti_param_empty_init(_param)) { + if (!_rti_param_empty_init(_param)) { rterror("rt_raster_iterator: Unable to initialize empty values and NODATA"); _rti_param_destroy(_param); @@ -13631,8 +13640,9 @@ rt_raster_iterator( RASTER_DEBUGF(4, "raster %d", i); /* empty raster */ - if (_param->isempty[i]) { - RASTER_DEBUG(4, "empty raster. using empty values and NODATA"); + /* OR band does not exist and flag set to use NODATA */ + if (_param->isempty[i] || (_param->band[i] == NULL && itrset[i].nbnodata)) { + RASTER_DEBUG(4, "empty raster or band does not exist. using empty values and NODATA"); x = _x; y = _y; @@ -13762,6 +13772,7 @@ rt_raster_iterator( } /* callback */ + RASTER_DEBUG(4, "calling callback function"); value = 0; nodata = 0; status = callback(_param->arg, userarg, &value, &nodata); diff --git a/raster/rt_core/rt_api.h b/raster/rt_core/rt_api.h index a36f9a68a..ac624d6f4 100644 --- a/raster/rt_core/rt_api.h +++ b/raster/rt_core/rt_api.h @@ -2150,6 +2150,7 @@ struct rt_reclassexpr_t { struct rt_iterator_t { rt_raster raster; uint16_t nband; /* 0-based */ + uint8_t nbnodata; /* no band = treat as NODATA */ }; /* callback argument from raster iterator */ diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c index 51fee3950..1b3209af1 100644 --- a/raster/rt_pg/rt_pg.c +++ b/raster/rt_pg/rt_pg.c @@ -14093,31 +14093,9 @@ Datum RASTER_union_transfn(PG_FUNCTION_ARGS) break; numbands = rt_raster_get_num_bands(raster); - if (numbands == iwr->numband) + if (numbands <= iwr->numband) break; - /* incoming has fewer bands, add NODATA bands to incoming */ - /* TODO: have rt_raster_iterator() treat missing band as NODATA band? */ - if (numbands < iwr->numband) { - POSTGIS_RT_DEBUG(4, "input raster has fewer bands, adding NODATA bands"); - for (i = numbands; i < iwr->numband; i++) { - if (rt_raster_generate_new_band(raster, PT_8BUI, 0, 1, 0, i) < 0) { - elog(ERROR, "RASTER_union_transfn: Unable to create NODATA band"); - - rtpg_union_arg_destroy(iwr); - if (raster != NULL) { - rt_raster_destroy(raster); - PG_FREE_IF_COPY(pgraster, 1); - } - - MemoryContextSwitchTo(oldcontext); - PG_RETURN_NULL(); - } - } - - break; - } - /* more bands to process */ POSTGIS_RT_DEBUG(4, "input raster has more bands, adding more bandargs"); if (iwr->numband) @@ -14175,34 +14153,6 @@ Datum RASTER_union_transfn(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); PG_RETURN_NULL(); } - - /* create band of same type as input raster */ - _band = rt_raster_get_band(raster, i); - pixtype = rt_band_get_pixtype(_band); - hasnodata = rt_band_get_hasnodata_flag(_band); - if (hasnodata) - nodataval = rt_band_get_nodata(_band); - else - nodataval = rt_band_get_min_value(_band); - - if (rt_raster_generate_new_band( - iwr->bandarg[i].raster[0], - pixtype, - nodataval, - hasnodata, nodataval, - i - ) < 0) { - elog(ERROR, "RASTER_union_transfn: Unable to add new band to working raster"); - - rtpg_union_arg_destroy(iwr); - if (raster != NULL) { - rt_raster_destroy(raster); - PG_FREE_IF_COPY(pgraster, 1); - } - - MemoryContextSwitchTo(oldcontext); - PG_RETURN_NULL(); - } } } @@ -14285,6 +14235,17 @@ Datum RASTER_union_transfn(PG_FUNCTION_ARGS) itrset[1].raster = raster; itrset[1].nband = iwr->bandarg[i].nband; + /* no additional arguments in aggregate, allow use NODATA to replace missing bands */ + if (nargs < 3) { + itrset[0].nbnodata = 1; + itrset[1].nbnodata = 1; + } + /* additional arguments in aggregate, missing bands are not ignored */ + else { + itrset[0].nbnodata = 0; + itrset[1].nbnodata = 0; + } + /* pass everything to iterator */ _raster = rt_raster_iterator( itrset, 2, diff --git a/raster/test/core/testapi.c b/raster/test/core/testapi.c index 50f36bb25..a99753726 100644 --- a/raster/test/core/testapi.c +++ b/raster/test/core/testapi.c @@ -7845,8 +7845,10 @@ static void testRasterIterator() { itrset = rtalloc(sizeof(struct rt_iterator_t) * num); itrset[0].raster = rast1; itrset[0].nband = 0; + itrset[0].nbnodata = 1; itrset[1].raster = rast2; itrset[1].nband = 0; + itrset[1].nbnodata = 1; /* 1 raster, 0 distance, FIRST or SECOND or LAST or UNION or INTERSECTION */ userargs->rasters = 1;