diff --git a/include/grass/defs/raster.h b/include/grass/defs/raster.h index bedf926bbee..899528e13bc 100644 --- a/include/grass/defs/raster.h +++ b/include/grass/defs/raster.h @@ -401,6 +401,7 @@ int Rast_option_to_interp_type(const struct Option *); /* mask_info.c */ char *Rast_mask_info(void); +bool Rast_mask_status(char *, char *, bool *); int Rast__mask_info(char *, char *); /* maskfd.c */ diff --git a/lib/init/grass.py b/lib/init/grass.py index e4308786615..50a23f67167 100755 --- a/lib/init/grass.py +++ b/lib/init/grass.py @@ -1998,8 +1998,8 @@ def sh_like_startup(location, location_name, grass_env_file, sh): ) ) + mask2d_test = 'r.mask.status -t' # TODO: have a function and/or module to test this - mask2d_test = 'test -f "$MAPSET_PATH/cell/MASK"' mask3d_test = 'test -d "$MAPSET_PATH/grid3/RASTER3D_MASK"' specific_addition = "" diff --git a/raster/r.mask.status/Makefile b/raster/r.mask.status/Makefile new file mode 100644 index 00000000000..0be917f1040 --- /dev/null +++ b/raster/r.mask.status/Makefile @@ -0,0 +1,10 @@ +MODULE_TOPDIR = ../.. + +PGM = r.mask.status + +LIBES = $(MANAGELIB) $(RASTERLIB) $(GISLIB) +DEPENDENCIES = $(MANAGEDEP) $(RASTERDEP) $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +default: cmd diff --git a/raster/r.mask.status/main.c b/raster/r.mask.status/main.c new file mode 100644 index 00000000000..3f3d736bdd6 --- /dev/null +++ b/raster/r.mask.status/main.c @@ -0,0 +1,168 @@ +/**************************************************************************** + * + * MODULE: r.mask.status + * AUTHORS: Vaclav Petras + * PURPOSE: Report status of raster mask + * COPYRIGHT: (C) 2022 by Vaclav Petras and the GRASS Development Team + * + * This program is free software under the GNU General Public + * License (>=v2). Read the file COPYING that comes with GRASS + * for details. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +struct Parameters +{ + struct Option *format; + struct Flag *like_test; +}; + +void parse_parameters(struct Parameters *params, int argc, char **argv) +{ + struct GModule *module; + + module = G_define_module(); + G_add_keyword(_("raster")); + G_add_keyword(_("reclassification")); + module->label = _("Reclassify raster map based on category values."); + module->description = + _("Creates a new raster map whose category values are based " + "upon a reclassification of the categories in an existing " + "raster map."); + + params->format = G_define_option(); + params->format->key = "format"; + params->format->type = TYPE_STRING; + params->format->required = NO; + params->format->answer = "yaml"; + params->format->options = "yaml,json,bash"; + params->format->description = _("Format for reporting"); + + params->like_test = G_define_flag(); + params->like_test->key = 't'; + params->like_test->lable = + _("Return code 0 when mask present, 1 otherwise"); + params->like_test->description = + _("Behave like the test utility, 0 for true, 1 for false, no output"); + //flags.like_test->guisection = _(""); + // suppress_required + + if (G_parser(argc, argv)) + exit(EXIT_FAILURE); +} + +char *min_json_escape(const char *str) +{ + char *tmp1 = G_str_replace(str, "\\", "\\\\"); + char *tmp2 = G_str_replace(tmp1, "\"", "\\\""); + + G_free(tmp1); + return tmp2; +} + +void json_print_name_mapset(const char *name, const char *mapset) +{ + // Being paranoid about what is in the name. + char *escaped_name = min_json_escape(name); + char *escaped_mapset = min_json_escape(mapset); + + printf("\"%s@%s\"", name, mapset); + G_free(escaped_name); + G_free(escaped_mapset); +} + +int report_status(struct Parameters *params) +{ + + char name[GNAME_MAX]; + char mapset[GMAPSET_MAX]; + + bool is_mask_reclass; + bool present = + Rast_mask_status(name, mapset, reclass_name, reclass_mapset, + &is_mask_reclass); + bool present = Rast_mask_present(name, mapset); + + //printf("%s", Rast_mask_info()); + + if (params->like_test->answer) { + if (present) + return 0; + else + return 1; + } + else if (strcmp(params->format->answer, "json") == 0) { + printf("{\"present\":"); + if (present) + printf("true"); + else + printf("false"); + printf(",\n\"full_name\":"); + if (present) + json_print_name_mapset("MASK", G_mapset()); // Too much mask details here, move this to the library. + else + printf("null"); + printf(",\n\"is_reclass_of\": "); + if (is_mask_reclass) + json_print_name_mapset(name, mapset); + else + printf("null"); + printf("}\n"); + } + else if (strcmp(params->format->answer, "bash") == 0) { + printf("present="); + if (present) + printf("1"); // Good choice here or not? + else + printf("0"); + printf("\nfull_name="); + if (present) { + json_print_name_mapset(name, mapset); + } + printf("\n"); + } + else { + printf("present: "); + if (present) + printf("true"); + else + printf("false"); + printf("\nfull_name: "); + if (present) + printf("|-\n MASK@%s", G_mapset()); // MASK or MASK@current_mapset + else + printf("null"); + printf("\nis_reclass_of: "); + // Using block scalar with |- to avoid need for escaping. + if (is_mask_reclass) + printf("|-\n %s@%s", name, mapset); + else + printf("null"); + // true if MASK in current mapset and is reclass, false otherwise, + // then also outputting mask cats is needed to inform user about the portion of the map + // printf("\nmask_reclass: "); + // if (is_mask_reclass) + // printf("true"); + // else + // printf("false"); + printf("\n"); + } + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) +{ + struct Parameters params; + + G_gisinit(argv[0]); + parse_parameters(¶ms, argc, argv); + return report_status(¶ms); +} diff --git a/raster/r.mask.status/r.mask.status.html b/raster/r.mask.status/r.mask.status.html new file mode 100644 index 00000000000..f8cb8255c5e --- /dev/null +++ b/raster/r.mask.status/r.mask.status.html @@ -0,0 +1,35 @@ +

DESCRIPTION

+ +r.mask.status reports presence or absence of a raster mask. + +

NOTES

+ +

EXAMPLES

+ +

Generate JSON output

+ +
+r.mask.status format=json
+
+ +

Use as the test utility

+ +The POSIX test utility uses return code 0 to indicate true +and 1 to indicate false, so testing existence of a file with test -f +gives return code 0 when the file exists. r.mask.status can be used +in the same with the the -t flag: + +
+r.mask.status -t
+
+ +

SEE ALSO

+ + +r.mask, +g.region + + +

AUTHORS

+ +Vaclav Petras, NC State University, Center for Geospatial Analytics