[GIS] How to update raster pixel values based on another raster with conditions in QGIS

pythonqgisrasterraster-calculator

I have 2 land cover rasters. I want to update parts of the first raster with values from the second using QGIS.

The workflow should be like this:

1. Select values equal to 30 and 34 in the first raster.

2. Check if there is a value at the corresponding pixel in the second raster.

3. If there is a value in the second raster and it is different from 0,
   change the value in the first raster to the value of the second raster.

4. If not, do nothing.

How should I proceed to achieve such updating tasks? I think raster calculator is not supporting conditional statements, so I'm not sure how I can do that.

test files used are here.

Best Answer

The QGIS raster calculator seems limited, but you can achieve a lot once you know a couple of tricks

These hold true for both SAGA and QGIS raster calculators

true = 1
false = 0

You can use addition to simulate boolean logic

X or Y : x+y > 0
X and y : x+y = 2

I've modified Joseph's answer to use these, and get around the lack of boolean logic in SAGA's grid calculator

ifelse(gt(eq(g1,30)+eq(g1,34),0),ifelse(eq(g2,0/0),g1,g2),g1)

This i've tested, the example below shows my two images. The first is a land cover classification, the second is a gradient based on latitude (generated in saga using ypos()). The final image, I've taken two of the classified values and replaced them with the gradient value.

enter image description here

Be careful doing this in SAGA itself, it's all to easy to overwrite your original raster. Probably safer to call from Processing, as Joseph suggested.

In QGIS the same would be as follows. I've assumed your rasters are a (first) and b (second), and you're only using band1 (@1)

"a@1" + ((((("a@1"=30)+("a@1"=34) >=1) + ("b@1">0)) =2) *("b@1"-"a@1"))

EDIT

Just realised I'm copying over all data pixels from the second image, including zeros. This slightly more complex expression should do the job...

ifelse(gt(eq(g1,30)+eq(g1,34),0),ifelse(eq(g2,0/0),a,ifelse(eq(g2,0),g1,g2)),g1)