7

I'm looking for an equivalent of the conditional expression "Con" from arcpy in an open source spatial analysis package. I'd prefer to use QGIS or R.

To provide some additional detail, I need to evaluate some moderately complicated conditional statements in map algebra, e.g., if the value for one raster is above a certain threshold, use one value, but if the value is below that threshold, use a value based on whether another raster value is above or below another threshold, e.g.:

newraster = Con(raster1 < 4, 0, Con(raster2 > 3, 0.5, 1))

Caveat: I have not been able to confirm that the above code will execute, since the machine I'm currently using does not have any ESRI products installed.

Erica
  • 8,974
  • 4
  • 34
  • 79
user1521655
  • 1,319
  • 15
  • 24
  • I don't really know arcpy enough, but I guess this answer here could be related to what you ask in pyqgis: http://gis.stackexchange.com/a/59305/9839 and see here for the raster calculator syntax – Matthias Kuhn Aug 26 '13 at 14:56
  • 1
    Con can be used to accomplish a great deal of tasks. Could you please describe what specifically you are trying to accomplish (e.g. replace all 0's with NaN)? – Aaron Aug 26 '13 at 15:00
  • @MatthiasKuhn, thank you for your input. The raster calculator syntax might be helpful, but I'm not seeing any syntax for conditional statements, so I think I'd need to use some combination of masks and unions to do what I need done. I'm wondering if this is the most computationally efficient approach. – user1521655 Aug 26 '13 at 17:05
  • 1
    @Aaron, I've tried to clarify by editing my original question. I hope this answers your question. – user1521655 Aug 26 '13 at 17:06
  • What form does your data take? Do you have a data.frame or some kind of sp object? At first glance it looks as if straightforward R operations would do the trick if you are using a data frame. It would also help if we had reproducible data and code from you... – SlowLearner Aug 26 '13 at 20:38
  • If your data is already in rasters, then the raster package seems to have abundant functions for comparing and manipulating raster objects - check out the Compare-methods section of the reference pdf. – SlowLearner Aug 26 '13 at 21:25
  • I've had no trouble finding methods for comparing values. I have had trouble finding documentation on a way of applying conditionals. I may be looking at the documentation incorrectly, though. – user1521655 Aug 26 '13 at 21:48

2 Answers2

10

Its a one-liner - the trick is to add the true value times the condition being true to the false value times the condition being not true. Only one of those parts will be true, so you end up getting the value you want.

Con=function(condition, trueValue, falseValue){
    return(condition * trueValue + (!condition)*falseValue)
    }

Sample:

r=raster(matrix(1:12,3,4))
q=Con(r<6,0,1)

Your case:

raster1=r
raster2=raster(matrix(12:1,3,4))

as.matrix(raster1)

     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

as.matrix(raster2)

     [,1] [,2] [,3] [,4]
[1,]   12    9    6    3
[2,]   11    8    5    2
[3,]   10    7    4    1


q = as.matrix(Con(raster1<4,0,Con(raster2>3,.5,.1)))
as.matrix(q)
     [,1] [,2] [,3] [,4]
[1,]    0  0.5  0.5  0.1
[2,]    0  0.5  0.5  0.1
[3,]    0  0.5  0.5  0.1

Conditional that takes a value from a raster:

as.matrix(Con(raster1>6,0,raster2))

     [,1] [,2] [,3] [,4]
[1,]   12    9    0    0
[2,]   11    8    0    0
[3,]   10    7    0    0

Not tested with NA's though...

This is just the raster version of ifelse.

Spacedman
  • 63,755
  • 5
  • 81
  • 115
1

There is no well-documented conditional conditional function in QGIS raster calculator, however, there exists a hack:

(condition) = 0

This will create a raster with values 0 where condition is not met, and 1 elsewhere. So, you can create basic if-then-else calculation like this:

(("raster@1" > 4) = 0) * 4 + (("raster@1" < 4) = 0) * 5

The resulting raster will have pixel value of 4 where source raster has values below 4, and 5 where source raster has values higher than 4. You can try this on some simple example(eg. elevation model) to get an idea how it works. The multiplication is essential and you can't just directly replace 0 with desired value - at least in QGIS 2.4 this does not work.