Simple inpainting algorithms generally use a smoothness heuristic, so this behavior is common. In some algorithms there will be an option to provide separate masks for inpainting (to be filled) and "seeding" (to be smoothly connected to the fill). If that is a possibility, then you could force the smoothing to only look at river cells. If not, you could set the inpainting mask to include all non-river cells, and then mask out the un-needed areas after inpainting. (I have done this actually to inpaint shoreface bathymetry, excluding land.) For performance, with this method you may want to do the inpainting only in AOI tiles buffered around each river-road intersection.
One (slightly hacky) way of doing it is to use an intermediate VRT with the gdalbuildvrt
command and specifying a new NoData value with the srcnodata
and vrtnodata
arguments. This does actually change the underlying values.
First, get your actual nodata value from gdalinfo
:
$ gdalinfo input.tif | grep No
NoData Value=3.39999995214436425e+38
Assign it to a bash variable: na=3.39999995214436425e+38
Or if you have jq
installed (in ubuntu/debian based Linux distros sudo apt install jq
):
na=$(gdalinfo input.tif -json | jq '.bands[0].noDataValue')
And use it in the following examples:
gdalbuildvrt -srcnodata ${na} -vrtnodata 0 output.vrt input.tif
However, it also sets those values to NoData in the output, so you need to specify a different value to be considered as NoData when converting to your final GeoTIFF.
gdal_translate -a_nodata ${na} output.vrt output.tif # original 3.39999995214436425e+38 values from input.tif are now 0
Chaining it together with a pipe so you don't need to clean up any intermediate VRT files:
gdalbuildvrt -srcnodata ${na} -vrtnodata 0 /vsistdout/ input.tif | gdal_translate -a_nodata -9999 /vsistdin/ output.tif
Best Answer
I got curious and tried the different fill nodata functions. As you can see the regular SAGA Close Gaps produced the least anomalies. It also took the longest.