[GRASS-dev] Re: [GRASS GIS] #73: r.out.gdal tiff output does not work

Glynn Clements glynn at gclements.plus.com
Thu Apr 16 13:04:47 EDT 2009


Markus Metz wrote:

> >> 3. Allow the user to specify what they would like NULL cells encoded as. 
> >> Unless I am overlooking something, it would seem reasonable to export a CELL 
> >> map to a signed integer format, and use some obvious negative value for NULL:
> >>     
> >
> > If you're exporting to a 32-bit (signed or unsigned) integer format,
> > the obvious choice for null is 0x80000000. That's what GRASS uses
> > internally, so it can never occur as a legitimate value (if a
> > computation ends up producing that value, it will get treated as a
> > null in all regards).
> >   
> 0x80000000 as nodata value seems to work with GeoTIFF for Int32 but not 
> for UInt32, here gdalinfo tells me NoData Value=2147483648 which is well 
> within the range of UInt32. It may be a problem that nodataval in 
> r.out.gdal is of type double, so 0x80000000 is cast to double and then 
> either back to int or left as double. In the case of UInt32, the raster 
> to be exported is currently read as DCELL, written as GDT_Float64 and 
> then converted to GDT_UInt32. There is a lot of type casting going on in 
> r.out.gdal, making tests a bit complicated.

Nope.

The problem is that r.in.gdal reads the data as GDT_Int32, which
causes GDAL to clamp 0x80000000 to 0x7fffffff.

If the input is GDT_Int32, GDAL interprets 0x80000000 as -2147483648,
which is within the range of an int. But if the input is GDT_UInt32,
0x80000000 is interpreted as +2147483648, which is out of range.

r.in.gdal can't just read the data as GDT_UInt32, as that would result
in negative values being converted to zero.

Ultimately, exporting CELL data as GDT_UInt32 is a bad idea, as it
cannot represent negative values. As CELL is signed, exporting as
GDT_UInt32 is lossy; half the range of the source type is
unrepresentable, while half the range of the destination type is
unused.

> In the end, the value 
> assigned to NULL cells must match the nodata value in the metadata, and 
> a safe default choice seems to be type min or type max.
> 
> NaN seems to work for Float32 and Float64, at least gdal reports NoData 
> Value=nan and QGIS display is ok for GTiff, HFA, PAux, EHdr. NaN is 
> constructed with 0.0/0.0, idea from r.univar.
> 
> IMHO, using 0x80000000 or similar can be dangerous (not sure about NaN) 
> because I don't know how these values are supported by all the different 
> file formats and all the different applications. Testing welcome!
> 
> I would suggest to use some fool-proof default nodata value for GDAL 
> integer types, i.e. type min or type max, check if it works, otherwise 
> abort and ask the user to specify a nodata value. For GDAL floating 
> point types, it could be recommended to use the default nodata value 
> (NaN) instead of specifying a nodata value.

The only "fool-proof" nodata value for CELL is 0x80000000; all other
values may be actual data values.

More generally, you can't losslessly export N+1 data values using a
format which only supports N values (e.g. exporting 0-255 plus null
using only one byte per cell).

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list