[GRASS-user] r.mapcalc help

Hi List,

I'm writing a short python script that involves some mapcalc and I
could really use some more eyes on the problem. I'm not sure why I'm
getting the results that I am - might be that I'm confused about the
operation with isnull(). The input consists of two maps:

1. (let it be 'A') a circular area, derived from a v.buffer-v.to.rast
operation, that contains distances from r.grow.distance
2. (let it be 'B') a map of distances from r.grow.distance that covers
a much larger area than the buffer circle in map 1.

All of the buffer circles created are within the area covered by map B
and some of the map A circles may overlap one another. Below is some
pseudo-code with the mapcalc operation in actual code. So far, my
result at the end, which is essentially a distance map that has been
updated by the circles in map A, is just a map a nulls.

def main():
get cat values from a vector map
for i in cat_values:
v.extract -r cat value i
v.to.rast extracted_cats
r.grow.distance to rast_extracted_cats #essentially get the distances
to all points in vector while leaving out one at a time
v.extract cat_value i #to use as the center for a buffer operation
that will then be used to query the distance map created in the last
step
v.buffer with extracted_cat_i
v.to.rast extracted_cat_i
r.mapcalc if(extracted_cat_i,distance_map) #this step uses the buffer
area to mask the distance map and is now map 'A'
###the problematic r.mapcalc operation is below###
subprocess.call([
  "r.mapcalc",
  "B = if(!isnull(A) && temp_rast_focus_ <= B,A,B"])
return()

The idea is that each map A will be used to update B only if A is less
than (or equal to) B. It seems that the first run through the loop
creates a map B which is only the circle from map A, and then the
second run creates a null map B, which then of course stays null for
all further operations. Any suggestions here would be greatly
appreciated. Thanks,

Chris

Chris Carleton wrote:

###the problematic r.mapcalc operation is below###
subprocess.call([
  "r.mapcalc",
  "B = if(!isnull(A) && temp_rast_focus_ <= B,A,B"])

1. Don't use the same map for both input and output.

2. If either temp_rast_focus_ or B are null, the result will be null.

Except for specific cases, nulls propagate, i.e. if any operand is
null the result will be null. isnull() is an exception, but && isn't
(i.e. "0 && null()" is null, not 0). You might want to use the &&&
operator instead, which satisfies "0 &&& x == 0" and "x &&& 0 == 0"
even when x is null.

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

Thanks Glynn. My solution has been to do as you say with some
modifications and the result looks good. I changed the small
buffer-circle maps from 1 and nulls to binary rasters so that I can
avoid dealing with nulls. I also stopped using the same map as output
and input. It was easier to work out the conditional statement without
the nulls.

Chris

On 26 February 2011 00:59, Glynn Clements <glynn@gclements.plus.com> wrote:

Chris Carleton wrote:

###the problematic r.mapcalc operation is below###
subprocess.call([
"r.mapcalc",
"B = if(!isnull(A) && temp_rast_focus_ <= B,A,B"])

1. Don't use the same map for both input and output.

2. If either temp_rast_focus_ or B are null, the result will be null.

Except for specific cases, nulls propagate, i.e. if any operand is
null the result will be null. isnull() is an exception, but && isn't
(i.e. "0 && null()" is null, not 0). You might want to use the &&&
operator instead, which satisfies "0 &&& x == 0" and "x &&& 0 == 0"
even when x is null.

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