[GRASS-SVN] r58396 - grass/trunk/raster/r.stats
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Dec 6 07:06:41 PST 2013
Author: martinl
Date: 2013-12-06 07:06:40 -0800 (Fri, 06 Dec 2013)
New Revision: 58396
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/r.stats.html
grass/trunk/raster/r.stats/stats.c
Log:
r.stats: implement 'sort' parameter
update manual page, add examples
use G_option_to_separator()
Modified: grass/trunk/raster/r.stats/cell_stats.c
===================================================================
--- grass/trunk/raster/r.stats/cell_stats.c 2013-12-05 18:43:49 UTC (rev 58395)
+++ grass/trunk/raster/r.stats/cell_stats.c 2013-12-06 15:06:40 UTC (rev 58396)
@@ -3,7 +3,7 @@
#include "global.h"
int cell_stats(int fd[], int with_percents, int with_counts,
- int with_areas, int with_labels, char *fmt)
+ int with_areas, int do_sort, int with_labels, char *fmt)
{
CELL **cell;
int i;
@@ -64,7 +64,7 @@
G_percent(row, nrows, 2);
- sort_cell_stats();
+ sort_cell_stats(do_sort);
print_cell_stats(fmt, with_percents, with_counts, with_areas, with_labels,
fs);
Modified: grass/trunk/raster/r.stats/global.h
===================================================================
--- grass/trunk/raster/r.stats/global.h 2013-12-05 18:43:49 UTC (rev 58395)
+++ grass/trunk/raster/r.stats/global.h 2013-12-06 15:06:40 UTC (rev 58396)
@@ -1,6 +1,10 @@
#include <grass/gis.h>
#include <grass/raster.h>
+#define SORT_DEFAULT 0
+#define SORT_ASC 1
+#define SORT_DESC 2
+
extern char *no_data_str;
extern int nfiles;
extern int nrows;
@@ -12,11 +16,11 @@
extern CELL NULL_CELL;
extern int (*get_row) ();
-extern char fs[2];
+extern char *fs;
extern struct Categories *labels;
/* cell_stats.c */
-int cell_stats(int[], int, int, int, int, char *);
+int cell_stats(int[], int, int, int, int, int, char *);
/* raw_stats.c */
int raw_stats(int[], int, int, int);
@@ -28,7 +32,6 @@
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);
+int sort_cell_stats(int);
int print_node_count(void);
int print_cell_stats(char *, int, int, int, int, char *);
Modified: grass/trunk/raster/r.stats/main.c
===================================================================
--- grass/trunk/raster/r.stats/main.c 2013-12-05 18:43:49 UTC (rev 58395)
+++ grass/trunk/raster/r.stats/main.c 2013-12-06 15:06:40 UTC (rev 58396)
@@ -7,9 +7,10 @@
* Huidae Cho <grass4u gmail.com>, Glynn Clements <glynn gclements.plus.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
+ * Sort parameter by Martin Landa <landa.martin gmail.com>
+ * PURPOSE: Calculates the area present in each of the categories of
* user-selected raster map layer(s)
- * COPYRIGHT: (C) 1999-2006 by the GRASS Development Team
+ * COPYRIGHT: (C) 1999-2006, 2013 by the GRASS Development Team
*
* This program is free software under the GNU General Public
* License (>=v2). Read the file COPYING that comes with GRASS
@@ -21,6 +22,7 @@
#include <string.h>
#include <unistd.h>
#include <grass/glocale.h>
+
#include "global.h"
char *no_data_str;
@@ -34,14 +36,13 @@
CELL NULL_CELL;
int (*get_row) ();
-char fs[2];
+char *fs;
struct Categories *labels;
int main(int argc, char *argv[])
{
int *fd;
char **names;
- char **ptr;
char *name;
/* flags */
@@ -52,6 +53,7 @@
int with_counts;
int with_areas;
int with_labels;
+ int do_sort;
/* printf format */
char fmt[20];
@@ -94,6 +96,7 @@
NOTE: when -C flag is used, and there are
explicit fp ranges in cats or when the map
is int, nsteps is ignored */
+ struct Option *sort; /* sort by cell counts */
} option;
G_gisinit(argv[0]);
@@ -102,7 +105,7 @@
G_add_keyword(_("raster"));
G_add_keyword(_("statistics"));
module->description =
- _("Generates area statistics for raster map layers.");
+ _("Generates area statistics for raster map.");
/* Define the different options */
@@ -116,6 +119,19 @@
option.fs = G_define_standard_option(G_OPT_F_SEP);
option.fs->answer = "space";
+ option.sort = G_define_option();
+ option.sort->key = "sort";
+ option.sort->type = TYPE_STRING;
+ option.sort->required = NO;
+ option.sort->multiple = NO;
+ option.sort->label = _("Sort output statistics by cell counts");
+ option.sort->description = _("Default: sorted by categories or intervals)");
+ option.sort->options = "asc,desc";
+ G_asprintf((char **)&(option.sort->descriptions),
+ "asc;%s;desc;%s",
+ _("Sort by cell counts in ascending order"),
+ _("Sort by cell counts in descending order"));
+
option.nv = G_define_option();
option.nv->key = "nv";
option.nv->type = TYPE_STRING;
@@ -131,19 +147,10 @@
option.nsteps->multiple = NO;
option.nsteps->answer = "255";
option.nsteps->description =
- _("Number of fp subranges to collect stats from");
+ _("Number of floating-point subranges to collect stats from");
/* Define the different flags */
- flag.one = G_define_flag();
- flag.one->key = '1';
- flag.one->description = _("One cell (range) per line");
-
- flag.A = G_define_flag();
- flag.A->key = 'A';
- flag.A->description = _("Print averaged values instead of intervals");
- flag.A->guisection = _("Print");
-
flag.a = G_define_flag();
flag.a->key = 'a';
flag.a->description = _("Print area totals in square meters");
@@ -151,15 +158,19 @@
flag.c = G_define_flag();
flag.c->key = 'c';
- flag.c->description = _("Print cell counts");
+ flag.c->description = _("Print cell counts (sortable)");
flag.c->guisection = _("Print");
flag.p = G_define_flag();
flag.p->key = 'p';
flag.p->description =
- _("Print APPROXIMATE percents (total percent may not be 100%)");
+ _("Print approximate (total percent may not be 100%) percents");
flag.p->guisection = _("Print");
+ flag.one = G_define_flag();
+ flag.one->key = '1';
+ flag.one->description = _("One cell (range) per line");
+
flag.l = G_define_flag();
flag.l->key = 'l';
flag.l->description = _("Print category labels");
@@ -175,9 +186,14 @@
flag.x->description = _("Print x and y (column and row)");
flag.x->guisection = _("Print");
+ flag.A = G_define_flag();
+ flag.A->key = 'A';
+ flag.A->description = _("Print averaged values instead of intervals (floating-point maps only)");
+ flag.A->guisection = _("Print");
+
flag.r = G_define_flag();
flag.r->key = 'r';
- flag.r->description = _("Print raw indexes of fp ranges (fp maps only)");
+ flag.r->description = _("Print raw indexes of floating-point ranges (floating-point maps only)");
flag.r->guisection = _("Print");
flag.n = G_define_flag();
@@ -191,11 +207,11 @@
flag.C = G_define_flag();
flag.C->key = 'C';
- flag.C->description = _("Report for cats fp ranges (fp maps only)");
+ flag.C->description = _("Report for cats floating-point ranges (floating-point maps only)");
flag.i = G_define_flag();
flag.i->key = 'i';
- flag.i->description = _("Read fp map as integer (use map's quant rules)");
+ flag.i->description = _("Read floating-point map as integer (use map's quant rules)");
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -230,6 +246,22 @@
with_areas = flag.a->answer;
with_labels = flag.l->answer;
+ /* determine sorting method */
+ do_sort = SORT_DEFAULT; /* sort by cats by default */
+ if (option.sort->answer) {
+ switch(option.sort->answer[0]) {
+ case 'a':
+ do_sort = SORT_ASC;
+ break;
+ case 'd':
+ do_sort = SORT_DESC;
+ break;
+ default:
+ G_debug(1, "Sorting by '%s' not supported", option.sort->answer);
+ break;
+ }
+ }
+
no_nulls = flag.n->answer;
no_nulls_all = flag.N->answer;
no_data_str = option.nv->answer;
@@ -241,28 +273,16 @@
raw_data = 1;
/* get field separator */
- strcpy(fs, " ");
- if (option.fs->answer) {
- if (strcmp(option.fs->answer, "space") == 0)
- *fs = ' ';
- else if (strcmp(option.fs->answer, "tab") == 0)
- *fs = '\t';
- else if (strcmp(option.fs->answer, "\\t") == 0)
- *fs = '\t';
- else
- *fs = *option.fs->answer;
- }
+ fs = G_option_to_separator(option.fs);
-
/* open all raster maps */
if (option.cell->answers[0] == NULL)
G_fatal_error(_("Raster map not found"));
names = option.cell->answers;
- ptr = option.cell->answers;
- for (; *ptr != NULL; ptr++) {
- name = *ptr;
+ for (; *names != NULL; names++) {
+ name = *names;
fd = (int *)G_realloc(fd, (nfiles + 1) * sizeof(int));
is_fp = (int *)G_realloc(is_fp, (nfiles + 1) * sizeof(int));
DMAX = (DCELL *) G_realloc(DMAX, (nfiles + 1) * sizeof(DCELL));
@@ -350,8 +370,8 @@
if (raw_data)
raw_stats(fd, with_coordinates, with_xy, with_labels);
else
- cell_stats(fd, with_percents, with_counts, with_areas, with_labels,
- fmt);
+ cell_stats(fd, with_percents, with_counts, with_areas, do_sort,
+ with_labels, fmt);
exit(EXIT_SUCCESS);
}
Modified: grass/trunk/raster/r.stats/r.stats.html
===================================================================
--- grass/trunk/raster/r.stats/r.stats.html 2013-12-05 18:43:49 UTC (rev 58395)
+++ grass/trunk/raster/r.stats/r.stats.html 2013-12-06 15:06:40 UTC (rev 58396)
@@ -1,52 +1,59 @@
<h2>DESCRIPTION</h2>
-<em>r.stats</em> calculates the area present in each of the categories of
-user-selected raster map layer(s). Area statistics are given in units of
-square meters and/or cell counts. This analysis uses the current geographic
-region and mask settings. Output can be sent to a file in the user's current
-working directory.
+<em>r.stats</em> calculates the area present in each of the categories
+or floating-point intervals of user-selected <b>input</b> raster map. Area
+statistics are given in units of square meters and/or cell
+counts. This analysis uses the current geographic region
+(<em><a href="g.region.html">g.region</a></em>) and mask settings
+(<em><a href="r.mask.html">r.mask</a></em>). The output statistics can
+be saved to a <b>output</b> file.
-If a single map layer is specified on the command line, a list of areas in
-square meters for each category in the raster map layer will be printed. (If
-the <em>-c</em> option is chosen, areas will be stated in number of cells.) If
-multiple raster map layers are specified on the command line, a
-cross-tabulation table of areas for each combination of categories in the map
-layers will be printed.
+<p>
+Area statistics is printed in square meters for each category
+when <b>-a</b> is given. Similarly if <b>-c</b> flag is chosen, areas
+will be stated also in number of cells.
-<p>For example, if one raster map layer were specified, the output would look like:
-<pre>
- 1:1350000.00
- 2:4940000.00
- 3:8870000.00
-</pre>
-If three raster map layers <em>a, b</em>, and <em>c</em>, were specified,
-the output would look like:
-<pre>
- 0:0:0:8027500.00
- 0:1:0:1152500.00
- 1:0:0:164227500.00
- 1:0:1:2177500.00
- 1:1:0:140092500.00
- 1:1:1:3355000.00
- 2:0:0:31277500.00
- 2:0:1:2490000.00
- 2:1:0:24207500.00
- 2:1:1:1752500.00
- 3:0:0:17140000.00
- 3:1:0:11270000.00
- 3:1:1:2500.00
-</pre>
-Within each grouping, the first field represents the category value of map
-layer <em>a</em>, the second represents the category values associated with
-map layer <em>b</em>, the third represents category values for map layer
-<em>c</em>, and the last field gives the area in square meters for the
-particular combination of these three map layers' categories. For example,
-above, combination 3,1,1 covered 2500 square meters. Fields are separated by
-colons.
-
<h2>NOTES</h2>
-<em>r.stats</em> works in the current geographic region with the current mask.
+If a single raster map is specified, a list of categories will be
+printed. If multiple raster maps are specified, a cross-tabulation
+table for each combination of categories in the raster maps will be
+printed.
+
+<p>
+For example, if one raster map was specified, the output would look like:
+<div class="code"><pre>
+1 1350000.00
+2 4940000.00
+3 8870000.00
+</pre></div>
+
+If three raster maps were specified, the output would look like:
+<div class="code"><pre>
+0 0 0 8027500.00
+0 1 0 1152500.00
+1 0 0 164227500.00
+1 0 1 2177500.00
+1 1 0 140092500.00
+1 1 1 3355000.00
+2 0 0 31277500.00
+2 0 1 2490000.00
+2 1 0 24207500.00
+2 1 1 1752500.00
+3 0 0 17140000.00
+3 1 0 11270000.00
+3 1 1 2500.00
+</pre></div>
+
+Within each grouping, the first field represents the category value of
+first raster map, the second represents the category values associated
+with second raster map, the third represents category values for third
+raster map, and the last field gives the area in square meters for the
+particular combination of these three raster maps' categories. For
+example, above, combination 3,1,1 covered 2500 square meters. Fields
+are separated by the <b>separator</b> option.
+
+<!-- do not use bash commands in the manual
<p>If a nicely formatted output is desired, pipe the output into a command
which can create columnar output. For example, the command:
@@ -59,26 +66,106 @@
2:1:1:1090000.00 2:4:1:700000.00 3:1:3:5280000.00
2:1:3:410000.00 2:4:3:10000.00 3:1:5:3140000.00
</pre>
+-->
-The output from <em>r.stats</em> on more than one map layer is sorted.
+The output from <em>r.stats</em> is sorted by category or category
+intervals (for floating-point raster maps).
-<p>Note that the user has only the option of printing out cell statistics in
-terms of cell counts and/or area totals. Users wishing to use different
-units than are available here should use the GRASS program
-<em><a href="r.report.html">r.report</a></em>.
+<p>
+Note that the user has only the option of printing out cell statistics
+in terms of cell counts and/or area totals. Users wishing to use
+different units than are available here should
+use <em><a href="r.report.html">r.report</a></em>.
+<h2>EXAMPLES</h2>
+
+Report area for each category in the single raster map:
+
+<div class="code"><pre>
+r.stats -a in=geology_30m nv=no-data sep=tab
+
+217 71960000.000000
+262 19760000.000000
+270 67760000.000000
+405 25120000.000000
+583 2520000.000000
+720 480000.000000
+766 840000.000000
+862 6560000.000000
+910 4360000.000000
+921 1200000.000000
+946 360000.000000
+948 80000.000000
+no-data 33375200000.000004
+</pre></div>
+
+Report sorted number of cells for each category in the single raster
+map (suppress NULL data):
+
+<div class="code"><pre>
+r.stats -cn in=geology_30m sort=desc
+
+217 1799
+270 1694
+405 628
+262 494
+862 164
+910 109
+583 63
+921 30
+766 21
+720 12
+946 9
+948 2
+</pre></div>
+
+Report area, number of cells, and percents (separated by tabs) for
+each category in the multiple raster maps (suppress NULL data):
+
+<div class="code"><pre>
+r.stats -nacp in=towns,urban sep=tab
+
+1 55 23840000.000000 596 11.89%
+2 55 13680000.000000 342 6.82%
+3 55 1360000.000000 34 0.68%
+4 55 16040000.000000 401 8.00%
+5 55 98240000.000000 2456 48.98%
+6 55 19760000.000000 494 9.85%
+</pre></div>
+
+Report sorted area for each interval of floating-point input raster
+map. Number of intervals are given by <b>nsteps</b> option.
+
+<div class="code"><pre>
+r.stats -an in=elevation nsteps=10 sort=desc sep=tab
+
+95.879221-105.954329 36440000.000000
+85.804114-95.879221 30800000.000000
+105.954329-116.029436 30080000.000000
+116.029436-126.104543 27960000.000000
+126.104543-136.17965 26440000.000000
+136.17965-146.254757 20880000.000000
+75.729007-85.804114 15880000.000000
+65.6539-75.729007 6040000.000000
+146.254757-156.329865 5720000.000000
+55.578793-65.6539 760000.000000
+</pre></div>
+
<h2>SEE ALSO</h2>
<em>
<a href="g.region.html">g.region</a>,
+<a href="r.report.html">r.report</a>,
<a href="r.coin.html">r.coin</a>,
<a href="r.describe.html">r.describe</a>,
-<a href="r.report.html">r.report</a>,
<a href="r.statistics.html">r.statistics</a>,
<a href="r.univar.html">r.univar</a>
</em>
-<h2>AUTHOR</h2>
-Michael Shapiro, U.S. Army Construction Engineering Research Laboratory
+<h2>AUTHORS</h2>
-<p><i>Last changed: $Date$</i>
+Michael Shapiro, U.S. Army Construction Engineering Research Laboratory<br>
+Sort option by Martin Landa, Czech Technical University in Prague, 2013
+
+<p>
+<i>Last changed: $Date$</i>
Modified: grass/trunk/raster/r.stats/stats.c
===================================================================
--- grass/trunk/raster/r.stats/stats.c 2013-12-05 18:43:49 UTC (rev 58395)
+++ grass/trunk/raster/r.stats/stats.c 2013-12-06 15:06:40 UTC (rev 58396)
@@ -180,7 +180,7 @@
return 0;
}
-int node_compare(const void *pp, const void *qq)
+static int node_compare(const void *pp, const void *qq)
{
struct Node *const *p = pp, *const *q = qq;
register int i, x;
@@ -191,22 +191,50 @@
for (i = nfiles; --i >= 0;)
if (x = (*a++ - *b++), x)
return x;
+
return 0;
}
-int sort_cell_stats(void)
+static int node_compare_count_asc(const void *pp, const void *qq)
{
+ struct Node *const *p = pp, *const *q = qq;
+ long a, b;
+
+ a = (*p)->count;
+ b = (*q)->count;
+
+ return (a - b);
+}
+
+static int node_compare_count_desc(const void *pp, const void *qq)
+{
+ struct Node *const *p = pp, *const *q = qq;
+ long a, b;
+
+ a = (*p)->count;
+ b = (*q)->count;
+
+ return (b - a);
+}
+
+int sort_cell_stats(int do_sort)
+{
struct Node **q, *p;
if (node_count <= 0)
return 0;
- G_free(hashtable); /* make a bit more room */
+ G_free(hashtable); /* make a bit more room */
sorted_list = (struct Node **)G_calloc(node_count, sizeof(struct Node *));
for (q = sorted_list, p = node_list; p; p = p->list)
*q++ = p;
- qsort(sorted_list, node_count, sizeof(struct Node *), node_compare);
+ if (do_sort == SORT_DEFAULT)
+ qsort(sorted_list, node_count, sizeof(struct Node *), node_compare);
+ else if (do_sort == SORT_ASC)
+ qsort(sorted_list, node_count, sizeof(struct Node *), node_compare_count_asc);
+ else if (do_sort == SORT_DESC)
+ qsort(sorted_list, node_count, sizeof(struct Node *), node_compare_count_desc);
return 0;
}
@@ -329,7 +357,7 @@
if (with_counts)
fprintf(stdout, "%s%ld", fs, (long)node->count);
if (with_percents)
- fprintf(stdout, "%s%6.2f%%", fs,
+ fprintf(stdout, "%s%.2f%%", fs,
(double)100 * node->count / total_count);
fprintf(stdout, "\n");
}
More information about the grass-commit
mailing list