]> granicus.if.org Git - postgis/commitdiff
Code cleanup of rt_raster_gdal_warp()
authorBborie Park <bkpark at ucdavis.edu>
Mon, 28 Jan 2013 23:01:15 +0000 (23:01 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Mon, 28 Jan 2013 23:01:15 +0000 (23:01 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@11056 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_core/rt_api.c
raster/rt_pg/rt_pg.c

index a9a7c018c13e5b8edab8c3c46f919d1e1d7f1e17..bd8924fd78dba2d58dd26b0ade76a8a04c056fc0 100644 (file)
@@ -9274,6 +9274,104 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) {
        return rast;
 }
 
+/******************************************************************************
+* rt_raster_gdal_warp()
+******************************************************************************/
+
+typedef struct _rti_warp_arg_t* _rti_warp_arg;
+struct _rti_warp_arg_t {
+
+       struct {
+               GDALDriverH drv;
+               GDALDatasetH ds;
+               char *srs;
+       } src, dst;
+
+       GDALWarpOptions *wopts;
+
+       struct {
+               struct {
+                       char **item;
+                       int len;
+               } option;
+
+               struct {
+                       void *transform;
+                       void *imgproj;
+                       void *approx;
+               } arg;
+
+               GDALTransformerFunc func;
+       } transform;
+
+};
+
+static _rti_warp_arg
+_rti_warp_arg_init() {
+       _rti_warp_arg arg = NULL;
+
+       arg = rtalloc(sizeof(struct _rti_warp_arg_t));
+       if (arg == NULL) {
+               rterror("_rti_warp_arg_init: Unable to allocate memory for _rti_warp_arg");
+               return NULL;
+       }
+
+       arg->src.drv = NULL;
+       arg->src.ds = NULL;
+       arg->src.srs = NULL;
+
+       arg->dst.drv = NULL;
+       arg->dst.ds = NULL;
+       arg->dst.srs = NULL;
+
+       arg->wopts = NULL;
+
+       arg->transform.option.item = NULL;
+       arg->transform.option.len = 0;
+
+       arg->transform.arg.transform = NULL;
+       arg->transform.arg.imgproj = NULL;
+       arg->transform.arg.approx = NULL;
+
+       arg->transform.func = NULL;
+
+       return arg;
+}
+
+static void
+_rti_warp_arg_destroy(_rti_warp_arg arg) {
+       int i = 0;
+
+       if (arg->dst.ds != NULL)
+               GDALClose(arg->dst.ds);
+       if (arg->dst.srs != NULL)
+               CPLFree(arg->dst.srs);
+
+       if (arg->src.ds != NULL)
+               GDALClose(arg->src.ds);
+       if (arg->src.srs != NULL)
+               CPLFree(arg->src.srs);
+
+       if (arg->transform.func == GDALApproxTransform) {
+               if (arg->transform.arg.imgproj != NULL)
+                       GDALDestroyGenImgProjTransformer(arg->transform.arg.imgproj);
+       }
+
+       if (arg->wopts != NULL)
+               GDALDestroyWarpOptions(arg->wopts);
+
+       if (arg->transform.option.len > 0 && arg->transform.option.item != NULL) {
+               for (i = 0; i < arg->transform.option.len; i++) {
+                       if (arg->transform.option.item[i] != NULL)
+                               rtdealloc(arg->transform.option.item[i]);
+               }
+               rtdealloc(arg->transform.option.item);
+       }
+
+       rtdealloc(arg);
+       arg = NULL;
+}
+
 /**
  * Return a warped raster using GDAL Warp API
  *
@@ -9314,21 +9412,12 @@ rt_raster rt_raster_gdal_warp(
        double *skew_x, double *skew_y,
        GDALResampleAlg resample_alg, double max_err
 ) {
+       // keep these
        CPLErr cplerr;
-       GDALDriverH src_drv = NULL;
-       GDALDatasetH src_ds = NULL;
-       GDALWarpOptions *wopts = NULL;
-       GDALDriverH dst_drv = NULL;
-       GDALDatasetH dst_ds = NULL;
-       char *_src_srs = NULL;
-       char *_dst_srs = NULL;
        char *dst_options[] = {"SUBCLASS=VRTWarpedDataset", NULL};
-       char **transform_opts = NULL;
-       int transform_opts_len = 2;
-       void *transform_arg = NULL;
-       void *imgproj_arg = NULL;
-       void *approx_arg = NULL;
-       GDALTransformerFunc transform_func = NULL;
+       _rti_warp_arg arg = NULL;
+
+       int hasnodata = 0;
 
        GDALRasterBandH band;
        rt_band rtband = NULL;
@@ -9347,13 +9436,19 @@ rt_raster rt_raster_gdal_warp(
 
        rt_raster rast = NULL;
        int i = 0;
-       int j = 0;
        int numBands = 0;
 
        RASTER_DEBUG(3, "starting");
 
        assert(NULL != raster);
 
+       /* internal variables */
+       arg = _rti_warp_arg_init();
+       if (arg == NULL) {
+               rterror("rt_raster_gdal_warp: Unable to initialize internal variables");
+               return NULL;
+       }
+
        /*
                max_err must be gte zero
 
@@ -9367,14 +9462,12 @@ rt_raster rt_raster_gdal_warp(
                /* reprojection taking place */
                if (dst_srs != NULL && strcmp(src_srs, dst_srs) != 0) {
                        RASTER_DEBUG(4, "Warp operation does include a reprojection");
-                       _src_srs = rt_util_gdal_convert_sr(src_srs, 0);
-                       _dst_srs = rt_util_gdal_convert_sr(dst_srs, 0);
+                       arg->src.srs = rt_util_gdal_convert_sr(src_srs, 0);
+                       arg->dst.srs = rt_util_gdal_convert_sr(dst_srs, 0);
 
-                       if (_src_srs == NULL || _dst_srs == NULL) {
+                       if (arg->src.srs == NULL || arg->dst.srs == NULL) {
                                rterror("rt_raster_gdal_warp: Unable to convert srs values to GDAL accepted format");
-                               if (_src_srs != NULL) CPLFree(_src_srs);
-                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                               _rti_warp_arg_destroy(arg);
                                return NULL;
                        }
                }
@@ -9386,127 +9479,113 @@ rt_raster rt_raster_gdal_warp(
        else if (dst_srs != NULL) {
                /* dst_srs provided but not src_srs */
                rterror("rt_raster_gdal_warp: SRS required for input raster if SRS provided for warped raster");
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
        /* load raster into a GDAL MEM dataset */
-       src_ds = rt_raster_to_gdal_mem(raster, _src_srs, NULL, NULL, 0, &src_drv);
-       if (NULL == src_ds) {
+       arg->src.ds = rt_raster_to_gdal_mem(raster, arg->src.srs, NULL, NULL, 0, &(arg->src.drv));
+       if (NULL == arg->src.ds) {
                rterror("rt_raster_gdal_warp: Unable to convert raster to GDAL MEM format");
-
-               if (_src_srs != NULL) {
-                       CPLFree(_src_srs);
-                       CPLFree(_dst_srs);
-               }
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
        RASTER_DEBUG(3, "raster loaded into GDAL MEM dataset");
-
-       /* set transform_opts */
-       transform_opts = (char **) rtalloc(sizeof(char *) * (transform_opts_len + 1));
-       if (NULL == transform_opts) {
-               rterror("rt_raster_gdal_warp: Unable to allocation memory for transform options");
-
-               GDALClose(src_ds);
-
-               if (_src_srs != NULL) {
-                       CPLFree(_src_srs);
-                       CPLFree(_dst_srs);
-               }
-
-               return NULL;
-       }
-       for (i = 0; i < transform_opts_len; i++) {
-               switch (i) {
-                       case 1:
-                               if (_dst_srs != NULL)
-                                       transform_opts[i] = (char *) rtalloc(sizeof(char) * (strlen("DST_SRS=") + strlen(_dst_srs) + 1));
-                               else
-                                       transform_opts[i] = (char *) rtalloc(sizeof(char) * (strlen("DST_SRS=") + 1));
-                               break;
-                       case 0:
-                               if (_src_srs != NULL)
-                                       transform_opts[i] = (char *) rtalloc(sizeof(char) * (strlen("SRC_SRS=") + strlen(_src_srs) + 1));
-                               else
-                                       transform_opts[i] = (char *) rtalloc(sizeof(char) * (strlen("SRC_SRS=") + 1));
-                               break;
-               }
-               if (NULL == transform_opts[i]) {
+       {
+               GDALRasterBandH _grb = NULL;
+               double _min;
+               double _max;
+               double _mean;
+               double _stddev;
+
+               _grb = GDALGetRasterBand(arg->src.ds, 1);
+               GDALComputeRasterStatistics(_grb, FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL);
+               RASTER_DEBUGF(4, "GDAL stats: %f, %f, %f, %f", _min, _max, _mean, _stddev);
+       }
+
+       /* set transform options */
+       if (arg->src.srs != NULL || arg->dst.srs != NULL) {
+               arg->transform.option.len = 2;
+               arg->transform.option.item = rtalloc(sizeof(char *) * (arg->transform.option.len + 1));
+               if (NULL == arg->transform.option.item) {
                        rterror("rt_raster_gdal_warp: Unable to allocation memory for transform options");
-
-                       for (j = 0; j < i; j++) rtdealloc(transform_opts[j]);
-                       rtdealloc(transform_opts);
-                       GDALClose(src_ds);
-
-                       if (_src_srs != NULL) {
-                               CPLFree(_src_srs);
-                               CPLFree(_dst_srs);
-                       }
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
+               memset(arg->transform.option.item, 0, sizeof(char *) * (arg->transform.option.len + 1));
 
-               switch (i) {
-                       case 1:
-                               if (_dst_srs != NULL) {
-                                       snprintf(
-                                               transform_opts[i],
-                                               sizeof(char) * (strlen("DST_SRS=") + strlen(_dst_srs) + 1),
-                                               "DST_SRS=%s",
-                                               _dst_srs
-                                       );
-                               }
-                               else
-                                       sprintf(transform_opts[i], "%s", "DST_SRS=");
-                               break;
-                       case 0:
-                               if (_src_srs != NULL) {
-                                       snprintf(
-                                               transform_opts[i],
-                                               sizeof(char) * (strlen("SRC_SRS=") + strlen(_src_srs) + 1),
-                                               "SRC_SRS=%s",
-                                               _src_srs
-                                       );
-                               }
-                               else
-                                       sprintf(transform_opts[i], "%s", "SRC_SRS=");
-                               break;
+               for (i = 0; i < arg->transform.option.len; i++) {
+                       switch (i) {
+                               case 1:
+                                       if (arg->dst.srs != NULL)
+                                               arg->transform.option.item[i] = (char *) rtalloc(sizeof(char) * (strlen("DST_SRS=") + strlen(arg->dst.srs) + 1));
+                                       else
+                                               arg->transform.option.item[i] = (char *) rtalloc(sizeof(char) * (strlen("DST_SRS=") + 1));
+                                       break;
+                               case 0:
+                                       if (arg->src.srs != NULL)
+                                               arg->transform.option.item[i] = (char *) rtalloc(sizeof(char) * (strlen("SRC_SRS=") + strlen(arg->src.srs) + 1));
+                                       else
+                                               arg->transform.option.item[i] = (char *) rtalloc(sizeof(char) * (strlen("SRC_SRS=") + 1));
+                                       break;
+                       }
+                       if (NULL == arg->transform.option.item[i]) {
+                               rterror("rt_raster_gdal_warp: Unable to allocation memory for transform options");
+                               _rti_warp_arg_destroy(arg);
+                               return NULL;
+                       }
+
+                       switch (i) {
+                               case 1:
+                                       if (arg->dst.srs != NULL) {
+                                               snprintf(
+                                                       arg->transform.option.item[i],
+                                                       sizeof(char) * (strlen("DST_SRS=") + strlen(arg->dst.srs) + 1),
+                                                       "DST_SRS=%s",
+                                                       arg->dst.srs
+                                               );
+                                       }
+                                       else
+                                               sprintf(arg->transform.option.item[i], "%s", "DST_SRS=");
+                                       break;
+                               case 0:
+                                       if (arg->src.srs != NULL) {
+                                               snprintf(
+                                                       arg->transform.option.item[i],
+                                                       sizeof(char) * (strlen("SRC_SRS=") + strlen(arg->src.srs) + 1),
+                                                       "SRC_SRS=%s",
+                                                       arg->src.srs
+                                               );
+                                       }
+                                       else
+                                               sprintf(arg->transform.option.item[i], "%s", "SRC_SRS=");
+                                       break;
+                       }
+                       RASTER_DEBUGF(4, "arg->transform.option.item[%d] = %s", i, arg->transform.option.item[i]);
                }
-               RASTER_DEBUGF(4, "transform_opts[%d] = %s", i, transform_opts[i]);
        }
-       transform_opts[transform_opts_len] = NULL;
-       if (_src_srs != NULL) CPLFree(_src_srs);
+       else
+               arg->transform.option.len = 0;
 
        /* transformation object for building dst dataset */
-       transform_arg = GDALCreateGenImgProjTransformer2(src_ds, NULL, transform_opts);
-       if (NULL == transform_arg) {
+       arg->transform.arg.transform = GDALCreateGenImgProjTransformer2(arg->src.ds, NULL, arg->transform.option.item);
+       if (NULL == arg->transform.arg.transform) {
                rterror("rt_raster_gdal_warp: Unable to create GDAL transformation object for output dataset creation");
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
        /* get approximate output georeferenced bounds and resolution */
-       cplerr = GDALSuggestedWarpOutput2(src_ds, GDALGenImgProjTransform,
-               transform_arg, _gt, &(_dim[0]), &(_dim[1]), dst_extent, 0);
-       GDALDestroyGenImgProjTransformer(transform_arg);
+       cplerr = GDALSuggestedWarpOutput2(
+               arg->src.ds, GDALGenImgProjTransform,
+               arg->transform.arg.transform, _gt, &(_dim[0]), &(_dim[1]), dst_extent, 0);
        if (cplerr != CE_None) {
                rterror("rt_raster_gdal_warp: Unable to get GDAL suggested warp output for output dataset creation");
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
+       GDALDestroyGenImgProjTransformer(arg->transform.arg.transform);
+       arg->transform.arg.transform = NULL;
 
        /*
                don't use suggested dimensions as use of suggested scales
@@ -9536,13 +9615,7 @@ rt_raster rt_raster_gdal_warp(
                ((NULL != width) || (NULL != height))
        ) {
                rterror("rt_raster_gdal_warp: Scale X/Y and width/height are mutually exclusive.  Only provide one");
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
@@ -9570,13 +9643,7 @@ rt_raster rt_raster_gdal_warp(
                ((NULL == scale_x) && (NULL != scale_y))
        ) {
                rterror("rt_raster_gdal_warp: Both X and Y scale values must be provided for scale");
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
@@ -9637,13 +9704,7 @@ rt_raster rt_raster_gdal_warp(
                );
                if (skewedrast == NULL) {
                        rterror("rt_raster_gdal_warp: Could not compute skewed raster");
-
-                       GDALClose(src_ds);
-
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-                       if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
 
@@ -9668,13 +9729,7 @@ rt_raster rt_raster_gdal_warp(
        rast = rt_raster_new(_dim[0], _dim[1]);
        if (rast == NULL) {
                rterror("rt_raster_gdal_warp: Out of memory allocating temporary raster");
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
@@ -9708,14 +9763,8 @@ rt_raster rt_raster_gdal_warp(
                ((NULL == ul_xw) && (NULL != ul_yw))
        ) {
                rterror("rt_raster_gdal_warp: Both X and Y upper-left corner values must be provided");
-
                rt_raster_destroy(rast);
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
@@ -9731,14 +9780,8 @@ rt_raster rt_raster_gdal_warp(
                        ((NULL == grid_xw) && (NULL != grid_yw))
                ) {
                        rterror("rt_raster_gdal_warp: Both X and Y alignment values must be provided");
-
                        rt_raster_destroy(rast);
-                       GDALClose(src_ds);
-
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-                       if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
 
@@ -9766,14 +9809,8 @@ rt_raster rt_raster_gdal_warp(
                                NULL
                        ) != ES_NONE) {
                                rterror("rt_raster_gdal_warp: Unable to compute raster pixel for spatial coordinates");
-
                                rt_raster_destroy(rast);
-                               GDALClose(src_ds);
-
-                               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                               rtdealloc(transform_opts);
-                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                               _rti_warp_arg_destroy(arg);
                                return NULL;
                        }
 
@@ -9786,12 +9823,7 @@ rt_raster rt_raster_gdal_warp(
                                rterror("rt_raster_gdal_warp: Unable to compute spatial coordinates for raster pixel");
 
                                rt_raster_destroy(rast);
-                               GDALClose(src_ds);
-
-                               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                               rtdealloc(transform_opts);
-                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                               _rti_warp_arg_destroy(arg);
                                return NULL;
                        }
 
@@ -9812,14 +9844,8 @@ rt_raster rt_raster_gdal_warp(
                                                NULL
                                        ) != ES_NONE) {
                                                rterror("rt_raster_gdal_warp: Unable to compute spatial coordinates for raster pixel");
-
                                                rt_raster_destroy(rast);
-                                               GDALClose(src_ds);
-
-                                               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                                               rtdealloc(transform_opts);
-                                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                                               _rti_warp_arg_destroy(arg);
                                                return NULL;
                                        }
 
@@ -9844,12 +9870,7 @@ rt_raster rt_raster_gdal_warp(
                                                rterror("rt_raster_gdal_warp: Unable to compute spatial coordinates for raster pixel");
 
                                                rt_raster_destroy(rast);
-                                               GDALClose(src_ds);
-
-                                               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                                               rtdealloc(transform_opts);
-                                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                                               _rti_warp_arg_destroy(arg);
                                                return NULL;
                                        }
 
@@ -9892,15 +9913,8 @@ rt_raster rt_raster_gdal_warp(
                                NULL
                        ) != ES_NONE) {
                                rterror("rt_raster_gdal_warp: Unable to compute spatial coordinates for raster pixel");
-
                                rt_raster_destroy(rast);
-
-                               GDALClose(src_ds);
-
-                               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                               rtdealloc(transform_opts);
-                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                               _rti_warp_arg_destroy(arg);
                                return NULL;
                        }
 
@@ -9923,15 +9937,8 @@ rt_raster rt_raster_gdal_warp(
                                NULL
                        ) != ES_NONE) {
                                rterror("rt_raster_gdal_warp: Unable to compute spatial coordinates for raster pixel");
-
                                rt_raster_destroy(rast);
-
-                               GDALClose(src_ds);
-
-                               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                               rtdealloc(transform_opts);
-                               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+                               _rti_warp_arg_destroy(arg);
                                return NULL;
                        }
 
@@ -9954,70 +9961,44 @@ rt_raster rt_raster_gdal_warp(
 
        if (FLT_EQ(_dim[0], 0) || FLT_EQ(_dim[1], 0)) {
                rterror("rt_raster_gdal_warp: The width (%f) or height (%f) of the warped raster is zero", _dim[0], _dim[1]);
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
        /* load VRT driver */
        if (!rt_util_gdal_driver_registered("VRT"))
                GDALRegister_VRT();
-       dst_drv = GDALGetDriverByName("VRT");
-       if (NULL == dst_drv) {
+       arg->dst.drv = GDALGetDriverByName("VRT");
+       if (NULL == arg->dst.drv) {
                rterror("rt_raster_gdal_warp: Unable to load the output GDAL VRT driver");
-
-               GDALClose(src_ds);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
        /* create dst dataset */
-       dst_ds = GDALCreate(dst_drv, "", _dim[0], _dim[1], 0, GDT_Byte, dst_options);
-       if (NULL == dst_ds) {
+       arg->dst.ds = GDALCreate(arg->dst.drv, "", _dim[0], _dim[1], 0, GDT_Byte, dst_options);
+       if (NULL == arg->dst.ds) {
                rterror("rt_raster_gdal_warp: Unable to create GDAL VRT dataset");
-
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-               if (_dst_srs != NULL) CPLFree(_dst_srs);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
        /* set dst srs */
-       if (_dst_srs != NULL) {
-               cplerr = GDALSetProjection(dst_ds, _dst_srs);
-               CPLFree(_dst_srs);
+       if (arg->dst.srs != NULL) {
+               cplerr = GDALSetProjection(arg->dst.ds, arg->dst.srs);
                if (cplerr != CE_None) {
                        rterror("rt_raster_gdal_warp: Unable to set projection");
-
-                       GDALClose(dst_ds);
-                       GDALClose(src_ds);
-
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
+               RASTER_DEBUGF(3, "Applied SRS: %s", GDALGetProjectionRef(arg->dst.ds));
        }
 
        /* set dst geotransform */
-       cplerr = GDALSetGeoTransform(dst_ds, _gt);
+       cplerr = GDALSetGeoTransform(arg->dst.ds, _gt);
        if (cplerr != CE_None) {
                rterror("rt_raster_gdal_warp: Unable to set geotransform");
-
-               GDALClose(dst_ds);
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
@@ -10027,13 +10008,7 @@ rt_raster rt_raster_gdal_warp(
                rtband = rt_raster_get_band(raster, i);
                if (NULL == rtband) {
                        rterror("rt_raster_gdal_warp: Unable to get band %d for adding to VRT dataset", i);
-
-                       GDALClose(dst_ds);
-                       GDALClose(src_ds);
-
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
 
@@ -10042,36 +10017,25 @@ rt_raster rt_raster_gdal_warp(
                if (gdal_pt == GDT_Unknown)
                        rtwarn("rt_raster_gdal_warp: Unknown pixel type for band %d", i);
 
-               cplerr = GDALAddBand(dst_ds, gdal_pt, NULL);
+               cplerr = GDALAddBand(arg->dst.ds, gdal_pt, NULL);
                if (cplerr != CE_None) {
                        rterror("rt_raster_gdal_warp: Unable to add band to VRT dataset");
-
-                       GDALClose(dst_ds);
-                       GDALClose(src_ds);
-
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
 
                /* get band to write data to */
                band = NULL;
-               band = GDALGetRasterBand(dst_ds, i + 1);
+               band = GDALGetRasterBand(arg->dst.ds, i + 1);
                if (NULL == band) {
                        rterror("rt_raster_gdal_warp: Could not get GDAL band for additional processing");
-
-                       GDALClose(dst_ds);
-                       GDALClose(src_ds);
-
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
 
                /* set nodata */
                if (rt_band_get_hasnodata_flag(rtband) != FALSE) {
+                       hasnodata = 1;
                        rt_band_get_nodata(rtband, &nodata);
                        if (GDALSetRasterNoDataValue(band, nodata) != CE_None)
                                rtwarn("rt_raster_gdal_warp: Could not set nodata value for band %d", i);
@@ -10080,170 +10044,123 @@ rt_raster rt_raster_gdal_warp(
        }
 
        /* create transformation object */
-       transform_arg = imgproj_arg = GDALCreateGenImgProjTransformer2(src_ds, dst_ds, transform_opts);
-       if (NULL == transform_arg) {
+       arg->transform.arg.transform = arg->transform.arg.imgproj = GDALCreateGenImgProjTransformer2(
+               arg->src.ds, arg->dst.ds,
+               arg->transform.option.item
+       );
+       if (NULL == arg->transform.arg.transform) {
                rterror("rt_raster_gdal_warp: Unable to create GDAL transformation object");
-
-               GDALClose(dst_ds);
-               GDALClose(src_ds);
-
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
-       transform_func = GDALGenImgProjTransform;
+       arg->transform.func = GDALGenImgProjTransform;
 
        /* use approximate transformation object */
        if (max_err > 0.0) {
-               transform_arg = approx_arg = GDALCreateApproxTransformer(
+               arg->transform.arg.transform = arg->transform.arg.approx = GDALCreateApproxTransformer(
                        GDALGenImgProjTransform,
-                       imgproj_arg, max_err
+                       arg->transform.arg.imgproj, max_err
                );
-               if (NULL == transform_arg) {
+               if (NULL == arg->transform.arg.transform) {
                        rterror("rt_raster_gdal_warp: Unable to create GDAL approximate transformation object");
-
-                       GDALClose(dst_ds);
-                       GDALClose(src_ds);
-
-                       GDALDestroyGenImgProjTransformer(imgproj_arg);
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
 
-               transform_func = GDALApproxTransform;
+               arg->transform.func = GDALApproxTransform;
        }
 
        /* warp options */
-       wopts = GDALCreateWarpOptions();
-       if (NULL == wopts) {
+       arg->wopts = GDALCreateWarpOptions();
+       if (NULL == arg->wopts) {
                rterror("rt_raster_gdal_warp: Unable to create GDAL warp options object");
-
-               GDALClose(dst_ds);
-               GDALClose(src_ds);
-
-               GDALDestroyGenImgProjTransformer(imgproj_arg);
-               GDALDestroyApproxTransformer(approx_arg);
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
 
        /* set options */
-       wopts->eResampleAlg = resample_alg;
-       wopts->hSrcDS = src_ds;
-       wopts->hDstDS = dst_ds;
-       wopts->pfnTransformer = transform_func;
-       wopts->pTransformerArg = transform_arg;
-       wopts->papszWarpOptions = (char **) CPLMalloc(sizeof(char *) * 2);
-       wopts->papszWarpOptions[0] = (char *) CPLMalloc(sizeof(char) * (strlen("INIT_DEST=NO_DATA") + 1));
-       strcpy(wopts->papszWarpOptions[0], "INIT_DEST=NO_DATA");
-       wopts->papszWarpOptions[1] = NULL;
+       arg->wopts->eResampleAlg = resample_alg;
+       arg->wopts->hSrcDS = arg->src.ds;
+       arg->wopts->hDstDS = arg->dst.ds;
+       arg->wopts->pfnTransformer = arg->transform.func;
+       arg->wopts->pTransformerArg = arg->transform.arg.transform;
+       arg->wopts->papszWarpOptions = (char **) CPLMalloc(sizeof(char *) * 2);
+       arg->wopts->papszWarpOptions[0] = (char *) CPLMalloc(sizeof(char) * (strlen("INIT_DEST=NO_DATA") + 1));
+       strcpy(arg->wopts->papszWarpOptions[0], "INIT_DEST=NO_DATA");
+       arg->wopts->papszWarpOptions[1] = NULL;
 
        /* set band mapping */
-       wopts->nBandCount = numBands;
-       wopts->panSrcBands = (int *) CPLMalloc(sizeof(int) * wopts->nBandCount);
-       wopts->panDstBands = (int *) CPLMalloc(sizeof(int) * wopts->nBandCount);
-       for (i = 0; i < wopts->nBandCount; i++)
-               wopts->panDstBands[i] = wopts->panSrcBands[i] = i + 1;
+       arg->wopts->nBandCount = numBands;
+       arg->wopts->panSrcBands = (int *) CPLMalloc(sizeof(int) * arg->wopts->nBandCount);
+       arg->wopts->panDstBands = (int *) CPLMalloc(sizeof(int) * arg->wopts->nBandCount);
+       for (i = 0; i < arg->wopts->nBandCount; i++)
+               arg->wopts->panDstBands[i] = arg->wopts->panSrcBands[i] = i + 1;
 
        /* set nodata mapping */
-       RASTER_DEBUG(3, "Setting nodata mapping");
-       wopts->padfSrcNoDataReal = (double *) CPLMalloc(numBands * sizeof(double));
-       wopts->padfDstNoDataReal = (double *) CPLMalloc(numBands * sizeof(double));
-       wopts->padfSrcNoDataImag = (double *) CPLMalloc(numBands * sizeof(double));
-       wopts->padfDstNoDataImag = (double *) CPLMalloc(numBands * sizeof(double));
-       if (
-               NULL == wopts->padfSrcNoDataReal ||
-               NULL == wopts->padfDstNoDataReal ||
-               NULL == wopts->padfSrcNoDataImag ||
-               NULL == wopts->padfDstNoDataImag
-       ) {
-               rterror("rt_raster_gdal_warp: Out of memory allocating nodata mapping");
-
-               GDALClose(dst_ds);
-               GDALClose(src_ds);
-
-               GDALDestroyGenImgProjTransformer(imgproj_arg);
-               GDALDestroyApproxTransformer(approx_arg);
-               GDALDestroyWarpOptions(wopts);
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-
-               return NULL;
-       }
-       for (i = 0; i < numBands; i++) {
-               band = rt_raster_get_band(raster, i);
-               if (!band) {
-                       rterror("rt_raster_gdal_warp: Unable to process bands for nodata values");
-
-                       GDALClose(dst_ds);
-                       GDALClose(src_ds);
-
-                       GDALDestroyGenImgProjTransformer(imgproj_arg);
-                       GDALDestroyApproxTransformer(approx_arg);
-                       GDALDestroyWarpOptions(wopts);
-                       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-                       rtdealloc(transform_opts);
-
+       if (hasnodata) {
+               RASTER_DEBUG(3, "Setting nodata mapping");
+               arg->wopts->padfSrcNoDataReal = (double *) CPLMalloc(numBands * sizeof(double));
+               arg->wopts->padfDstNoDataReal = (double *) CPLMalloc(numBands * sizeof(double));
+               arg->wopts->padfSrcNoDataImag = (double *) CPLMalloc(numBands * sizeof(double));
+               arg->wopts->padfDstNoDataImag = (double *) CPLMalloc(numBands * sizeof(double));
+               if (
+                       NULL == arg->wopts->padfSrcNoDataReal ||
+                       NULL == arg->wopts->padfDstNoDataReal ||
+                       NULL == arg->wopts->padfSrcNoDataImag ||
+                       NULL == arg->wopts->padfDstNoDataImag
+               ) {
+                       rterror("rt_raster_gdal_warp: Out of memory allocating nodata mapping");
+                       _rti_warp_arg_destroy(arg);
                        return NULL;
                }
+               for (i = 0; i < numBands; i++) {
+                       band = rt_raster_get_band(raster, i);
+                       if (!band) {
+                               rterror("rt_raster_gdal_warp: Unable to process bands for nodata values");
+                               _rti_warp_arg_destroy(arg);
+                               return NULL;
+                       }
 
-               if (!rt_band_get_hasnodata_flag(band)) {
-                       /*
-                               based on line 1004 of gdalwarp.cpp
-                               the problem is that there is a chance that this number is a legitimate value
-                       */
-                       wopts->padfSrcNoDataReal[i] = -123456.789;
-               }
-               else {
-                       rt_band_get_nodata(band, &(wopts->padfSrcNoDataReal[i]));
-               }
+                       if (!rt_band_get_hasnodata_flag(band)) {
+                               /*
+                                       based on line 1004 of gdalwarp.cpp
+                                       the problem is that there is a chance that this number is a legitimate value
+                               */
+                               arg->wopts->padfSrcNoDataReal[i] = -123456.789;
+                       }
+                       else {
+                               rt_band_get_nodata(band, &(arg->wopts->padfSrcNoDataReal[i]));
+                       }
 
-               wopts->padfDstNoDataReal[i] = wopts->padfSrcNoDataReal[i];
-               wopts->padfDstNoDataImag[i] = wopts->padfSrcNoDataImag[i] = 0.0;
-               RASTER_DEBUGF(4, "Mapped nodata value for band %d: %f (%f) => %f (%f)",
-                       i,
-                       wopts->padfSrcNoDataReal[i], wopts->padfSrcNoDataImag[i],
-                       wopts->padfDstNoDataReal[i], wopts->padfDstNoDataImag[i]
-               );
+                       arg->wopts->padfDstNoDataReal[i] = arg->wopts->padfSrcNoDataReal[i];
+                       arg->wopts->padfDstNoDataImag[i] = arg->wopts->padfSrcNoDataImag[i] = 0.0;
+                       RASTER_DEBUGF(4, "Mapped nodata value for band %d: %f (%f) => %f (%f)",
+                               i,
+                               arg->wopts->padfSrcNoDataReal[i], arg->wopts->padfSrcNoDataImag[i],
+                               arg->wopts->padfDstNoDataReal[i], arg->wopts->padfDstNoDataImag[i]
+                       );
+               }
        }
 
        /* warp raster */
        RASTER_DEBUG(3, "Warping raster");
-       cplerr = GDALInitializeWarpedVRT(dst_ds, wopts);
+       cplerr = GDALInitializeWarpedVRT(arg->dst.ds, arg->wopts);
        if (cplerr != CE_None) {
                rterror("rt_raster_gdal_warp: Unable to warp raster");
-
-               GDALClose(dst_ds);
-               GDALClose(src_ds);
-
-               if ((transform_func == GDALApproxTransform) && (NULL != imgproj_arg))
-                       GDALDestroyGenImgProjTransformer(imgproj_arg);
-               GDALDestroyWarpOptions(wopts);
-               for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-               rtdealloc(transform_opts);
-
+               _rti_warp_arg_destroy(arg);
                return NULL;
        }
-       GDALFlushCache(dst_ds);
+       /*
+       */
+       GDALSetDescription(arg->dst.ds, "/tmp/warped.vrt");
+       GDALFlushCache(arg->dst.ds);
        RASTER_DEBUG(3, "Raster warped");
 
        /* convert gdal dataset to raster */
        RASTER_DEBUG(3, "Converting GDAL dataset to raster");
-       rast = rt_raster_from_gdal_dataset(dst_ds);
-
-       GDALClose(dst_ds);
-       GDALClose(src_ds);
+       rast = rt_raster_from_gdal_dataset(arg->dst.ds);
 
-       if ((transform_func == GDALApproxTransform) && (NULL != imgproj_arg))
-               GDALDestroyGenImgProjTransformer(imgproj_arg);
-       GDALDestroyWarpOptions(wopts);
-       for (i = 0; i < transform_opts_len; i++) rtdealloc(transform_opts[i]);
-       rtdealloc(transform_opts);
+       _rti_warp_arg_destroy(arg);
 
        if (NULL == rast) {
                rterror("rt_raster_gdal_warp: Unable to warp raster");
index 9249f401878f82341e92071c20595d827b4c8de8..954dc19d7aa72ccbf34eb3cc8bb7406ad5cdd2cf 100644 (file)
@@ -11346,7 +11346,7 @@ Datum RASTER_GDALWarp(PG_FUNCTION_ARGS)
        }
        /* target SRID == src SRID, no reprojection */
        else if (dst_srid == src_srid) {
-               /* set geotransform BUT ONLY when geotransform isn't default */
+               /* set geotransform BUT ONLY when geotransform IS the default */
                if (src_srid == SRID_UNKNOWN) {
                        double gt[6];