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