I was wondering if there is a easy way (GDAL) to replace GeoTIFF pixels that are -nan with a different value (e.g. 100)?

I tried

gdal_calc.py -A my.tif --outfile=result.tif --calc="A-(A==-nan)*(-nan - 100))" 

following some examples, but this doesn't work because NaN messes with arithmetic operations and turns everything it touches into a NaN.

Any pointers to alternatives?

Ideally a command line as with gdal_calc.py.

  • NaN (Not a Number) is a database value... what data type are your pixels? I believe that IEEEE floating point supports INF and NaN, perhaps if you multiply by a fixed value and output as Int32 then divide by the same as Float32. You are right that these values totally muck with arithmetic operations, but how did they get there in the first place? Perhaps you could try an always true statement like A>-9999999 which should always return true for values and if that doesn't work then use the opposite A<99999999 but I have a feeling that those values will stick. – Michael Stimson Feb 11 '15 at 22:08
  • The issue is I don't even know what's the real value. I was given the GeoTIFF. I used gdallocationinfo my.tif 1 1 -valonly, and it only returns -nan. – tinlyx Feb 11 '15 at 22:19
  • The data type is 64bit float – tinlyx Feb 11 '15 at 22:20
  • If they're NaN I think it would be safe to convert them to NODATA, try the answer that I have submitted, you need to find how the value is stored in the ASC by locating one value; from memory I think it's -1#QNaN. If the file is small you can use notepad but for big rasters (more than a few MB) then you will need to find a better text editor. – Michael Stimson Feb 11 '15 at 22:26

You can use the flag --NoDataValue=NODATAVALUE to replace NoDataValue.

See the third example here

  • This does not work with A/B, where B=0 – Poiana Apuana Sep 23 '17 at 9:16
  • 1
    Then do A/(B+(B==0)) or similar – mikewatt Jul 19 at 17:15
  • Please provide a full example based on OP's commandline. – bugmenot123 Jul 25 at 13:25

One strategy is to use a nan_to_num function from Numpy, however it always uses 0. for nan, and there are unfortunately no parameters to replace nans with custom values.

$ gdal_calc.py -A nan.tif --outfile=result.tif --calc="nan_to_num(A)"

This is one of the most annoying things I have found in trying to deal with gdal_calc.py (or the raster calculator GUI). Anywhere there is a nodata in any of the inputs the output gets set to nodata. So let's say you have a mask that has values inside a region you want to modify, and nodata outside. The result will be that the pixels inside the region are correctly modified, and the pixels outside are all set to nodata. That's no good if you want to modify part of a map while leaving the rest alone.

What you need is a mask with values inside the region and valid data zeros (or some other tag value) outside. No problem, you say, I just need to change the nodatas in the mask layer to zeros. Should be a snap. I have a raster calculator. Turns out it's not so easy.

When I tried googling an answer to this question the most common advice was, here's how to do it with GRASS or Numpy, or some other plugin. If I'm trying to do something that should take me less than 5 minutes, and someone's advice is first install and learn how to use a completely different tool, I stop reading immediately.

You can do it with GDAL. There are two scripts that you will need. doktoreas' answer about the --NoDataValue option of gdal_calc.py is part of the answer. This changes all of the nodata pixels to have that value, and sets the metadata so that value is the nodata value. If you just do that, the raster calculator will still treat them as nodata and produce nodata in the result. Next you have to use the -a_nodata option of gdal_translate. This changes the metadata of what value is treated as nodata without changing the values of pixels that have the old nodata value. This leaves your pixels with a numeric value that is not treated as nodata.

gdal_calc.py -A input.tif --outfile=intermediate.tif --calc="A" --NoDataValue=0
gdal_translate intermediate.tif result.tif -a_nodata -1

This might be totally tedious but if you convert to Esri ASC (GDAL_Translate -of AAIGRID) which is a text based format and then open in a really good text editor like Notepad++ or VI/VIm, or write a python script, you can replace bad values using find & replace.

Then save & close the file and translate to a GeoTiff

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.