diff --git a/general/g.parser/g.parser.md b/general/g.parser/g.parser.md index fab49d78b6b..aef4d7834fb 100644 --- a/general/g.parser/g.parser.md +++ b/general/g.parser/g.parser.md @@ -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"} ] } ``` diff --git a/lib/gis/parser.c b/lib/gis/parser.c index 98bb4eb8572..69bbdf5e788 100644 --- a/lib/gis/parser.c +++ b/lib/gis/parser.c @@ -517,7 +517,6 @@ int G_parser(int argc, char **argv) } /* Loop through all command line arguments */ - while (--argc) { ptr = *(++argv); @@ -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 */ @@ -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 */ diff --git a/lib/gis/parser_json.c b/lib/gis/parser_json.c index ddaa7a87842..3e9830d7a8e 100644 --- a/lib/gis/parser_json.c +++ b/lib/gis/parser_json.c @@ -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 @@ -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) { @@ -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) { @@ -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 */ diff --git a/lib/gis/parser_local_proto.h b/lib/gis/parser_local_proto.h index 43a4ab0cd29..14108faff31 100644 --- a/lib/gis/parser_local_proto.h +++ b/lib/gis/parser_local_proto.h @@ -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;