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@gclements.plus.com>