[GRASS-user] r.mapcalc and nested if

Glynn Clements glynn at gclements.plus.com
Thu Apr 15 06:54:11 EDT 2010


thedok78 wrote:

> 
> Hello everybody,
> I need to run a complex r.mapcalc expression, but I can't understand how to
> use nested if.
> This is the expression:
> r.mapcalc
> 'map2=if(mode(map[-1,-1],map[-1,0],map[-1,1],map[0,1],map[1,1],map[1,0],map[1,-1],map[0,-1])==1,0,mode(map[-1,-1],map[-1,0],map[-1,1],map[0,1],map[1,1],map[1,0],map[1,-1],map[0,-1]))'
> 
> The idea is this:
> if the cell value is 1, do the mode else skip that cell; 

What do you mean by "skip"? Copy the input cell?

> if the mode is equal to 1 assign 0 to that cell else assign the mode value.
> 
> The r.mapcalc expression I just posted produce wrong result..

> Sorry, this is the expression:
> r.mapcalc 'map2=if(map ==1,if(mode(map[-1,-1],map[-1,0],map[-1,1],map[0,1],map[1,1],map[1,0],map[1,-1],map[0,-1])==1,0,mode(map[-1,-1],map[-1,0],map[-1,1],map[0,1],map[1,1],map[1,0],map[1,-1],map[0,-1]),map))'

First, use a variable to avoid the repeated mode calculation:

r.mapcalc 'map2=eval(m = mode(map[-1,-1],map[-1,0],map[-1,1],map[0,1],map[1,1],map[1,0],map[1,-1],map[0,-1]),\
          if(map==1,if(m==1,0,m,map)))'

That four-argument inner "if" expression is wrong (it's syntactically
valid, but it doesn't make sense as the first expression cannot be
negative). Based upon your description, I suspect that you want:

          if(map==1,if(m==1,0,m),map)

[IOW, the innermost right parenthesis should move to the left.]

But I'd suggest calculating the mode using r.neighbors and a custom
mask to exclude the centre cell, e.g.:

	cat > weights.txt <<EOF
	1 1 1
	1 0 1
	1 1 1
	EOF
	r.neighbors in=map out=map.mode size=3 method=mode weights=weights.txt
	r.mapcalc 'map2=if(map==1,if(map.mode==1,0,map.mode),map)'
	g.remove rast=map.mode
	rm weights.txt

The r.mapcalc approach will work, but expressions which use many
neighbourhood terms tend to be hard to read and thus error-prone.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-user mailing list