[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