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

Markus Metz markus.metz.giswork at googlemail.com
Thu Apr 16 14:28:53 EDT 2009


Glynn Clements wrote:
> 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.
>   
Not sure if your Nope refers to all of the above or only some of the 
above ;-)
Int32 is preferable over UInt32, ok, but it is possible to export a CELL 
(or any other) raster as UInt32. With regard to the type casting, in 
trunk, 0x80000000 would be cast to double:
http://trac.osgeo.org/grass/browser/grass/trunk/raster/r.out.gdal/main.c#L306
and then to UInt32, only replaced NULL cells, not the metadata nodata value:
http://trac.osgeo.org/grass/browser/grass/trunk/raster/r.out.gdal/main.c#L440

>
> 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.
>   
out of range of CELL, not GDT_UInt32. Input can not be GDT_UInt32, 
unless you are referring to r.in.gdal instead of r.out.gdal (leaving out 
r.external links). If your Nope refers to 0x80000000 as working nodata 
value for Int32, you're right, I was too fast. gdal (in r.out.gdal with 
export type Int32) does conversions of 0x80000000 replacing NULL cells 
but not of 0x80000000 as the nodata value in the metadata -> information 
loss about what cells are nodata.
> r.in.gdal can't just read the data as GDT_UInt32, as that would result
> in negative values being converted to zero.
>   
??? should r.in.gdal not import data as they are, e.g. UInt32, and then 
select a grass raster type that can hold the data range, FCELL or DCELL 
for UInt32, but not CELL?
> Ultimately, exporting CELL data as GDT_UInt32 is a bad idea, as it
> cannot represent negative values.
The new version of r.out.gdal checks if the grass raster data fit into 
the selected GDAL data type, if not, aborts with a message telling you 
the range of the raster to be exported and the range of the selected 
GDAL data type. It is then easy to figure out an appropriate GDAL data 
type with the help of the manual.
>  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.
>   
Still, it is possible. Your comment could go into the manual. All the 
complex GDAL data types are also not represented by GRASS raster types.
>
> The only "fool-proof" nodata value for CELL is 0x80000000; all other
> values may be actual data values.
>   
For grass rasters of type CELL, not for gdal export as Int32. gdalinfo 
says NoData Value=2147483648, but cells that should be nodata are 
-2147483648 and are thus not recognized as nodata.
> 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).
>   
As above, this is checked against in trunk and devbr6 and no longer 
possible.

I could not find a fool-proof nodata value for Int32 exports in my tests 
(independent of the grass raster map type), so I would leave it to the 
user and within r.out.gdal make sure the selected nodata value is not 
present in the grass raster.

Markus M

PS: I don't insist on exporting as UInt32, that was just an example. A 
better example would have been the troublemaker UInt16.


More information about the grass-dev mailing list