6

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.

1
  • You can do this sort of process in raster calc but it is a bit of a logic puzzle, using reclass to create binary masks eg 30,34 = 1 is a start. I could type out what I think would work but I would probably be wrong somewhere.
    – Sethinacan
    Commented Mar 21, 2016 at 16:21

2 Answers 2

5

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)
3
  • This is a very impressive and insightful answer! +1
    – Joseph
    Commented Mar 22, 2016 at 10:20
  • @Steven Kay, somehow the part of the formula where it checks for nodata doesn't work. My first raster doesn't have nodata, but the second does. The output raster includes nodata pixels where it's nodata in the second raster, instead of keeping the value from the 1st raster. I've put a link in my dropbox to the test files I'm using (two .tif files, raster1=circa, raster2=osm) if you want to take a look. Also, I had to replace the g2 in your formula by h1 to make it work.
    – kaycee
    Commented Mar 22, 2016 at 15:33
  • thanks for posting your files. I wasn't able to get this to work in Processing but I tried in SAGA itself and saw the same results you did. Not sure what's going on there :/ Will try again later, in the meantime try changing the with nodata setting on the algorithm and see if that works?
    – Steven Kay
    Commented Mar 22, 2016 at 20:57
3

I don't think the QGIS Raster Calculator supports conditional statements but the SAGA Raster Calculator does support the ifelse() statement which you can access from the Processing Toolbox.

I don't have an example raster to test but you could try something like the following formula which aims to follow your logic:

ifelse(eq(a,30 AND 34),ifelse(eq(b,!=0),a,b),a)

where:

a = first raster
b = second raster

Disclaimer: I rarely worked with rasters so this is more of a guess than anything else.

4
  • You can also compare to 0/0 to check for nodata (if nodata isn't 0).
    – Steven Kay
    Commented Mar 21, 2016 at 18:58
  • Thanks for your answer Joseph ! Steven, how would you do that ?
    – kaycee
    Commented Mar 21, 2016 at 19:04
  • @Joseph , eq(a, 30 AND 34) doesn't work. Looks like it can't take the OR operator... I'm trying to figure out a way to go around that...
    – kaycee
    Commented Mar 21, 2016 at 19:30
  • @kaycee - Check the brilliant answer given by Steven Kay which should avoid the error =)
    – Joseph
    Commented Mar 22, 2016 at 10:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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