Skip to content

Commit 59b171d

Browse files
committed
r.mask.status: Check mask status through module
Instead of using low-level test of file existence with hardcoded raster path and name, use a module to retrieve status of the raster mask. The new module r.mask.status reports presence or absence of the 2D raster mask and provides additional details about the mask. The PR requires additional changes in the library which are not yet included.
1 parent c64326e commit 59b171d

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed

include/grass/defs/raster.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ int Rast_option_to_interp_type(const struct Option *);
401401

402402
/* mask_info.c */
403403
char *Rast_mask_info(void);
404+
bool Rast_mask_status(char *, char *, bool *);
404405
int Rast__mask_info(char *, char *);
405406

406407
/* maskfd.c */

lib/init/grass.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1998,8 +1998,8 @@ def sh_like_startup(location, location_name, grass_env_file, sh):
19981998
)
19991999
)
20002000

2001+
mask2d_test = 'r.mask.status -t'
20012002
# TODO: have a function and/or module to test this
2002-
mask2d_test = 'test -f "$MAPSET_PATH/cell/MASK"'
20032003
mask3d_test = 'test -d "$MAPSET_PATH/grid3/RASTER3D_MASK"'
20042004

20052005
specific_addition = ""

raster/r.mask.status/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
MODULE_TOPDIR = ../..
2+
3+
PGM = r.mask.status
4+
5+
LIBES = $(MANAGELIB) $(RASTERLIB) $(GISLIB)
6+
DEPENDENCIES = $(MANAGEDEP) $(RASTERDEP) $(GISDEP)
7+
8+
include $(MODULE_TOPDIR)/include/Make/Module.make
9+
10+
default: cmd

raster/r.mask.status/main.c

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/****************************************************************************
2+
*
3+
* MODULE: r.mask.status
4+
* AUTHORS: Vaclav Petras
5+
* PURPOSE: Report status of raster mask
6+
* COPYRIGHT: (C) 2022 by Vaclav Petras and the GRASS Development Team
7+
*
8+
* This program is free software under the GNU General Public
9+
* License (>=v2). Read the file COPYING that comes with GRASS
10+
* for details.
11+
*
12+
*****************************************************************************/
13+
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
#include <string.h>
17+
#include <unistd.h>
18+
#include <grass/gis.h>
19+
#include <grass/raster.h>
20+
#include <grass/glocale.h>
21+
22+
struct Parameters
23+
{
24+
struct Option *format;
25+
struct Flag *like_test;
26+
};
27+
28+
void parse_parameters(struct Parameters *params, int argc, char **argv)
29+
{
30+
struct GModule *module;
31+
32+
module = G_define_module();
33+
G_add_keyword(_("raster"));
34+
G_add_keyword(_("reclassification"));
35+
module->label = _("Reclassify raster map based on category values.");
36+
module->description =
37+
_("Creates a new raster map whose category values are based "
38+
"upon a reclassification of the categories in an existing "
39+
"raster map.");
40+
41+
params->format = G_define_option();
42+
params->format->key = "format";
43+
params->format->type = TYPE_STRING;
44+
params->format->required = NO;
45+
params->format->answer = "yaml";
46+
params->format->options = "yaml,json,bash";
47+
params->format->description = _("Format for reporting");
48+
49+
params->like_test = G_define_flag();
50+
params->like_test->key = 't';
51+
params->like_test->lable =
52+
_("Return code 0 when mask present, 1 otherwise");
53+
params->like_test->description =
54+
_("Behave like the test utility, 0 for true, 1 for false, no output");
55+
//flags.like_test->guisection = _("");
56+
// suppress_required
57+
58+
if (G_parser(argc, argv))
59+
exit(EXIT_FAILURE);
60+
}
61+
62+
char *min_json_escape(const char *str)
63+
{
64+
char *tmp1 = G_str_replace(str, "\\", "\\\\");
65+
char *tmp2 = G_str_replace(tmp1, "\"", "\\\"");
66+
67+
G_free(tmp1);
68+
return tmp2;
69+
}
70+
71+
void json_print_name_mapset(const char *name, const char *mapset)
72+
{
73+
// Being paranoid about what is in the name.
74+
char *escaped_name = min_json_escape(name);
75+
char *escaped_mapset = min_json_escape(mapset);
76+
77+
printf("\"%s@%s\"", name, mapset);
78+
G_free(escaped_name);
79+
G_free(escaped_mapset);
80+
}
81+
82+
int report_status(struct Parameters *params)
83+
{
84+
85+
char name[GNAME_MAX];
86+
char mapset[GMAPSET_MAX];
87+
88+
bool is_mask_reclass;
89+
bool present =
90+
Rast_mask_status(name, mapset, reclass_name, reclass_mapset,
91+
&is_mask_reclass);
92+
bool present = Rast_mask_present(name, mapset);
93+
94+
//printf("%s", Rast_mask_info());
95+
96+
if (params->like_test->answer) {
97+
if (present)
98+
return 0;
99+
else
100+
return 1;
101+
}
102+
else if (strcmp(params->format->answer, "json") == 0) {
103+
printf("{\"present\":");
104+
if (present)
105+
printf("true");
106+
else
107+
printf("false");
108+
printf(",\n\"full_name\":");
109+
if (present)
110+
json_print_name_mapset("MASK", G_mapset()); // Too much mask details here, move this to the library.
111+
else
112+
printf("null");
113+
printf(",\n\"is_reclass_of\": ");
114+
if (is_mask_reclass)
115+
json_print_name_mapset(name, mapset);
116+
else
117+
printf("null");
118+
printf("}\n");
119+
}
120+
else if (strcmp(params->format->answer, "bash") == 0) {
121+
printf("present=");
122+
if (present)
123+
printf("1"); // Good choice here or not?
124+
else
125+
printf("0");
126+
printf("\nfull_name=");
127+
if (present) {
128+
json_print_name_mapset(name, mapset);
129+
}
130+
printf("\n");
131+
}
132+
else {
133+
printf("present: ");
134+
if (present)
135+
printf("true");
136+
else
137+
printf("false");
138+
printf("\nfull_name: ");
139+
if (present)
140+
printf("|-\n MASK@%s", G_mapset()); // MASK or MASK@current_mapset
141+
else
142+
printf("null");
143+
printf("\nis_reclass_of: ");
144+
// Using block scalar with |- to avoid need for escaping.
145+
if (is_mask_reclass)
146+
printf("|-\n %s@%s", name, mapset);
147+
else
148+
printf("null");
149+
// true if MASK in current mapset and is reclass, false otherwise,
150+
// then also outputting mask cats is needed to inform user about the portion of the map
151+
// printf("\nmask_reclass: ");
152+
// if (is_mask_reclass)
153+
// printf("true");
154+
// else
155+
// printf("false");
156+
printf("\n");
157+
}
158+
return EXIT_SUCCESS;
159+
}
160+
161+
int main(int argc, char **argv)
162+
{
163+
struct Parameters params;
164+
165+
G_gisinit(argv[0]);
166+
parse_parameters(&params, argc, argv);
167+
return report_status(&params);
168+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<h2>DESCRIPTION</h2>
2+
3+
<em>r.mask.status</em> reports presence or absence of a raster mask.
4+
5+
<h2>NOTES</h2>
6+
7+
<h2>EXAMPLES</h2>
8+
9+
<h3>Generate JSON output</h3>
10+
11+
<div class="code"><pre>
12+
r.mask.status format=json
13+
</pre></div>
14+
15+
<h3>Use as the test utility</h3>
16+
17+
The POSIX <em>test</em> utility uses return code 0 to indicate true
18+
and 1 to indicate false, so testing existence of a file with <code>test -f</code>
19+
gives return code 0 when the file exists. <em>r.mask.status</em> can be used
20+
in the same with the the <b>-t</b> flag:
21+
22+
<div class="code"><pre>
23+
r.mask.status -t
24+
</pre></div>
25+
26+
<h2>SEE ALSO</h2>
27+
28+
<em>
29+
<a href="r.mask.html">r.mask</a>,
30+
<a href="g.region.html">g.region</a>
31+
</em>
32+
33+
<h2>AUTHORS</h2>
34+
35+
Vaclav Petras, NC State University, Center for Geospatial Analytics

0 commit comments

Comments
 (0)