[GRASS-dev] [bug #5212] (grass) default color map range does not cover full data

Glynn Clements glynn at gclements.plus.com
Tue Oct 17 10:31:37 EDT 2006


Request Tracker wrote:

> this bug's URL: http://intevation.de/rt/webrt?serial_num=5212
> -------------------------------------------------------------------------
> 
> Subject: default color map range does not cover full data
> 
> Hi,
> 
> if you create a map as follows:
> 
> g.region n=50 s=0 w=0 e=50 res=1
> r.mapcalc colorbug="x()*y()"
> d.rast colorbug
> 
> you can see the top right cell has no color.

Actually, it's white rather than "no colour" (run e.g. "d.erase green"
first).

> d.what.rast shows that the cell has data, (2450.25 = 49.5^2, center of top-
> right cell)
> 
> r.colors colorbug rule=rainbow   # doesn't fix it (thankfully)
> 
> nor do any of the other dynamic color rules (same with color=).
> 
> using a fixed-rule color map like rule=terrain is ok.
> 
> The bug is not seen with CELL maps:
> r.mapcalc colorbug="int(x()*y())"
> 
> tweak beyond-color-range check from >= to >, or add GRASS_EPSILON to range_max
> before applying rules for FP maps?

This isn't an issue with colour tables per se, but with the range
calculation. "r.info colorbug" says:

 |   Range of data:    min = 0.250000  max = 2400.750000                      |

Likewise, the colour table for the map ends at 2400.75.

If I manually edit the colour table to end at 2450.25, the top-right
cell has the correct colour.

Note that 2400.75 = 48.5 * 49.5.

Changing the region to:

$ g.region n=25 s=0 w=0 e=50 res=1
$ r.mapcalc colorbug="x()*y()"
$ r.info colorbug | fgrep Range
 |   Range of data:    min = 0.250000  max = 1188.250000                      |

Note that 1188.25 = 48.5 * 24.5.

So, it's missing the right-most cell on the top row.

Looking at G_row_update_fp_range():

	int G_row_update_fp_range (
	    void *rast,int n,
	    struct FPRange *range,
	    RASTER_MAP_TYPE data_type)
	{
	    DCELL val = 0L;
	
	    while (n-- > 0)
	    {
		switch(data_type)
		{
		   case CELL_TYPE: val = (DCELL) *((CELL *) rast); break;
		   case FCELL_TYPE: val = (DCELL) *((FCELL *) rast); break;
		   case DCELL_TYPE: val = *((DCELL *) rast); break;
	        }
	
	        if (G_is_null_value(rast, data_type))
		{
	           rast = G_incr_void_ptr(rast, G_raster_size(data_type));
		   continue;
	        }
	        if (range->first_time)
	        {
	           range->first_time = 0;
	           range->min = val;
	           range->max = val;
	           continue;
	        }
		if (val < range->min)
		    range->min = val;
		if (val > range->max)
		    range->max = val;
	
	        rast = G_incr_void_ptr(rast, G_raster_size(data_type));
	    }
	
	    return 0;
	}

For the first cell processed, it sets both min and max to the cell's
value, then executes a "continue", which skips the G_incr_void_ptr()
(but n is still decremented). Thus, it's processing the first cell
twice, and missing the last cell.

Fix:

--- range.c	23 Jul 2006 01:32:16 -0000	2.3
+++ range.c	17 Oct 2006 14:22:09 -0000
@@ -565,12 +565,14 @@
            range->first_time = 0;
            range->min = val;
            range->max = val;
-           continue;
         }
-	if (val < range->min)
-	    range->min = val;
-	if (val > range->max)
-	    range->max = val;
+	else
+	{
+	   if (val < range->min)
+	       range->min = val;
+	   if (val > range->max)
+	       range->max = val;
+	}
 
         rast = G_incr_void_ptr(rast, G_raster_size(data_type));
     }

With the above fix, r.info reports the correct range, and the white
pixel is gone.

Committed to CVS.

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




More information about the grass-dev mailing list