Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r.stats: add JSON output #3884

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion raster/r.stats/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ MODULE_TOPDIR = ../..

PGM = r.stats

LIBES = $(RASTERLIB) $(GISLIB)
LIBES = $(RASTERLIB) $(GISLIB) $(PARSONLIB)
DEPENDENCIES = $(RASTERDEP) $(GISDEP)

include $(MODULE_TOPDIR)/include/Make/Module.make
Expand Down
6 changes: 4 additions & 2 deletions raster/r.stats/cell_stats.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include <stdlib.h>
#include <grass/parson.h>
#include <grass/glocale.h>
#include "global.h"

int cell_stats(int fd[], int with_percents, int with_counts, int with_areas,
int do_sort, int with_labels, char *fmt)
int do_sort, int with_labels, char *fmt,
enum OutputFormat format, JSON_Array *root_array)
{
CELL **cell;
int i;
Expand Down Expand Up @@ -65,7 +67,7 @@ int cell_stats(int fd[], int with_percents, int with_counts, int with_areas,

sort_cell_stats(do_sort);
print_cell_stats(fmt, with_percents, with_counts, with_areas, with_labels,
fs);
fs, format, root_array);
for (i = 0; i < nfiles; i++) {
G_free(cell[i]);
}
Expand Down
11 changes: 8 additions & 3 deletions raster/r.stats/global.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#include <grass/gis.h>
#include <grass/raster.h>
#include <grass/parson.h>

#define SORT_DEFAULT 0
#define SORT_ASC 1
#define SORT_DESC 2

enum OutputFormat { PLAIN, JSON };

extern char *no_data_str;
extern int nfiles;
extern int nrows;
Expand All @@ -19,10 +22,11 @@ extern char *fs;
extern struct Categories *labels;

/* cell_stats.c */
int cell_stats(int[], int, int, int, int, int, char *);
int cell_stats(int[], int, int, int, int, int, char *, enum OutputFormat,
JSON_Array *);

/* raw_stats.c */
int raw_stats(int[], int, int, int);
int raw_stats(int[], int, int, int, enum OutputFormat, JSON_Array *);

/* stats.c */
int initialize_cell_stats(int);
Expand All @@ -33,4 +37,5 @@ void reset_null_vals(CELL *, int);
int update_cell_stats(CELL **, int, double);
int sort_cell_stats(int);
int print_node_count(void);
int print_cell_stats(char *, int, int, int, int, char *);
int print_cell_stats(char *, int, int, int, int, char *, enum OutputFormat,
JSON_Array *);
35 changes: 33 additions & 2 deletions raster/r.stats/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <grass/parson.h>
#include <grass/glocale.h>

#include "global.h"
Expand Down Expand Up @@ -56,6 +57,10 @@ int main(int argc, char *argv[])
int with_labels;
int do_sort;

enum OutputFormat format;
JSON_Array *root_array;
JSON_Value *root_value;

/* printf format */
char fmt[20];
int dp;
Expand Down Expand Up @@ -95,6 +100,7 @@ int main(int argc, char *argv[])
explicit fp ranges in cats or when the map
is int, nsteps is ignored */
struct Option *sort; /* sort by cell counts */
struct Option *format;
} option;

G_gisinit(argv[0]);
Expand Down Expand Up @@ -145,6 +151,9 @@ int main(int argc, char *argv[])
_("Sort by cell counts in descending order"));
option.sort->guisection = _("Formatting");

option.format = G_define_standard_option(G_OPT_F_FORMAT);
option.format->guisection = _("Print");

/* Define the different flags */

flag.a = G_define_flag();
Expand Down Expand Up @@ -233,6 +242,16 @@ int main(int argc, char *argv[])
option.nsteps->key, option.nsteps->key);
nsteps = 255;
}

if (strcmp(option.format->answer, "json") == 0) {
format = JSON;
root_value = json_value_init_array();
root_array = json_array(root_value);
}
else {
format = PLAIN;
}

cat_ranges = flag.C->answer;

averaged = flag.A->answer;
Expand Down Expand Up @@ -376,10 +395,22 @@ int main(int argc, char *argv[])
sprintf(fmt, "%%.%dlf", dp);

if (raw_data)
raw_stats(fd, with_coordinates, with_xy, with_labels);
raw_stats(fd, with_coordinates, with_xy, with_labels, format,
root_array);
else
cell_stats(fd, with_percents, with_counts, with_areas, do_sort,
with_labels, fmt);
with_labels, fmt, format, root_array);

if (format == JSON) {
char *serialized_string = NULL;
serialized_string = json_serialize_to_string_pretty(root_value);
if (serialized_string == NULL) {
G_fatal_error(_("Failed to initialize pretty JSON string."));
}
puts(serialized_string);
json_free_serialized_string(serialized_string);
json_value_free(root_value);
}

exit(EXIT_SUCCESS);
}
67 changes: 67 additions & 0 deletions raster/r.stats/r.stats.html
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,73 @@ <h3>Report sorted area intervals of floating-point raster map</h3>
55.578793-65.6539 760000.000000
</pre></div>

<h3>JSON Format</h3>

<div class="code"><pre>
g.region raster=elevation
r.stats -an input=elevation nsteps=10 sort=desc format=json
</pre></div>

<div class="code"><pre>
[
{
"categories": [
{
"range": {
"low": 116.02943572998046,
"high": 126.10454292297364
}
}
],
"area": 1188100
},
{
"categories": [
{
"range": {
"low": 105.9543285369873,
"high": 116.02943572998046
}
}
],
"area": 857300
},
{
"categories": [
{
"range": {
"low": 126.10454292297364,
"high": 136.17965011596681
}
}
],
"area": 504700
},
{
"categories": [
{
"range": {
"low": 95.879221343994146,
"high": 105.9543285369873
}
}
],
"area": 336900
},
{
"categories": [
{
"range": {
"low": 85.804114151000974,
"high": 95.879221343994146
}
}
],
"area": 66500
}
]
</pre></div>

<h3>Report raster cell counts in multiple raster maps</h3>

Report raster cell counts of landuse and geological categories within
Expand Down
Loading
Loading