]> granicus.if.org Git - postgis/commitdiff
Fixed issue where ST_AsRaster() may not return raster with specified
authorBborie Park <bkpark at ucdavis.edu>
Mon, 19 Nov 2012 23:18:59 +0000 (23:18 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Mon, 19 Nov 2012 23:18:59 +0000 (23:18 +0000)
pixel types. Ticket #2100

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

NEWS
raster/rt_core/rt_api.c
raster/test/regress/rt_asraster_expected

diff --git a/NEWS b/NEWS
index c88aab06b3d9289a5839bc3334a4b4bd5b101aaa..5f5a4cdca2ff6c49d9d7b51ff23ae979838fa8f5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -103,6 +103,7 @@ PostGIS 2.1.0
   - #2057, Fixed linking issue for raster2psql to libpq
   - #2077, Fixed incorrect values returning from ST_Hillshade()
   - #2019, ST_FlipCoordinates does not update bbox
+  - #2100, ST_AsRaster may not return raster with specified pixel type
 
 
 PostGIS 2.0.1
index 8becd3fcd34c8718ddfc007b11647150fabdf5f0..8302ba0a738f01254c18ad34279fc0dabb8e8b05 100644 (file)
@@ -10173,19 +10173,19 @@ _rti_rasterize_arg_init() {
 
 static void
 _rti_rasterize_arg_destroy(_rti_rasterize_arg arg) {
-       if (!arg->noband || !arg->numbands)
-               return;
+       if (arg->noband) {
+               if (arg->pixtype != NULL)
+                       rtdealloc(arg->pixtype);
+               if (arg->init != NULL)
+                       rtdealloc(arg->init);
+               if (arg->nodata != NULL)
+                       rtdealloc(arg->nodata);
+               if (arg->hasnodata != NULL)
+                       rtdealloc(arg->hasnodata);
+               if (arg->value != NULL)
+                       rtdealloc(arg->value);
+       }
 
-       if (arg->pixtype != NULL)
-               rtdealloc(arg->pixtype);
-       if (arg->init != NULL)
-               rtdealloc(arg->init);
-       if (arg->nodata != NULL)
-               rtdealloc(arg->nodata);
-       if (arg->hasnodata != NULL)
-               rtdealloc(arg->hasnodata);
-       if (arg->value != NULL)
-               rtdealloc(arg->value);
        if (arg->bandlist != NULL)
                rtdealloc(arg->bandlist);
 
@@ -10231,9 +10231,9 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
        double *skew_x, double *skew_y,
        char **options
 ) {
-       rt_raster rast;
+       rt_raster rast = NULL;
        int i = 0;
-       int banderr = 0;
+       int err = 0;
 
        _rti_rasterize_arg arg = NULL;
 
@@ -10256,6 +10256,9 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
        GDALDatasetH _ds = NULL;
        GDALRasterBandH _band = NULL;
 
+       uint16_t _width = 0;
+       uint16_t _height = 0;
+
        RASTER_DEBUG(3, "starting");
 
        assert(NULL != wkb);
@@ -10964,21 +10967,21 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
 
        /* set bands */
        for (i = 0; i < arg->numbands; i++) {
-               banderr = 0;
+               err = 0;
 
                do {
                        /* add band */
                        cplerr = GDALAddBand(_ds, rt_util_pixtype_to_gdal_datatype(arg->pixtype[i]), NULL);
                        if (cplerr != CE_None) {
                                rterror("rt_raster_gdal_rasterize: Unable to add band to GDALDataset");
-                               banderr = 1;
+                               err = 1;
                                break;
                        }
 
                        _band = GDALGetRasterBand(_ds, i + 1);
                        if (NULL == _band) {
                                rterror("rt_raster_gdal_rasterize: Unable to get band %d from GDALDataset", i + 1);
-                               banderr = 1;
+                               err = 1;
                                break;
                        }
 
@@ -10988,7 +10991,7 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
                                cplerr = GDALSetRasterNoDataValue(_band, arg->nodata[i]);
                                if (cplerr != CE_None) {
                                        rterror("rt_raster_gdal_rasterize: Unable to set nodata value");
-                                       banderr = 1;
+                                       err = 1;
                                        break;
                                }
                                RASTER_DEBUGF(4, "NODATA value set to %f", GDALGetRasterNoDataValue(_band, NULL));
@@ -10998,13 +11001,13 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
                        cplerr = GDALFillRaster(_band, arg->init[i], 0);
                        if (cplerr != CE_None) {
                                rterror("rt_raster_gdal_rasterize: Unable to set initial value");
-                               banderr = 1;
+                               err = 1;
                                break;
                        }
                }
                while (0);
 
-               if (banderr) {
+               if (err) {
                        _rti_rasterize_arg_destroy(arg);
 
                        OGR_G_DestroyGeometry(src_geom);
@@ -11020,6 +11023,7 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
        arg->bandlist = (int *) rtalloc(sizeof(int) * arg->numbands);
        for (i = 0; i < arg->numbands; i++) arg->bandlist[i] = i + 1;
 
+
        /* burn geometry */
        cplerr = GDALRasterizeGeometries(
                _ds,
@@ -11030,10 +11034,11 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
                options,
                NULL, NULL
        );
-       _rti_rasterize_arg_destroy(arg);
        if (cplerr != CE_None) {
                rterror("rt_raster_gdal_rasterize: Unable to rasterize geometry");
 
+               _rti_rasterize_arg_destroy(arg);
+
                OGR_G_DestroyGeometry(src_geom);
                OSRDestroySpatialReference(src_sr);
                /* OGRCleanupAll(); */
@@ -11059,6 +11064,110 @@ rt_raster_gdal_rasterize(const unsigned char *wkb,
                return NULL;
        }
 
+       /* width, height */
+       _width = rt_raster_get_width(rast);
+       _height = rt_raster_get_height(rast);
+
+       /* check each band for pixtype */
+       for (i = 0; i < arg->numbands; i++) {
+               uint8_t *data = NULL;
+               rt_band band = NULL;
+               rt_band oldband = NULL;
+
+               double val = 0;
+               int nodata = 0;
+               int hasnodata = 0;
+               double nodataval = 0;
+               int x = 0;
+               int y = 0;
+
+               oldband = rt_raster_get_band(rast, i);
+               if (oldband == NULL) {
+                       rterror("rt_raster_gdal_rasterize: Unable to get band %d of output raster", i);
+                       _rti_rasterize_arg_destroy(arg);
+                       rt_raster_destroy(rast);
+                       return NULL;
+               }
+
+               /* band is of user-specified type */
+               if (rt_band_get_pixtype(oldband) == arg->pixtype[i])
+                       continue;
+
+               /* hasnodata, nodataval */
+               hasnodata = rt_band_get_hasnodata_flag(oldband);
+               if (hasnodata)
+                       rt_band_get_nodata(oldband, &nodataval);
+
+               /* allocate data */
+               data = rtalloc(rt_pixtype_size(arg->pixtype[i]) * _width * _height);
+               if (data == NULL) {
+                       rterror("rt_raster_gdal_rasterize: Could not allocate memory for band data");
+                       _rti_rasterize_arg_destroy(arg);
+                       rt_raster_destroy(rast);
+                       return NULL;
+               }
+               memset(data, 0, rt_pixtype_size(arg->pixtype[i]) * _width * _height);
+
+               /* create new band of correct type */
+               band = rt_band_new_inline(
+                       _width, _height,
+                       arg->pixtype[i],
+                       hasnodata, nodataval,
+                       data
+               );
+               if (band == NULL) {
+                       rterror("rt_raster_gdal_rasterize: Unable to create band");
+                       rtdealloc(data);
+                       _rti_rasterize_arg_destroy(arg);
+                       rt_raster_destroy(rast);
+                       return NULL;
+               }
+
+               /* give ownership of data to band */
+               rt_band_set_ownsdata_flag(band, 1);
+
+               /* copy pixel by pixel */
+               for (x = 0; x < _width; x++) {
+                       for (y = 0; y < _height; y++) {
+                               err = rt_band_get_pixel(oldband, x, y, &val, &nodata);
+                               if (err != 0) {
+                                       rterror("rt_raster_gdal_rasterize: Unable to get pixel value");
+                                       _rti_rasterize_arg_destroy(arg);
+                                       rt_raster_destroy(rast);
+                                       rt_band_destroy(band);
+                                       return NULL;
+                               }
+
+                               if (nodata)
+                                       val = nodataval;
+
+                               err = rt_band_set_pixel(band, x, y, val);
+                               if (err < 0) {
+                                       rterror("rt_raster_gdal_rasterize: Unable to set pixel value");
+                                       _rti_rasterize_arg_destroy(arg);
+                                       rt_raster_destroy(rast);
+                                       rt_band_destroy(band);
+                                       return NULL;
+                               }
+                       }
+               }
+
+               /* replace band */
+               oldband = rt_raster_replace_band(rast, band, i);
+               if (oldband == NULL) {
+                       rterror("rt_raster_gdal_rasterize: Unable to replace band %d of output raster", i);
+                       _rti_rasterize_arg_destroy(arg);
+                       rt_raster_destroy(rast);
+                       rt_band_destroy(band);
+                       return NULL;
+               }
+
+               /* free oldband */
+               rt_band_destroy(oldband);
+       }
+
+       _rti_rasterize_arg_destroy(arg);
+
        RASTER_DEBUG(3, "done");
 
        return rast;
index f9b6b4556b858148ecb4a914338a5f7b758853b0..dafd25e0641c9dcd01f3d84498af21379f5c5aaf 100644 (file)
@@ -17,7 +17,7 @@ NOTICE:  The two rasters provided have different scales on the X axis
 1.0||||||||||||||||
 1.1|993310|100|100|1|1406.537|-869.114|0.000|0.000|-175453.086|114987.661|8BUI|0.000|t|1.000|1.000|
 1.10|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|32BF|0.000|t|1.000|1.000|
-1.11|993310|100|100|1|1406.537|-869.114|0.000|0.000|-175453.086|114987.661|16BSI|0.000|t|1.000|1.000|
+1.11|993310|100|100|1|1406.537|-869.114|0.000|0.000|-175453.086|114987.661|8BSI|0.000|t|1.000|1.000|
 1.12|993310|100|100|1|1406.537|-869.114|0.000|0.000|-175453.086|114987.661|16BUI|0.000|t|1.000|1.000|
 1.13|993310|100|100|1|1406.537|-869.114|0.000|0.000|-175453.086|114987.661|32BF|0.000|t|255.000|255.000|
 1.14|993310|100|100|1|1406.537|-869.114|0.000|0.000|-175453.086|114987.661|32BF|1.000|t|255.000|255.000|
@@ -27,13 +27,13 @@ NOTICE:  The two rasters provided have different scales on the X axis
 1.18|993310|10|10|2|14065.366|-8691.142|0.000|0.000|-175453.086|114987.661|8BUI|0.000|t|255.000|255.000|
 1.19|993310|141|87|3|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|32BF||t|0.000|255.000|
 1.2|993310|1407|869|1|100.000|-100.000|0.000|0.000|-175453.086|114987.661|8BUI|0.000|t|1.000|1.000|
-1.20|993310|141|87|2|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|8BUI|1.000|f|||
+1.20|993310|141|87|2|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|1BB|1.000|f|||
 1.3|993310|500|500|1|281.307|-173.823|0.000|0.000|-175453.086|114987.661|8BUI|0.000|t|1.000|1.000|
 1.4|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|8BUI|0.000|t|1.000|1.000|
-1.5|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|16BSI|0.000|t|1.000|1.000|
+1.5|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|8BSI|0.000|t|1.000|1.000|
 1.6|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|16BUI|0.000|t|1.000|1.000|
 1.7|993310|1407|869|1|100.000|-100.000|0.000|0.000|-175453.086|114987.661|32BF|0.000|t|1.000|1.000|
-1.8|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|16BSI|0.000|t|1.000|1.000|
+1.8|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|8BSI|0.000|t|1.000|1.000|
 1.9|993310|141|87|1|1000.000|-1000.000|0.000|0.000|-175453.086|114987.661|16BUI|0.000|t|1.000|1.000|
 2.0||||||||||||||||
 2.1||||||||||||||||