Skip to content
75 changes: 62 additions & 13 deletions general/g.parser/g.parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,28 +255,77 @@ v.in.db --interface-description
## JSON

The flag **--json** added to a GRASS command with parameters mandatorily
to be specified generates a module interface description in JSON.
Example:
to be specified generates a module interface description in JSON. The JSON
output can be used as building blocks in actinia processing chains.

actinia specific parametrization is supported for both import and export.

Import of input data is denoted with a "@" as delimiter followed by a
valid URL.

Request for actinia to export a raster, vector or other file-based data
can be invoked with a "+" behind the file-name followed by an
actinia-format name. Currently recognized formats are:

- COG
- GTiff
- GPKG
- SQLite
- GML
- GeoJSON
- ESRI_Shapefile
- CSV
- TXT
- PDF
- PostgreSQL

Many GRASS tools produce textual output to *stdout* and actinia allows
to export that output. However, the **--json** flag does not yet
allow to specify export of *stdout*, so export instructions need to be
added manually to the resulting JSON data. In an actinia processing
chain, exporting *stdout* may be requested as follows:

```json
{
...
'stdout': {'id': 'stats', 'format': 'kv', 'delimiter': '='},
}
```

Please consult the
[actinia documentation](https://actinia-org.github.io/actinia-core/tutorial_process_chain/)
for possible export formats and settings of *stdout* results.

Here is a full example for usage of the **--json** flag:

```sh
v.in.db driver=sqlite database=mysqlite.db table=pointsfile x=x y=y z=z key=idcol out=dtmpoints --json
r.slope.aspect --o --q -e \
elevation="elevation@https://storage.googleapis.com/graas-geodata/elev_ned_30m.tif" \
slope="slope+GTiff" aspect="aspect+GTiff" --json
```

```json
{
"module": "v.in.db",
"id": "v.in.db_1804289383",
"module": "r.slope.aspect",
"overwrite": true,
"quiet": true,
"id": "r.slope.aspect_1804289383",
"flags":"e",
"inputs":[
{"param": "table", "value": "pointsfile"},
{"param": "driver", "value": "sqlite"},
{"param": "database", "value": "mysqlite.db"},
{"param": "x", "value": "x"},
{"param": "y", "value": "y"},
{"param": "z", "value": "z"},
{"param": "key", "value": "idcol"}
{"import_descr": {"source":"https://storage.googleapis.com/graas-geodata/elev_ned_30m.tif", "type":"raster"},
"param": "elevation", "value": "elevation"},
{"param": "format", "value": "degrees"},
{"param": "precision", "value": "FCELL"},
{"param": "zscale", "value": "1.0"},
{"param": "min_slope", "value": "0.0"},
{"param": "nprocs", "value": "0"},
{"param": "memory", "value": "300"}
],
"outputs":[
{"param": "output", "value": "dtmpoints"}
{"export": {"format":"GTiff", "type":"raster"},
"param": "slope", "value": "slope"},
{"export": {"format":"GTiff", "type":"raster"},
"param": "aspect", "value": "aspect"}
]
}
```
Expand Down
54 changes: 35 additions & 19 deletions lib/gis/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,6 @@ int G_parser(int argc, char **argv)
}

/* Loop through all command line arguments */

while (--argc) {
ptr = *(++argv);

Expand All @@ -540,51 +539,63 @@ int G_parser(int argc, char **argv)

/* Verbose option */
else if (strcmp(ptr, "--v") == 0 || strcmp(ptr, "--verbose") == 0) {
char buff[32];

/* print everything: max verbosity level */
st->module_info.verbose = G_verbose_max();
snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d",
G_verbose_max());
putenv(G_store(buff));
G_set_verbose(G_verbose_max());
if (st->quiet == 1) {
G_warning(_("Use either --quiet or --verbose flag, not "
"both. Assuming --verbose."));
}
if (st->superquiet) {

/* Reactivate warnings */
G_suppress_warnings(FALSE);
G_warning(_("Use either --qq or --verbose flag, not "
"both. Assuming --verbose."));
}
st->superquiet = false; /* for passing to gui init */
st->quiet = -1;
}

/* Quiet option */
else if (strcmp(ptr, "--q") == 0 || strcmp(ptr, "--quiet") == 0) {
char buff[32];

/* print nothing, but errors and warnings */
st->module_info.verbose = G_verbose_min();
snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d",
G_verbose_min());
putenv(G_store(buff));
G_set_verbose(G_verbose_min());
if (st->quiet == -1) {
G_warning(_("Use either --quiet or --verbose flag, not "
"both. Assuming --quiet."));
}
st->quiet = 1; /* for passing to gui init */
if (st->superquiet) {

/* Reactivate warnings */
G_suppress_warnings(FALSE);
G_warning(_("Use either --qq or --quiet flag, not "
"both. Assuming --quiet."));
}
st->superquiet = false; /* for passing to gui init */
st->quiet = 1;
}

/* Super quiet option */
else if (strcmp(ptr, "--qq") == 0) {
char buff[32];

/* print nothing, but errors */
st->module_info.verbose = G_verbose_min();
snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d",
G_verbose_min());
putenv(G_store(buff));
G_suppress_warnings(TRUE);
if (st->quiet == -1) {
if (st->module_info.verbose == G_verbose_max()) {
G_warning(_("Use either --qq or --verbose flag, not both. "
"Assuming --qq."));
}
st->quiet = 1; /* for passing to gui init */
if (st->quiet == 1) {
G_warning(_("Use either --qq or --quiet flag, not "
"both. Assuming --qq."));
}
/* print nothing, but errors */
st->module_info.verbose = G_verbose_min();
G_set_verbose(G_verbose_min());
G_suppress_warnings(TRUE);
st->superquiet = true; /* for passing to gui init */
st->quiet = -1;
}

/* Force gui to come up */
Expand Down Expand Up @@ -616,6 +627,11 @@ int G_parser(int argc, char **argv)
append_error(err);
}
}

/* Set verbosity in shell env */
char buff[32];
snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d", G_verbose());
putenv(G_store(buff));
}

/* Split options where multiple answers are OK */
Expand Down
23 changes: 19 additions & 4 deletions lib/gis/parser_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ char *check_mapset_in_layer_name(char *, int);
static char *str_json_escape(const char *str);
static char *str_replace_free_buffer(char *buffer, const char old_char,
const char *new_str);

/*!
\brief This function generates actinia JSON process chain building blocks
from the command line arguments that can be used in the actinia processing
Expand Down Expand Up @@ -229,7 +228,6 @@ char *G__json(void)
/* Count input and output options */
if (st->n_opts) {
struct Option *opt;

for (opt = &st->first_option; opt; opt = opt->next_opt) {
if (opt->answer) {
if (opt->gisprompt) {
Expand All @@ -254,6 +252,23 @@ char *G__json(void)

fprintf(fp, "{\n");
fprintf(fp, " \"module\": \"%s\",\n", G_program_name());
if (st->overwrite || getenv("GRASS_OVERWRITE")) {
fprintf(fp, " \"overwrite\": true,\n");
}

if (st->module_info.verbose == G_verbose_max() ||
G_verbose() == G_verbose_max()) {
fprintf(fp, " \"verbose\": true,\n");
}

if (st->quiet == 1 || (G_verbose() == G_verbose_min() && !st->superquiet)) {
fprintf(fp, " \"quiet\": true,\n");
}

if (st->superquiet || G_verbose() == -1) {
fprintf(fp, " \"superquiet\": true,\n");
}

fprintf(fp, " \"id\": \"%s_%i\"", G_program_name(), random_int);

if (st->n_flags && num_flags > 0) {
Expand Down Expand Up @@ -336,10 +351,10 @@ char *G__json(void)
}
}
}
fprintf(fp, " ]\n");
fprintf(fp, " ]");
}

fprintf(fp, "}\n");
fprintf(fp, "\n}\n");
fclose(fp);

/* Print the file content to stdout */
Expand Down
1 change: 1 addition & 0 deletions lib/gis/parser_local_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct state {
int n_keys_alloc;
int overwrite;
int quiet;
bool superquiet;
int has_required;
int suppress_required;
int suppress_overwrite;
Expand Down
Loading