]> granicus.if.org Git - postgis/commitdiff
Added option -G to get listing of supported raster types instead of calling ST_GDALDr...
authorBborie Park <bkpark at ucdavis.edu>
Wed, 14 Dec 2011 22:23:42 +0000 (22:23 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Wed, 14 Dec 2011 22:23:42 +0000 (22:23 +0000)
Added ability to specify band indices with ranges for option -b.  Example: -b 1-5,7,9-15.  Associated ticket is #1375.
Added warning messages when loader is processing more than one raster and rasters may have different number of bands, pixel types, hasnodata flags, NODATA values, geotransforms andtile sizes.  Associated ticket is #153.

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

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

index c11f7f92512b641123427f31a68b87ef62b712d5..871f244310d5a72a2f50e4d8f49861e2198f606d 100644 (file)
@@ -52,6 +52,36 @@ raster_destroy(rt_raster raster) {
        rt_raster_destroy(raster);
 }
 
+static int
+array_range(int min, int max, int step, int **range, int *len) {
+       int i = 0;
+       int j = 0;
+
+       step = abs(step);
+       *len = (abs(max - min) + 1 + (step / 2)) / step;
+       *range = rtalloc(sizeof(int) * *len);
+
+       if (min < max) {
+               for (i = min, j = 0; i <= max; i += step, j++)
+                       (*range)[j] = i;
+       }
+       else if (max < min) {
+               if (step > 0) step *= -1;
+               for (i = min, j = 0; i >= max; i += step, j++)
+                       (*range)[j] = i;
+       }
+       else if (min == max) {
+               (*range)[0] = min;
+       }
+       else {
+               *len = 0;
+               *range = NULL;
+               return 0;
+       }
+
+       return 1;
+}
+
 /* string replacement function taken from
  * http://ubuntuforums.org/showthread.php?s=aa6f015109fd7e4c7e30d2fd8b717497&t=141670&page=3
  */
@@ -263,8 +293,9 @@ usage() {
        ), SRID_UNKNOWN);
        printf(_(
                "  -b <band> Index (1-based) of band to extract from raster.  For more\n"
-               "      than one band index, separate with comma (,).  If unspecified,\n"
-               "      all bands of raster will be extracted.\n"
+               "      than one band index, separate with comma (,).  Ranges can be\n"
+               "      defined by separating with dash (-).  If unspecified, all bands\n"
+               "      of raster will be extracted.\n"
        ));
        printf(_(
                "  -t <tile size> Cut raster into tiles to be inserted one per\n"
@@ -344,6 +375,9 @@ usage() {
        printf(_(
                "  -Y  Use COPY statements instead of INSERT statements.\n"
        ));
+       printf(_(
+               "  -G  Print the supported GDAL raster formats.\n"
+       ));
        printf(_(
                "  -?  Display this help screen.\n"
        ));
@@ -379,6 +413,132 @@ rtdealloc_rastinfo(RASTERINFO *info) {
                rtdealloc(info->nodataval);
 }
 
+static int
+copy_rastinfo(RASTERINFO *dst, RASTERINFO *src) {
+       if (src->srs != NULL) {
+               dst->srs = rtalloc(sizeof(char) * (strlen(src->srs) + 1));
+               if (dst->srs == NULL) {
+                       fprintf(stderr, _("Not enough memory\n"));
+                       return 0;
+               }
+               strcpy(dst->srs, src->srs);
+       }
+       memcpy(dst->dim, src->dim, sizeof(uint32_t) * 2);
+       dst->nband_count = src->nband_count;
+       if (src->nband_count && src->nband != NULL) {
+               dst->nband = rtalloc(sizeof(int) * src->nband_count);
+               if (dst->nband == NULL) {
+                       fprintf(stderr, _("Not enough memory\n"));
+                       return 0;
+               }
+               memcpy(dst->nband, src->nband, sizeof(int) * src->nband_count);
+       }
+       if (src->gdalbandtype != NULL) {
+               dst->gdalbandtype = rtalloc(sizeof(GDALDataType) * src->nband_count);
+               if (dst->gdalbandtype == NULL) {
+                       fprintf(stderr, _("Not enough memory\n"));
+                       return 0;
+               }
+               memcpy(dst->gdalbandtype, src->gdalbandtype, sizeof(GDALDataType) * src->nband_count);
+       }
+       if (src->bandtype != NULL) {
+               dst->bandtype = rtalloc(sizeof(rt_pixtype) * src->nband_count);
+               if (dst->bandtype == NULL) {
+                       fprintf(stderr, _("Not enough memory\n"));
+                       return 0;
+               }
+               memcpy(dst->bandtype, src->bandtype, sizeof(rt_pixtype) * src->nband_count);
+       }
+       if (src->hasnodata != NULL) {
+               dst->hasnodata = rtalloc(sizeof(int) * src->nband_count);
+               if (dst->hasnodata == NULL) {
+                       fprintf(stderr, _("Not enough memory\n"));
+                       return 0;
+               }
+               memcpy(dst->hasnodata, src->hasnodata, sizeof(int) * src->nband_count);
+       }
+       if (src->nodataval != NULL) {
+               dst->nodataval = rtalloc(sizeof(double) * src->nband_count);
+               if (dst->nodataval == NULL) {
+                       fprintf(stderr, _("Not enough memory\n"));
+                       return 0;
+               }
+               memcpy(dst->nodataval, src->nodataval, sizeof(double) * src->nband_count);
+       }
+       memcpy(dst->gt, src->gt, sizeof(double) * 6);
+       memcpy(dst->tile_size, src->tile_size, sizeof(int) * 2);
+
+       return 1;
+}
+
+static void
+diff_rastinfo(RASTERINFO *x, RASTERINFO *ref) {
+       static uint8_t msg[6] = {0};
+       int i = 0;
+
+       /* # of bands */
+       if (
+               !msg[0] &&
+               x->nband_count != ref->nband_count
+       ) {
+               fprintf(stderr, _("WARNING: Different number of bands found in the set of rasters being converted to PostGIS Raster\n"));
+               msg[0]++;
+       }
+
+       /* pixel types */
+       if (!msg[1]) {
+               for (i = 0; i < ref->nband_count; i++) {
+                       if (x->bandtype[i] != ref->bandtype[i]) {
+                               fprintf(stderr, _("WARNING: Different pixel types found for band %d in the set of rasters being converted to PostGIS Raster\n"), ref->nband[i]);
+                               msg[1]++;
+                       }
+               }
+       }
+
+       /* hasnodata */
+       if (!msg[2]) {
+               for (i = 0; i < ref->nband_count; i++) {
+                       if (x->hasnodata[i] != ref->hasnodata[i]) {
+                               fprintf(stderr, _("WARNING: Different hasnodata flags found for band %d in the set of rasters being converted to PostGIS Raster\n"), ref->nband[i]);
+                               msg[2]++;
+                       }
+               }
+       }
+
+       /* nodataval */
+       if (!msg[3]) {
+               for (i = 0; i < ref->nband_count; i++) {
+                       if (!x->hasnodata[i] && !ref->hasnodata[i]) continue;
+                       if (FLT_NEQ(x->hasnodata[i], ref->hasnodata[i])) {
+                               fprintf(stderr, _("WARNING: Different NODATA values found for band %d in the set of rasters being converted to PostGIS Raster\n"), ref->nband[i]);
+                               msg[3]++;
+                       }
+               }
+       }
+
+       /* geotransform */
+       if (!msg[4]) {
+               for (i = 0; i < 6; i++) {
+                       if (FLT_NEQ(x->gt[i], ref->gt[i])) {
+                               fprintf(stderr, _("WARNING: Different geotransform matrices found in the set of rasters being converted to PostGIS Raster\n"));
+                               msg[4]++;
+                               break;
+                       }
+               }
+       }
+
+       /* tile size */
+       if (!msg[5]) {
+               for (i = 0; i < 2; i++) {
+                       if (FLT_NEQ(x->gt[i], ref->gt[i])) {
+                               fprintf(stderr, _("WARNING: Different tile sizes found in the set of rasters being converted to PostGIS Raster\n"));
+                               msg[5]++;
+                               break;
+                       }
+               }
+       }
+}
+
 static void
 init_config(RTLOADERCFG *config) {
        config->rt_file_count = 0;
@@ -1529,6 +1689,9 @@ process_rasters(RTLOADERCFG *config, STRINGBUFFER *buffer) {
 
        /* no need to run if opt is 'p' */
        if (config->opt != 'p') {
+               RASTERINFO refinfo;
+               init_rastinfo(&refinfo);
+
                /* register GDAL drivers */
                GDALAllRegister();
 
@@ -1634,8 +1797,18 @@ process_rasters(RTLOADERCFG *config, STRINGBUFFER *buffer) {
                                }
                        }
 
+                       if (config->rt_file_count > 1) {
+                               if (i < 1)
+                                       copy_rastinfo(&refinfo, &rastinfo);
+                               else {
+                                       diff_rastinfo(&rastinfo, &refinfo);
+                               }
+                       }
+
                        rtdealloc_rastinfo(&rastinfo);
                }
+
+               rtdealloc_rastinfo(&refinfo);
        }
 
        /* index */
@@ -1805,16 +1978,76 @@ main(int argc, char **argv) {
                                exit(1);
                        }
 
-                       config->nband_count = n;
-                       config->nband = rtalloc(sizeof(int) * n);
-                       if (config->nband == NULL) {
-                               fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
-                               rtdealloc_config(config);
-                               exit(1);
-                       }
+                       config->nband_count = 0;
                        for (j = 0; j < n; j++) {
                                char *t = trim(elements[j]);
-                               config->nband[j] = atoi(t);
+                               char **minmax = NULL;
+                               int *range = NULL;
+                               int p = 0;
+                               int l = 0;
+                               int m = 0;
+                               int o = 0;
+
+                               /* is t a range? */
+                               minmax = strsplit(t, "-", &o);
+                               if (o == 2) {
+                                       if (!array_range(atoi(minmax[0]), atoi(minmax[1]), 1, &range, &p)) {
+                                               fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
+                                               for (l = 0; l < o; l++)
+                                                       rtdealloc(minmax[l]);
+                                               rtdealloc(minmax);
+                                               for (j = 0; j < n; j++)
+                                                       rtdealloc(elements[j]);
+                                               rtdealloc(elements);
+                                               rtdealloc(t);
+                                               rtdealloc_config(config);
+                                               exit(1);
+                                       }
+                               }
+                               else {
+                                       p = 1;
+                                       range = rtalloc(sizeof(int));
+                                       if (range == NULL) {
+                                               fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
+                                               for (l = 0; l < o; l++)
+                                                       rtdealloc(minmax[l]);
+                                               rtdealloc(minmax);
+                                               for (j = 0; j < n; j++)
+                                                       rtdealloc(elements[j]);
+                                               rtdealloc(elements);
+                                               rtdealloc(t);
+                                               rtdealloc_config(config);
+                                               exit(1);
+                                       }
+                                       *range = atoi(t);
+                               }
+
+                               m = config->nband_count;
+                               config->nband_count += p;
+                               config->nband = rtrealloc(config->nband, sizeof(int) * config->nband_count);
+                               if (config->nband == NULL) {
+                                       fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
+                                       rtdealloc(range);
+                                       for (l = 0; l < o; l++)
+                                               rtdealloc(minmax[l]);
+                                       rtdealloc(minmax);
+                                       for (j = 0; j < n; j++)
+                                               rtdealloc(elements[j]);
+                                       rtdealloc(elements);
+                                       rtdealloc(t);
+                                       rtdealloc_config(config);
+                                       exit(1);
+                               }
+
+                               for (l = 0; l < p; l++, m++)
+                                       config->nband[m] = range[l];
+
+                               rtdealloc(range);
+
+                               for (l = 0; l < o; l++)
+                                       rtdealloc(minmax[l]);
+                               rtdealloc(minmax);
+
                                rtdealloc(t);
                                rtdealloc(elements[j]);
                        }
@@ -1824,7 +2057,7 @@ main(int argc, char **argv) {
 
                        for (j = 0; j < config->nband_count; j++) {
                                if (config->nband[j] < 1) {
-                                       fprintf(stderr, _("Band index %d must be greater than 0.\n"), config->nband[j]);
+                                       fprintf(stderr, _("Band index %d must be greater than 0\n"), config->nband[j]);
                                        rtdealloc_config(config);
                                        exit(1);
                                }
@@ -1851,7 +2084,7 @@ main(int argc, char **argv) {
 
                        for (j = 0; j < 2; j++) {
                                if (config->tile_size[j] < 1) {
-                                       fprintf(stderr, _("Tile size must be greater than 0x0.\n"));
+                                       fprintf(stderr, _("Tile size must be greater than 0x0\n"));
                                        rtdealloc_config(config);
                                        exit(1);
                                }
@@ -1920,7 +2153,7 @@ main(int argc, char **argv) {
 
                        for (j = 0; j < config->overview_count; j++) {
                                if (config->overview[j] < MINOVFACTOR || config->overview[j] > MAXOVFACTOR) {
-                                       fprintf(stderr, _("Overview factor %d is not between %d and %d.\n"), config->overview[j], MINOVFACTOR, MAXOVFACTOR);
+                                       fprintf(stderr, _("Overview factor %d is not between %d and %d\n"), config->overview[j], MINOVFACTOR, MAXOVFACTOR);
                                        rtdealloc_config(config);
                                        exit(1);
                                }
@@ -1993,6 +2226,28 @@ main(int argc, char **argv) {
                else if (CSEQUAL(argv[i], "-Y")) {
                        config->copy_statements = 1;
                }
+               /* GDAL formats */
+               else if (CSEQUAL(argv[i], "-G")) {
+                       uint32_t drv_count = 0;
+                       rt_gdaldriver drv_set = rt_raster_gdal_drivers(&drv_count, 0);
+                       if (drv_set == NULL || !drv_count) {
+                               fprintf(stderr, _("Cannot get list of available GDAL raster formats\n"));
+                       }
+                       else {
+                               fprintf(stderr, _("Available GDAL raster formats:\n"));
+                               for (j = 0; j < drv_count; j++) {
+                                       fprintf(stderr, _("  %s\n"), drv_set[j].long_name);
+
+                                       rtdealloc(drv_set[j].short_name);
+                                       rtdealloc(drv_set[j].long_name);
+                                       rtdealloc(drv_set[j].create_options);
+                               }
+                               rtdealloc(drv_set);
+                       }
+
+                       rtdealloc_config(config);
+                       exit(0);
+               }
                /* help */
                else if (CSEQUAL(argv[i], "-?")) {
                        usage();
index 625772ee63f26e1a84707c503d8315ced17c7b41..c2b55f4dbbfe364b014befd0131434ac3eb7e4cf 100644 (file)
@@ -6512,11 +6512,13 @@ rt_raster_to_gdal(rt_raster raster, const char *srs,
  * Returns a set of available GDAL drivers
  *
  * @param drv_count : number of GDAL drivers available
+ * @param cancc : if non-zero, filter drivers to only those
+ *   with support for CreateCopy and VirtualIO
  *
  * @return set of "gdaldriver" values of available GDAL drivers
  */
 rt_gdaldriver
-rt_raster_gdal_drivers(uint32_t *drv_count) {
+rt_raster_gdal_drivers(uint32_t *drv_count, uint8_t cancc) {
        const char *state;
        const char *txt;
        int txt_len;
@@ -6537,13 +6539,15 @@ rt_raster_gdal_drivers(uint32_t *drv_count) {
        for (i = 0, j = 0; i < count; i++) {
                drv = GDALGetDriver(i);
 
-               /* CreateCopy support */
-               state = GDALGetMetadataItem(drv, GDAL_DCAP_CREATECOPY, NULL);
-               if (state == NULL) continue;
+               if (cancc) {
+                       /* CreateCopy support */
+                       state = GDALGetMetadataItem(drv, GDAL_DCAP_CREATECOPY, NULL);
+                       if (state == NULL) continue;
 
-               /* VirtualIO support */
-               state = GDALGetMetadataItem(drv, GDAL_DCAP_VIRTUALIO, NULL);
-               if (state == NULL) continue;
+                       /* VirtualIO support */
+                       state = GDALGetMetadataItem(drv, GDAL_DCAP_VIRTUALIO, NULL);
+                       if (state == NULL) continue;
+               }
 
                /* index of driver */
                rtn[j].idx = i;
@@ -6552,7 +6556,9 @@ rt_raster_gdal_drivers(uint32_t *drv_count) {
                txt = GDALGetDriverShortName(drv);
                txt_len = strlen(txt);
 
-               RASTER_DEBUGF(3, "rt_raster_gdal_driver: driver %s (%d) supports CreateCopy() and VirtualIO()", txt, i);
+               if (cancc) {
+                       RASTER_DEBUGF(3, "rt_raster_gdal_driver: driver %s (%d) supports CreateCopy() and VirtualIO()", txt, i);
+               }
 
                txt_len = (txt_len + 1) * sizeof(char);
                rtn[j].short_name = (char *) rtalloc(txt_len);
index 89621dd7dc719c235d4f3ca3014f0bbd5ab5f832..3245304c27ae59a4ebe28d73a2c835cfe84c1577 100644 (file)
@@ -1038,10 +1038,12 @@ uint8_t *rt_raster_to_gdal(rt_raster raster, const char *srs,
  * Returns a set of available GDAL drivers
  *
  * @param drv_count : number of GDAL drivers available
+ * @param cancc : if non-zero, filter drivers to only those
+ *   with support for CreateCopy and VirtualIO
  *
  * @return set of "gdaldriver" values of available GDAL drivers
  */
-rt_gdaldriver rt_raster_gdal_drivers(uint32_t *drv_count);
+rt_gdaldriver rt_raster_gdal_drivers(uint32_t *drv_count, uint8_t cancc);
 
 /**
  * Return GDAL dataset using GDAL MEM driver from raster
index fbd2c2c98b798152ffcc2b2421e01555e39b4795..e2e5e36838df53d9141cac4488c773cc5f7394ac 100644 (file)
@@ -6655,7 +6655,7 @@ Datum RASTER_getGDALDrivers(PG_FUNCTION_ARGS)
                /* switch to memory context appropriate for multiple function calls */
                oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-               drv_set = rt_raster_gdal_drivers(&drv_count);
+               drv_set = rt_raster_gdal_drivers(&drv_count, 1);
                if (NULL == drv_set || !drv_count) {
                        elog(NOTICE, "No GDAL drivers found");
                        SRF_RETURN_DONE(funcctx);
@@ -6725,6 +6725,10 @@ Datum RASTER_getGDALDrivers(PG_FUNCTION_ARGS)
                /* clean up */
                pfree(nulls);
 
+               pfree(drv_set2[call_cntr].short_name);
+               pfree(drv_set2[call_cntr].long_name);
+               pfree(drv_set2[call_cntr].create_options);
+
                SRF_RETURN_NEXT(funcctx, result);
        }
        /* do when there is no more left */
index 508f6ec7e682575d930c90381b849f57a2681524..fd52280470fec6bdfab5fb30244fa511019b7b75 100644 (file)
@@ -1308,7 +1308,7 @@ static void testGDALDrivers() {
        uint32_t size;
        rt_gdaldriver drv;
 
-       drv = (rt_gdaldriver) rt_raster_gdal_drivers(&size);
+       drv = (rt_gdaldriver) rt_raster_gdal_drivers(&size, 1);
        /*printf("size: %d\n", size);*/
        CHECK(size);