[GRASS-SVN] r40119 - grass/trunk/raster/r.out.gdal

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Dec 23 07:49:44 EST 2009


Author: mmetz
Date: 2009-12-23 07:49:43 -0500 (Wed, 23 Dec 2009)
New Revision: 40119

Modified:
   grass/trunk/raster/r.out.gdal/export_band.c
   grass/trunk/raster/r.out.gdal/local_proto.h
   grass/trunk/raster/r.out.gdal/main.c
   grass/trunk/raster/r.out.gdal/r.out.gdal.html
Log:
check options before actual export

Modified: grass/trunk/raster/r.out.gdal/export_band.c
===================================================================
--- grass/trunk/raster/r.out.gdal/export_band.c	2009-12-22 15:37:11 UTC (rev 40118)
+++ grass/trunk/raster/r.out.gdal/export_band.c	2009-12-23 12:49:43 UTC (rev 40119)
@@ -24,11 +24,209 @@
 
 int exact_range_check(double, double, GDALDataType, const char *);
 
+/* exact check for each band
+ * returns 0 on success
+ * -1 if given nodata value was present in data
+ * -2 if selected GDAL datatype could not hold all values
+ * */
+int exact_checks(GDALDataType export_datatype,
+		const char *name, const char *mapset,
+		struct Cell_head *cellhead, RASTER_MAP_TYPE maptype,
+		double nodataval, const char *nodatakey,
+		int default_nodataval)
+{
+    int bHaveMinMax;
+    double dfCellMin;
+    double dfCellMax;
+    struct FPRange sRange;
+    int fd;
+    int cols = cellhead->cols;
+    int rows = cellhead->rows;
+    int ret = 0;
+
+    /* Open GRASS raster */
+    fd = Rast_open_old(name, mapset);
+    if (fd < 0) {
+	G_warning(_("Unable to open raster map <%s>"), name);
+	return -1;
+    }
+
+    /* Get min/max values. */
+    if (Rast_read_fp_range(name, mapset, &sRange) == -1) {
+	bHaveMinMax = FALSE;
+    }
+    else {
+	bHaveMinMax = TRUE;
+	Rast_get_fp_range_min_max(&sRange, &dfCellMin, &dfCellMax);
+    }
+
+    /* Create GRASS raster buffer */
+    void *bufer = Rast_allocate_buf(maptype);
+
+    if (bufer == NULL) {
+	G_warning(_("Unable to allocate buffer for reading raster map"));
+	return -1;
+    }
+    char *nulls = (char *)G_malloc(cols);
+
+    if (nulls == NULL) {
+	G_warning(_("Unable to allocate buffer for reading raster map"));
+	return -1;
+    }
+
+    /* Copy data form GRASS raster to GDAL raster */
+    int row, col;
+    int n_nulls = 0, nodatavalmatch = 0;
+
+    dfCellMin = TYPE_FLOAT64_MAX;
+    dfCellMax = TYPE_FLOAT64_MIN;
+
+    /* Better use selected GDAL datatype instead of 
+     * the best match with GRASS raster map types ? */
+
+    if (maptype == FCELL_TYPE) {
+
+	FCELL fnullval = (FCELL) nodataval;
+
+	G_debug(1, "FCELL nodata val: %f", fnullval);
+
+	for (row = 0; row < rows; row++) {
+
+	    if (Rast_get_row(fd, bufer, row, maptype) < 0) {
+		G_warning(_("Unable to read raster map <%s> row %d"),
+			  name, row);
+		return -1;
+	    }
+	    Rast_get_null_value_row(fd, nulls, row);
+	    for (col = 0; col < cols; col++) {
+		if (nulls[col]) {
+		    ((FCELL *) bufer)[col] = fnullval;
+		    n_nulls++;
+		}
+		else {
+		    if (((FCELL *) bufer)[col] == fnullval) {
+			nodatavalmatch = 1;
+		    }
+		    if (dfCellMin > ((FCELL *) bufer)[col])
+			dfCellMin = ((FCELL *) bufer)[col];
+		    if (dfCellMax < ((FCELL *) bufer)[col])
+			dfCellMax = ((FCELL *) bufer)[col];
+		}
+	    }
+	    G_percent(row + 1, rows, 2);
+	}
+    }
+    else if (maptype == DCELL_TYPE) {
+
+	DCELL dnullval = (DCELL) nodataval;
+
+	G_debug(1, "DCELL nodata val: %f", dnullval);
+
+	for (row = 0; row < rows; row++) {
+
+	    if (Rast_get_row(fd, bufer, row, maptype) < 0) {
+		G_warning(_("Unable to read raster map <%s> row %d"),
+			  name, row);
+		return -1;
+	    }
+	    Rast_get_null_value_row(fd, nulls, row);
+	    for (col = 0; col < cols; col++) {
+		if (nulls[col]) {
+		    ((DCELL *) bufer)[col] = dnullval;
+		    n_nulls++;
+		}
+		else {
+		    if (((DCELL *) bufer)[col] == dnullval) {
+			nodatavalmatch = 1;
+		    }
+		    if (dfCellMin > ((DCELL *) bufer)[col])
+			dfCellMin = ((DCELL *) bufer)[col];
+		    if (dfCellMax < ((DCELL *) bufer)[col])
+			dfCellMax = ((DCELL *) bufer)[col];
+		}
+	    }
+	    G_percent(row + 1, rows, 2);
+	}
+    }
+    else {
+
+	CELL inullval = (CELL) nodataval;
+
+	G_debug(1, "CELL nodata val: %d", inullval);
+
+	for (row = 0; row < rows; row++) {
+
+	    if (Rast_get_row(fd, bufer, row, maptype) < 0) {
+		G_warning(_("Unable to read raster map <%s> row %d"),
+			  name, row);
+		return -1;
+	    }
+	    Rast_get_null_value_row(fd, nulls, row);
+	    for (col = 0; col < cols; col++) {
+		if (nulls[col]) {
+		    ((CELL *) bufer)[col] = inullval;
+		    n_nulls++;
+		}
+		else {
+		    if (((CELL *) bufer)[col] == inullval) {
+			nodatavalmatch = 1;
+		    }
+		    if (dfCellMin > ((CELL *) bufer)[col])
+			dfCellMin = ((CELL *) bufer)[col];
+		    if (dfCellMax < ((CELL *) bufer)[col])
+			dfCellMax = ((CELL *) bufer)[col];
+		}
+	    }
+	    G_percent(row + 1, rows, 2);
+	}
+    }
+
+    /* can the GDAL datatype hold the data range to be exported ? */
+    /* f-flag does not override */
+    if (exact_range_check(export_datatype, dfCellMin, dfCellMax, name)) {
+	G_warning("Raster export results in data loss.");
+	ret = -2;
+    }
+
+    /* a default nodata value was used and NULL cells were present */
+    if (n_nulls && default_nodataval) {
+	if (maptype == CELL_TYPE)
+	    G_important_message(_("Input raster map contains cells with NULL-value (no-data). "
+				 "The value %d will be used to represent no-data values in the input map. "
+				 "You can specify a nodata value with the %s option."),
+				(int)nodataval, nodatakey);
+	else
+	    G_important_message(_("Input raster map contains cells with NULL-value (no-data). "
+				 "The value %f will be used to represent no-data values in the input map. "
+				 "You can specify a nodata value with the %s option."),
+				nodataval, nodatakey);
+    }
+
+    /* the nodata value was present in the exported data */
+    if (nodatavalmatch && n_nulls) {
+	/* default nodataval didn't work */
+	if (default_nodataval) {
+	    G_warning(_("The default nodata value is present in raster"
+			"band <%s> and would lead to data loss. Please specify a "
+			"custom nodata value with the %s parameter."),
+		      name, nodatakey);
+	}
+	/* user-specified nodataval didn't work */
+	else {
+	    G_warning(_("The given nodata value is present in raster"
+			"band <%s> and would lead to data loss. Please specify a "
+			"different nodata value with the %s parameter."),
+		      name, nodatakey);
+	}
+	ret = -1;
+    }
+
+    return ret;
+}
+
 /* actual raster band export
  * returns 0 on success
  * -1 on raster data read/write error
- * -2 if given nodata value was present in data
- * -3 if selected GDAL datatype could not hold all values
  * */
 int export_band(GDALDatasetH hMEMDS, GDALDataType export_datatype, int band,
 		const char *name, const char *mapset,
@@ -36,7 +234,6 @@
 		double nodataval, const char *nodatakey,
 		int suppress_main_colortable, int default_nodataval)
 {
-
     struct Colors sGrassColors;
     GDALColorTableH hCT;
     int iColor;
@@ -191,11 +388,8 @@
 
     /* Copy data form GRASS raster to GDAL raster */
     int row, col;
-    int n_nulls = 0, nodatavalmatch = 0;
+    int n_nulls = 0;
 
-    dfCellMin = TYPE_FLOAT64_MAX;
-    dfCellMax = TYPE_FLOAT64_MIN;
-
     /* Better use selected GDAL datatype instead of 
      * the best match with GRASS raster map types ? */
 
@@ -215,7 +409,7 @@
 		return -1;
 	    }
 	    Rast_get_null_value_row(fd, nulls, row);
-	    for (col = 0; col < cols; col++)
+	    for (col = 0; col < cols; col++) {
 		if (nulls[col]) {
 		    ((FCELL *) bufer)[col] = fnullval;
 		    if (n_nulls == 0) {
@@ -223,15 +417,7 @@
 		    }
 		    n_nulls++;
 		}
-		else {
-		    if (((FCELL *) bufer)[col] == fnullval) {
-			nodatavalmatch = 1;
-		    }
-		    if (dfCellMin > ((FCELL *) bufer)[col])
-			dfCellMin = ((FCELL *) bufer)[col];
-		    if (dfCellMax < ((FCELL *) bufer)[col])
-			dfCellMax = ((FCELL *) bufer)[col];
-		}
+	    }
 
 	    if (GDALRasterIO
 		(hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype,
@@ -257,7 +443,7 @@
 		return -1;
 	    }
 	    Rast_get_null_value_row(fd, nulls, row);
-	    for (col = 0; col < cols; col++)
+	    for (col = 0; col < cols; col++) {
 		if (nulls[col]) {
 		    ((DCELL *) bufer)[col] = dnullval;
 		    if (n_nulls == 0) {
@@ -265,15 +451,7 @@
 		    }
 		    n_nulls++;
 		}
-		else {
-		    if (((DCELL *) bufer)[col] == dnullval) {
-			nodatavalmatch = 1;
-		    }
-		    if (dfCellMin > ((DCELL *) bufer)[col])
-			dfCellMin = ((DCELL *) bufer)[col];
-		    if (dfCellMax < ((DCELL *) bufer)[col])
-			dfCellMax = ((DCELL *) bufer)[col];
-		}
+	    }
 
 	    if (GDALRasterIO
 		(hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype,
@@ -299,7 +477,7 @@
 		return -1;
 	    }
 	    Rast_get_null_value_row(fd, nulls, row);
-	    for (col = 0; col < cols; col++)
+	    for (col = 0; col < cols; col++) {
 		if (nulls[col]) {
 		    ((CELL *) bufer)[col] = inullval;
 		    if (n_nulls == 0) {
@@ -307,15 +485,7 @@
 		    }
 		    n_nulls++;
 		}
-		else {
-		    if (((CELL *) bufer)[col] == inullval) {
-			nodatavalmatch = 1;
-		    }
-		    if (dfCellMin > ((CELL *) bufer)[col])
-			dfCellMin = ((CELL *) bufer)[col];
-		    if (dfCellMax < ((CELL *) bufer)[col])
-			dfCellMax = ((CELL *) bufer)[col];
-		}
+	    }
 
 	    if (GDALRasterIO
 		(hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype,
@@ -327,46 +497,6 @@
 	}
     }
 
-    /* can the GDAL datatype hold the data range to be exported ? */
-    /* f-flag does not override */
-    if (exact_range_check(export_datatype, dfCellMin, dfCellMax, name)) {
-	G_warning("Raster export results in data loss.");
-	ret = -3;
-    }
-
-    /* a default nodata value was used and NULL cells were present */
-    if (n_nulls && default_nodataval) {
-	if (maptype == CELL_TYPE)
-	    G_important_message(_("Input raster map contains cells with NULL-value (no-data). "
-				 "The value %d was used to represent no-data values in the input map. "
-				 "You can specify a nodata value with the %s option."),
-				(int)nodataval, nodatakey);
-	else
-	    G_important_message(_("Input raster map contains cells with NULL-value (no-data). "
-				 "The value %f was used to represent no-data values in the input map. "
-				 "You can specify a nodata value with the %s option."),
-				nodataval, nodatakey);
-    }
-
-    /* the nodata value was present in the exported data */
-    if (nodatavalmatch && n_nulls) {
-	/* default nodataval didn't work */
-	if (default_nodataval) {
-	    G_warning(_("The default nodata value is present in raster"
-			"band <%s> and would lead to data loss. Please specify a "
-			"custom nodata value with the %s parameter."),
-		      name, nodatakey);
-	}
-	/* user-specified nodataval didn't work */
-	else {
-	    G_warning(_("The given nodata value is present in raster"
-			"band <%s> and would lead to data loss. Please specify a "
-			"different nodata value with the %s parameter."),
-		      name, nodatakey);
-	}
-	ret = -2;
-    }
-
     return ret;
 }
 

Modified: grass/trunk/raster/r.out.gdal/local_proto.h
===================================================================
--- grass/trunk/raster/r.out.gdal/local_proto.h	2009-12-22 15:37:11 UTC (rev 40118)
+++ grass/trunk/raster/r.out.gdal/local_proto.h	2009-12-23 12:49:43 UTC (rev 40119)
@@ -57,5 +57,8 @@
 int export_band(GDALDatasetH, GDALDataType, int, const char *, 
 		const char *, struct Cell_head *, RASTER_MAP_TYPE, 
 		double, const char *, int, int);
+int exact_checks(GDALDataType, const char *, const char *,
+                 struct Cell_head *, RASTER_MAP_TYPE, double,
+		 const char *, int);
 
 #endif /* __LOCAL_PROTO_H__ */

Modified: grass/trunk/raster/r.out.gdal/main.c
===================================================================
--- grass/trunk/raster/r.out.gdal/main.c	2009-12-22 15:37:11 UTC (rev 40118)
+++ grass/trunk/raster/r.out.gdal/main.c	2009-12-23 12:49:43 UTC (rev 40119)
@@ -366,11 +366,9 @@
 		if (export_max < dfCellMax)
 		    export_max = dfCellMax;
 	    }
-
 	}
 	G_debug(3, "Range of <%s>: min: %f, max: %f", ref.file[band].name,
 		dfCellMin, dfCellMax);
-
     }
     if (bHaveMinMax == FALSE) {
 	export_min = TYPE_FLOAT64_MIN;
@@ -489,6 +487,34 @@
 	    set_default_nodata_value(datatype, export_min, export_max);
     }
 
+    /* exact range and nodata checks for each band */
+    G_message(_("Checking GDAl data type and nodata value"));
+    for (band = 0; band < ref.nfiles; band++) {
+	if (ref.nfiles > 1) {
+	    G_verbose_message(_("Checking options for raster map <%s> (band %d)..."),
+			      G_fully_qualified_name(ref.file[band].name,
+						     ref.file[band].mapset),
+			      band + 1);
+	}
+
+	retval = exact_checks
+	    (datatype, ref.file[band].name, ref.file[band].mapset,
+	     &cellhead, maptype, nodataval, nodataopt->key,
+	     default_nodataval);
+
+	/* nodata problem */
+	if (retval == -1) {
+	    if (flag_f->answer)
+		G_warning(_("Forcing raster export."));
+	    else
+		G_fatal_error(_("Raster export aborted."));
+	}
+	/* data don't fit into range of GDAL datatype */
+	else if (retval == -2) {
+	    G_fatal_error(_("Raster export aborted."));
+	}
+    }
+
     /* Create dataset for output with target driver or, if needed, with in-memory driver */
     char **papszOptions = NULL;
 
@@ -550,6 +576,7 @@
     AttachMetadata(hCurrDS, metaopt->answers);
 
     /* Export to GDAL raster */
+    G_message(_("Exporting to GDAL raster"));
     for (band = 0; band < ref.nfiles; band++) {
 	if (ref.nfiles > 1) {
 	    G_verbose_message(_("Exporting raster map <%s> (band %d)..."),
@@ -568,17 +595,6 @@
 	    G_warning(_("Unable to export raster map <%s>"),
 		      ref.file[band].name);
 	}
-	/* nodata problem */
-	else if (retval == -2) {
-	    if (flag_f->answer)
-		G_warning(_("Forcing raster export."));
-	    else
-		G_fatal_error(_("Raster export aborted."));
-	}
-	/* data don't fit into range of GDAL datatype */
-	else if (retval == -3) {
-	    G_fatal_error(_("Raster export aborted."));
-	}
     }
 
     /* Finaly create user requested raster format from memory raster 
@@ -686,17 +702,8 @@
 
     case GDT_Float64:
     case GDT_CFloat64:
-	/* not possible because DCELL is FLOAT64, not 128bit floating point, but anyway... */
-	if (max < TYPE_FLOAT64_MIN || min > TYPE_FLOAT64_MAX) {
-	    G_warning(_("Selected GDAL datatype does not cover data range."));
-	    G_warning(_("GDAL datatype: %s, range: %g - %g"),
-		      GDALGetDataTypeName(datatype), TYPE_FLOAT64_MIN,
-		      TYPE_FLOAT64_MAX);
-	    G_warning(_("Range to be exported: %f - %f"), min, max);
-	    return 1;
-	}
-	else
-	    return 0;
+	/* not needed because FLOAT64 should always cover the data range */
+	return 0;
 
     default:
 	return 0;
@@ -793,7 +800,7 @@
 
     case GDT_Float64:
     case GDT_CFloat64:
-	/* not needed because FLOAT64 is double */
+	/* not needed because FLOAT64 is equal to double */
 	return 0;
 
     default:
@@ -854,7 +861,6 @@
     case GDT_CFloat64:
 	return 0.0 / 0.0;
 
-    /* should not happen: */
     default:
 	return 0;
     }

Modified: grass/trunk/raster/r.out.gdal/r.out.gdal.html
===================================================================
--- grass/trunk/raster/r.out.gdal/r.out.gdal.html	2009-12-22 15:37:11 UTC (rev 40118)
+++ grass/trunk/raster/r.out.gdal/r.out.gdal.html	2009-12-23 12:49:43 UTC (rev 40119)
@@ -108,7 +108,7 @@
 <em>r.out.gdal</em> exports may appear all black or gray on initial
 display in other GIS software. This is not a bug of <em>r.out.gdal</em>,
 but often caused by the default color table assigned by that software.
-The dafault color table may be grayscale covering the whole range of
+The default color table may be grayscale covering the whole range of
 possible values which is very large for e.g. Int32 or Float32. E.g.
 stretching the color table to actual min/max would help (sometimes under
 symbology).
@@ -132,7 +132,7 @@
 
 <h4>Improving GeoTIFF compatibility</h4>
 
-To create a GeoTIFF that is highly compatibility with various other GIS
+To create a GeoTIFF that is highly compatible with various other GIS
 software packages, it is recommended to keep the GeoTIFF file as simple
 as possible. You will have to experiment with which options your
 software is compatible with, as this varies widely between vendors and



More information about the grass-commit mailing list