GDAL – Patch Over Raster A with Values from Raster B

gdalgdal-merge

I'm trying to come up with a way to patch over raster A with data from raster B. Extent of raster A can be smaller than raster B.

More specifically, I'd like to patch over nodata values from raster A with raster B values as well as create pixels in raster A where they exist in raster B.

Simple gdal_merge doesn't work for me as this doesn't work:

gdal_merge -o out.tif rasterA.tif rasterB.tif

as it is replacing values in raster A with values of raster B and would like values in raster A to be kept where they are not nodata.

and this won't work

gdal_merge -o out.tif rasterB.tif rasterA.tif

as it will replace values in raster B with nodata from raster A.

gdal_calc won't work, as rasters have different dimesions.

I'm aware that this such conditional logic can be implemented in Arc, but I'm looking for a solution using GDAL. Any suggestions?

Best Answer

Formulating the question helped me answer it myself. To solve this, 3 steps are required:

Step 1: create a nodata mask equal in size to raster B (255 is the nodata value)

gdal_calc -A rasterB.tif --outfile=mask.tif --calc="255"

Step 2: merge over raster A over this mask

gdal_merge -o rasterA_extended.tif mask.tif rasterA.tif

Step 3: conditional gdal_calc, update only where nodata

gdal_calc -A rasterA_extended.tif -B rasterB.tif --outfile=result.tif --calc="A*(A<255) + B*(A==255)"

Additionally, if don't want to copy over value, but you need to set all pixels to be patched to a specific value (0 in my case), you can use this logic:

gdal_calc -A rasterA_extended.tif -B rasterB.tif --outfile=!res.tif --calc="A*(A<255) + 0*(logical_and(A==255,B<>255)) + A*(logical_and(B==255,A<>255))" Note that B is never assigned.