[GRASS-SVN] r37700 - grass/trunk/raster/r.stats

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jun 2 03:19:32 EDT 2009


Author: hamish
Date: 2009-06-02 03:19:31 -0400 (Tue, 02 Jun 2009)
New Revision: 37700

Modified:
   grass/trunk/raster/r.stats/cell_stats.c
   grass/trunk/raster/r.stats/global.h
   grass/trunk/raster/r.stats/main.c
   grass/trunk/raster/r.stats/stats.c
Log:
bugfix for #475: top bin for FP maps always held just the single max cell (merge from devbr6)

Modified: grass/trunk/raster/r.stats/cell_stats.c
===================================================================
--- grass/trunk/raster/r.stats/cell_stats.c	2009-06-02 07:15:29 UTC (rev 37699)
+++ grass/trunk/raster/r.stats/cell_stats.c	2009-06-02 07:19:31 UTC (rev 37700)
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <grass/glocale.h>
 #include "global.h"
 
 int cell_stats(int fd[], int with_percents, int with_counts,
@@ -47,11 +48,17 @@
 
 	for (i = 0; i < nfiles; i++) {
 	    if (G_get_c_raster_row(fd[i], cell[i], row) < 0)
-		exit(1);
+		G_fatal_error(_("Unable to read raster map <map %d of %d> row %d"),
+				i+1, nfiles, row);
+
+	    /* include max FP value in nsteps'th bin */
+	    if(is_fp[i])
+		fix_max_fp_val(cell[i], ncols);
+
+	    /* we can't compute hash on null values, so we change all
+	       nulls to max+1, set NULL_CELL to max+1, and later compare
+	       with NULL_CELL to chack for nulls */
 	    reset_null_vals(cell[i], ncols);
-	    /* we can't compute hash on null values, so we change all
-	       nulls to max+1, set NULL_CELL to max+1, and later compare with 
-	       NULL_CELL  to chack for nulls */
 	}
 
 	update_cell_stats(cell, ncols, unit_area);

Modified: grass/trunk/raster/r.stats/global.h
===================================================================
--- grass/trunk/raster/r.stats/global.h	2009-06-02 07:15:29 UTC (rev 37699)
+++ grass/trunk/raster/r.stats/global.h	2009-06-02 07:19:31 UTC (rev 37700)
@@ -24,7 +24,8 @@
 int initialize_cell_stats(int);
 int allocate_values(void);
 struct Node *NewNode(double);
-int reset_null_vals(CELL *, int);
+void fix_max_fp_val(CELL *, int);
+void reset_null_vals(CELL *, int);
 int update_cell_stats(CELL **, int, double);
 int node_compare(const void *, const void *);
 int sort_cell_stats(void);

Modified: grass/trunk/raster/r.stats/main.c
===================================================================
--- grass/trunk/raster/r.stats/main.c	2009-06-02 07:15:29 UTC (rev 37699)
+++ grass/trunk/raster/r.stats/main.c	2009-06-02 07:19:31 UTC (rev 37700)
@@ -5,7 +5,7 @@
  * AUTHOR(S):    Michael Shapiro, CERL (original contributor)
  *               Markus Neteler <neteler itc.it>, Brad Douglas <rez touchofmadness.com>,
  *               Huidae Cho <grass4u gmail.com>, Glynn Clements <glynn gclements.plus.com>,
- *               Hamish Bowman <hamish_nospam yahoo.com>,
+ *               Hamish Bowman <hamish_b yahoo.com>,
  *               Jachym Cepicky <jachym les-ejk.cz>, Jan-Oliver Wagner <jan intevation.de>
  * PURPOSE:      calculates the area present in each of the categories of
  *               user-selected raster map layer(s)
@@ -20,9 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-
 #include <grass/glocale.h>
-
 #include "global.h"
 
 char *no_data_str;
@@ -311,10 +309,17 @@
 				  name);
 		G_get_fp_range_min_max(&fp_range, &DMIN[nfiles],
 				       &DMAX[nfiles]);
-		G_quant_add_rule(&q, DMIN[nfiles], DMAX[nfiles], 1, nsteps);
+		G_debug(3, "file %2d: dmin=%f  dmax=%f", nfiles, DMIN[nfiles], 
+			DMAX[nfiles]);
+
+		G_quant_add_rule(&q, DMIN[nfiles], DMAX[nfiles], 1, nsteps+1);
+
 		/* set the quant rules for reading the map */
 		G_set_quant_rules(fd[nfiles], &q);
 		G_quant_get_limits(&q, &dmin, &dmax, &min, &max);
+		G_debug(2, "overall: dmin=%f  dmax=%f,  qmin=%d  qmax=%d",
+			dmin, dmax, min, max);
+
 		G_quant_free(&q);
 	    }
 	    else {		/* cats ranges */
@@ -336,6 +341,7 @@
 	}
 	else if (NULL_CELL < max + 1)
 	    NULL_CELL = max + 1;
+
 	nfiles++;
     }
 

Modified: grass/trunk/raster/r.stats/stats.c
===================================================================
--- grass/trunk/raster/r.stats/stats.c	2009-06-02 07:15:29 UTC (rev 37699)
+++ grass/trunk/raster/r.stats/stats.c	2009-06-02 07:19:31 UTC (rev 37700)
@@ -87,16 +87,38 @@
     return node;
 }
 
-int reset_null_vals(CELL * cell, int ncols)
+
+/* Essentially, G_quant_add_rule() treats the ranges as half-open,
+ *  i.e. the values range from low (inclusive) to high (exclusive).
+ *  While half-open ranges are a common concept (e.g. floor() behaves
+ *  the same way), the range of a GRASS raster is closed, i.e. both the
+ *  low and high values are inclusive.
+ *  Therefore the quantized max FP cell gets put in the nsteps+1'th bin
+ *  and we need to manually place it back in the previous bin. */
+void fix_max_fp_val(CELL *cell, int ncols)
 {
     while (ncols-- > 0) {
+	if (cell[ncols] > nsteps)
+	    cell[ncols] = nsteps;
+	    /* { G_debug(5, ". resetting %d to %d\n", cell[ncols], nsteps); } */
+    }
+    return;
+}
+
+
+/* we can't compute hash on null values, so we change all
+ *  nulls to max+1, set NULL_CELL to max+1, and later compare
+ *  with NULL_CELL to chack for nulls */
+void reset_null_vals(CELL *cell, int ncols)
+{
+    while (ncols-- > 0) {
 	if (G_is_c_null_value(&cell[ncols]))
 	    cell[ncols] = NULL_CELL;
     }
-
-    return 0;
+    return;
 }
 
+
 int update_cell_stats(CELL ** cell, int ncols, double area)
 {
     register int i;
@@ -108,13 +130,16 @@
 	/* copy this cell to an array, compute hash */
 
 	hash = values[0] = cell[0][ncols];
+
 	for (i = 1; i < nfiles; i++)
 	    hash = hash * HASHMOD + (values[i] = cell[i][ncols]);
+
 	if (hash < 0)
 	    hash = -hash;
+
 	hash %= HASHSIZE;
+
 	/* look it up and update/insert */
-
 	if ((q = hashtable[hash]) == NULL) {
 	    hashtable[hash] = NewNode(area);
 	}
@@ -132,6 +157,7 @@
 			break;
 		    }
 		}
+
 		if (i == nfiles) {	/* match */
 		    q->count++;
 		    q->area += area;
@@ -192,8 +218,7 @@
     return 0;
 }
 
-int
-print_cell_stats(char *fmt, int with_percents, int with_counts,
+int print_cell_stats(char *fmt, int with_percents, int with_counts,
 		 int with_areas, int with_labels, char *fs)
 {
     int i, n, nulls_found;



More information about the grass-commit mailing list