]> granicus.if.org Git - postgis/commitdiff
Addition of flag nbnodata to rt_raster_iterator() thus allowing some
authorBborie Park <bkpark at ucdavis.edu>
Wed, 3 Oct 2012 23:07:09 +0000 (23:07 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Wed, 3 Oct 2012 23:07:09 +0000 (23:07 +0000)
memory savings from ST_Union(raster)

git-svn-id: http://svn.osgeo.org/postgis/trunk@10373 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_core/rt_api.c
raster/rt_core/rt_api.h
raster/rt_pg/rt_pg.c
raster/test/core/testapi.c

index e093d101cc5b177ba80ae956402ae4b44a4c1858..70b32f20ce23bb587658a772125be934885b9894 100644 (file)
@@ -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);
index a36f9a68a63d5a94c6e10a30902b22e9a4d8eb62..ac624d6f47607af90979280ff0240a961d490585 100644 (file)
@@ -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 */
index 51fee395052230885e5f1db48d8743d09a71c4b2..1b3209af10268c8d45f1ab5f976f5f71388afba3 100644 (file)
@@ -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,
index 50f36bb25b08480b6e30b213a99382f7df740a25..a99753726e6e44f0f807f64016be197a615a38b5 100644 (file)
@@ -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;