-
-
Notifications
You must be signed in to change notification settings - Fork 327
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
r.mask.status: Check mask status through a tool and function (#2390)
Instead of using low-level test of file existence with hardcoded raster path and name, this offers a new tool to retrieve status of the raster mask. The new r.mask.status tool reports presence or absence of the 2D raster mask and provides additional details about the mask. There is one usage of this now and that's the one for a shell prompt. The prompt no longer relies on testing the file presence with the test program, but uses a GRASS tool to find out. The code goes out of its way to report both mask name (currently always MASK) and the underlying raster name if it is a reclassified (without rewriting the current C API). This is to mimic the existing C functions which are returning the underlying raster if MASK is a reclass. The tool and the new C API function return both preparing a way for using an arbitrary name for the mask while having the option to look at the underlying reclassified raster map.
- Loading branch information
1 parent
cbc3ff4
commit 1d42e58
Showing
9 changed files
with
507 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,7 @@ SUBDIRS = \ | |
r.lake \ | ||
r.li \ | ||
r.mapcalc \ | ||
r.mask.status \ | ||
r.mfilter \ | ||
r.mode \ | ||
r.neighbors \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
MODULE_TOPDIR = ../.. | ||
|
||
PGM = r.mask.status | ||
|
||
LIBES = $(MANAGELIB) $(RASTERLIB) $(GISLIB) $(PARSONLIB) | ||
DEPENDENCIES = $(MANAGEDEP) $(RASTERDEP) $(GISDEP) | ||
|
||
include $(MODULE_TOPDIR)/include/Make/Module.make | ||
|
||
default: cmd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/**************************************************************************** | ||
* | ||
* MODULE: r.mask.status | ||
* AUTHORS: Vaclav Petras | ||
* PURPOSE: Report status of raster mask | ||
* COPYRIGHT: (C) 2024 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 <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include <grass/gis.h> | ||
#include <grass/parson.h> | ||
#include <grass/raster.h> | ||
#include <grass/glocale.h> | ||
|
||
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(_("mask")); | ||
G_add_keyword(_("reclassification")); | ||
module->label = _("Reports presence or absence of a raster mask"); | ||
module->description = | ||
_("Provides information about the presence of a 2D raster mask" | ||
" as text output or return code"); | ||
|
||
params->format = G_define_option(); | ||
params->format->key = "format"; | ||
params->format->type = TYPE_STRING; | ||
params->format->required = NO; | ||
params->format->answer = "plain"; | ||
params->format->options = "plain,json,shell,yaml"; | ||
params->format->descriptions = | ||
"plain;Plain text output;" | ||
"json;JSON (JavaScript Object Notation);" | ||
"shell;Shell script style output;" | ||
"yaml;YAML (human-friendly data serialization language)"; | ||
params->format->description = _("Format for reporting"); | ||
|
||
params->like_test = G_define_flag(); | ||
params->like_test->key = 't'; | ||
params->like_test->label = | ||
_("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"); | ||
// suppress_required is not required given the default value for format. | ||
// Both no parameters and only -t work as expected. | ||
|
||
if (G_parser(argc, argv)) | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
int report_status(struct Parameters *params) | ||
{ | ||
|
||
char name[GNAME_MAX]; | ||
char mapset[GMAPSET_MAX]; | ||
char reclass_name[GNAME_MAX]; | ||
char reclass_mapset[GMAPSET_MAX]; | ||
|
||
bool is_mask_reclass; | ||
bool present = Rast_mask_status(name, mapset, &is_mask_reclass, | ||
reclass_name, reclass_mapset); | ||
|
||
// This does not have to be exclusive with the printing, but leaving this | ||
// to a different boolean flag which could do the return code and printing. | ||
// The current implementation really behaves like the test utility which | ||
// facilitates the primary usage of this which is prompt building | ||
// (and there any output would be noise). | ||
if (params->like_test->answer) { | ||
if (present) | ||
return 0; | ||
return 1; | ||
} | ||
|
||
// Mask raster | ||
char *full_mask = G_fully_qualified_name(name, mapset); | ||
// Underlying raster if applicable | ||
char *full_underlying = NULL; | ||
if (is_mask_reclass) | ||
full_underlying = G_fully_qualified_name(reclass_name, reclass_mapset); | ||
|
||
if (strcmp(params->format->answer, "json") == 0) { | ||
JSON_Value *root_value = json_value_init_object(); | ||
JSON_Object *root_object = json_object(root_value); | ||
json_object_set_boolean(root_object, "present", present); | ||
if (present) | ||
json_object_set_string(root_object, "full_name", full_mask); | ||
else | ||
json_object_set_null(root_object, "full_name"); | ||
if (is_mask_reclass) | ||
json_object_set_string(root_object, "is_reclass_of", | ||
full_underlying); | ||
else | ||
json_object_set_null(root_object, "is_reclass_of"); | ||
char *serialized_string = json_serialize_to_string_pretty(root_value); | ||
puts(serialized_string); | ||
json_free_serialized_string(serialized_string); | ||
json_value_free(root_value); | ||
} | ||
else if (strcmp(params->format->answer, "shell") == 0) { | ||
printf("present="); | ||
if (present) | ||
printf("1"); | ||
else | ||
printf("0"); | ||
printf("\nfull_name="); | ||
if (present) | ||
printf("%s", full_mask); | ||
printf("\nis_reclass_of="); | ||
if (is_mask_reclass) | ||
printf("%s", full_underlying); | ||
printf("\n"); | ||
} | ||
else if (strcmp(params->format->answer, "yaml") == 0) { | ||
printf("present: "); | ||
if (present) | ||
printf("true"); | ||
else | ||
printf("false"); | ||
printf("\nfull_name: "); | ||
if (present) | ||
printf("|-\n %s", full_mask); | ||
else | ||
printf("null"); | ||
// Null values in YAML can be an empty (no) value (rather than null), | ||
// so we could use that, but using the explicit null as a reasonable | ||
// starting point. | ||
printf("\nis_reclass_of: "); | ||
// Using block scalar with |- to avoid need for escaping. | ||
// Alternatively, we could check mapset naming limits against YAML | ||
// escaping needs for different types of strings and do the necessary | ||
// escaping here. | ||
if (is_mask_reclass) | ||
printf("|-\n %s", full_underlying); | ||
else | ||
printf("null"); | ||
printf("\n"); | ||
} | ||
else { | ||
if (present) | ||
printf(_("Mask is active")); | ||
else | ||
printf(_("Mask is not present")); | ||
if (present) { | ||
printf("\n"); | ||
printf(_("Mask name: %s"), full_mask); | ||
} | ||
if (is_mask_reclass) { | ||
printf("\n"); | ||
printf(_("Mask is a raster reclassified from: %s"), | ||
full_underlying); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
G_free(full_mask); | ||
G_free(full_underlying); | ||
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); | ||
} |
Oops, something went wrong.