[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