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

Glynn Clements glynn at gclements.plus.com
Mon Apr 20 01:02:58 EDT 2009


Markus Metz wrote:

> >> That would also mean that r.out.gdal with type = GDT_Int32 and nodata = 
> >> 2147483648, NULL cells become -2147483648 but the nodata value in the 
> >> metadata stays 2147483648 (gdalinfo on the export output), which in turn 
> >> means that other software, also QGIS, does not see any nodata cells in 
> >> the export output ->information loss about NULL cells. That's why I 
> >> wouldn't use 0x80000000 as default nodata value for GDT_Int32 in 
> >> r.out.gdal even if r.in.gdal has no problems with it.
> >
> > You're misinterpretating my use of "0x80000000" here. I'm talking
> > about the C interpretation, which is the (signed) integer value
> > -2147483648.
> 
> OK, but I have tested r.out.gdal with type = GDT_Int32 and nodata = 
> 0x80000000. Same result: NULL cells become -2147483648 but the nodata 
> value in the metadata says 2147483648 (gdalinfo on the export output),

Yes. I know. Running "r.out.gdal ... nodata=0x80000000" is
misinterpreting what I was saying, as r.out.gdal parses nodata= as a
floating-point value.

I'm talking about using (GDT_Int32)0x80000000 (i.e. -2^31) or
(GDT_UInt32)0x80000000 (i.e. +2^31) as appropriate for the destination
type.

> >> For r.out.gdal, there was discussion about not to override user options 
> >> and instead issue an error or a warning (going for error now) that the 
> >> nodata value is out of range.
> >>     
> >
> > This isn't about overriding user options, but interpreting them
> > correctly.
> 
> Close to "the module knows better" which is not desirable according to 
> Dylan and Moritz.

No, the opposite. Writing code which does what the user asks for
rather than doing something else which is easier to code.

> > It's debatable whether just using atof(nodataopt->answer) directly is
> > actually a correct interpretation when the input map is CELL, or
> > whether the code should use e.g. atoi(nodataopt->answer) or
> > (CELL)atof(nodataopt->answer) for CELL inputs. Reading as int (or
> > casting to it) will interpret 0x80000000 as -2^31, while reading as FP
> > will interpret it as 2^31.
> 
> If r.out.gdal should support out of range nodata values, and the nodata 
> value is read with atof(), 2^31 should stay 2^31and not be cast to 
> -2^31. The GUI description of the nodata option says that it is of type 
> float (actually it's a double), i.e. suggesting that any value that is 
> representable as floating point is ok.

That's a limitation of the parser. If the input is CELL, then the
nodata value which the input data uses isn't any kind of float. It
might be more correct to have separate int/float nodata options.

OTOH, GDAL's no-data value is always a double, even for integer data.

> > OTOH, reading as FP allows you to specify +2^31 as the nodata value
> > when exporting CELL as UInt32. Maybe it would be better to read as
> > double then cast to the destination type.
> 
> Hmm, then it would be no longer possible to have an out-of-range nodata 
> value in the metadata. I would support that solution, but it was 
> explicitly requested to obey all user options when the -f flag is used, 
> also writing the nodata value as it is to the metadata. It is then up to 
> the user to figure out what happened to the NULL cells, assuming that 
> the user knows what happens when using the -f flag.

I can see some point to that, but may be confusing for the user, who
may assume that they're talking about the data's no-data value when
they're actually specifying GDAL's no-data value.

> > Even so, 0x80000000 is still the ideal value for exporting CELL data
> > to either UInt32 or Int32. You just have to pick the correct
> > interpretation of it (unsigned int or signed int respectively).
> >   
> The current as well as previous policy of r.out.gdal is to not to 
> interpret the nodata value. It is written as is (currently double) to 
> metadata, same like e.g. gdal_translate -a_nodata behaves.

It doesn't have any choice about interpreting it. nodataopt->answer is
a char*, while GDALSetRasterNoDataValue() expects a double. There are
several ways to convert a char* to a double; atof() may be the
simplest to implement, but is it the most correct?

> Afraid of rewriting large parts of r.out.gdal: can't we just use 
> -2147483648 as default nodata value for Int32

Yes.

> and 0 as default nodata value for UInt32?

No; 0 is a valid data value. Use +2147483648, as that will never occur
in the input data. Or even any value >= 2147483648.

> Getting tired of this UInt32 example, but again: 
> (unsigned int) 0x80000000 is 2^31, yes?

Yes.

> Then this value would be right 
> in the middle of the range of UInt32, and can cause data loss when 
> exporting a FCELL raster as UInt32 .

In that case, use (double) 0xFFFFFFFFU, which will never exist in CELL
or FCELL data.

Maybe the default should depend upon the input type?

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


More information about the grass-dev mailing list