[GRASS-user] r.mapcalc and nested if

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;
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..
Any idea?

Thanks
Luca
--
View this message in context: http://n2.nabble.com/r-mapcalc-and-nested-if-tp4901916p4901916.html
Sent from the Grass - Users mailing list archive at Nabble.com.

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))'

Thanks
Luca
--
View this message in context: http://n2.nabble.com/r-mapcalc-and-nested-if-tp4901916p4901925.html
Sent from the Grass - Users mailing list archive at Nabble.com.

thedok78 pisze:

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))'

Thanks
Luca
  

seem that much easier will be:

r.neighbors input=your_map method=mode size=3 output=mode_output
r.mapcalc 'first_map=if(your_map==1,output_mode,your_map)'
r.mapclac 'final=if(first_map=1,0,first_map'

Hi there,

may be the last command need double ==

r.mapclac ‘final=if(first_map==1,0,first_map’

cheers

milton

2010/4/14 Jarek Jasiewicz <jarekj@amu.edu.pl>

thedok78 pisze:

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))’

Thanks
Luca

seem that much easier will be:

r.neighbors input=your_map method=mode size=3 output=mode_output
r.mapcalc ‘first_map=if(your_map==1,output_mode,your_map)’
r.mapclac ‘final=if(first_map=1,0,first_map’


grass-user mailing list
grass-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-user

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>

Thank you all for yours answers!
I'll explain my problem:

I have got a raster map with a lot of small area like this one:

112 112 112 122 112
112 112 1 1 122
122 1 1 1 122
112 122 122 112 112

The boundary is made cells with values from 100 to 200 instead the inner
ones have got 1 as value.
I need to fill the inner cells with the mode of a 3x3 window.
Using a loop until there are no more cell with 1 as value, I started with
this approach:

map=if(map ==
1,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]),0)

I added the map == 1 condition due the null cells outside the boundary,
which set the mode to null and slowly eat all my areas :slight_smile:

Using that syntax the loop goes smooth but after a certain point the cells=1
remain the same because the mode is always 1.

I discarded r.neighbors because it changes also the values on the boundary
which should remain the same.

Any hint?
Thank you very much.

Luca

--
View this message in context: http://n2.nabble.com/r-mapcalc-and-nested-if-tp4901916p4913028.html
Sent from the Grass - Users mailing list archive at Nabble.com.

thedok78 wrote:

I have got a raster map with a lot of small area like this one:

112 112 112 122 112
112 112 1 1 122
122 1 1 1 122
112 122 122 112 112

The boundary is made cells with values from 100 to 200 instead the inner
ones have got 1 as value.
I need to fill the inner cells with the mode of a 3x3 window.
Using a loop until there are no more cell with 1 as value, I started with
this approach:

map=if(map ==
1,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]),0)

I added the map == 1 condition due the null cells outside the boundary,
which set the mode to null and slowly eat all my areas :slight_smile:

Using that syntax the loop goes smooth but after a certain point the cells=1
remain the same because the mode is always 1.

I discarded r.neighbors because it changes also the values on the boundary
which should remain the same.

r.mapcalc 'map.tmp = if(map == 1, null(), map)'
r.neighbors in=map.tmp out=map.mode method=mode size=3
r.mapcalc 'map.filled = if(map == 1, map.mode, map)'

Replacing the ones with nulls in the first step will cause r.neighbors
to ignore those cells when calculating the mode.

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