[GRASS-user] Problems creating new map with r.mapcalc

Glynn Clements glynn at gclements.plus.com
Sun Sep 21 22:17:57 EDT 2008


Lars Forseth wrote:

> The NULL's were biting me ;-)
> 
> Did this; R_VannB at larsf = if(isnull(R_VannA at larsf), 0, 1)
> 
> And lo and behold this did work; R_test14 = if(R_VannB at larsf, 7, 
> R_paramNew at larsf)
> 
> And produced the wanted map!
> 
> But could someone enlighten me as to what exactly is the reason why this 
> worked?

Nearly all operators and functions return null if any of their
arguments are null.

The main exceptions are:

"isnull(x)" returns 0 if x is non-null and 1 if x is null.

"if(1,a,b)" returns a even if b is null.

"if(0,a,b)" returns b even if a is null.

"eval(a,b,c,...,x)" returns x even if any or all of a,b,c,... are null.

"0 &&& x" and "x &&& 0" return 0 even if x is null.

"1 ||| x" and "x ||| 1" return 1 even if x is null.

"graph(x,x1,y1,...,xn,yn)" will return null if x is null or any of the
x[i] are null, or if a "relevant" y[i] is null, but not where a y[i]
which isn't used in the calculation is null.

[The &&& and ||| operators are a relatively recent addition; the older
&& and || operators follow the usual behaviour for nulls, i.e. they
return null if either operand is null.]

The behaviour is quite intuitive if you view null as representing an
unknown quantity. This explains why both "x == null()" and "x != null()"
are always null, regardless of whether x is null or non-null.

null() is an unknown value, so it's unknown whether or not it's equal
to any particular (known) value. If x is also null, then you have two
unknown values, and it's unknown whether or not the two are equal.

In many respects, the behaviour is similar to that of NaN in
floating-point arithmetic.

With the exception of the cases listed above, r.mapcalc doesn't try to
detect "special" cases where the result can be deduced even if one of
the operands is null. E.g. if x is null, "x * 0" is null rather than
zero, "x == x" is null rather than 1, "x != x" is null rather than 0,
etc.

If you have a "boolean" map where the values are either null or 1, you
normally want to convert null to 0 before performing any other
processing. You can either replace the nulls in an existing map using
e.g. "r.null null=0", or adjust the tests within r.mapcalc, e.g.:

	R_test14 = if(not(isnull(R_VannB at larsf)), 7, R_paramNew at larsf)

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


More information about the grass-user mailing list