Skip to content

Commit

Permalink
r.mask.status: Check mask status through module
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wenzeslaus committed May 20, 2022
1 parent c64326e commit 59b171d
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/grass/defs/raster.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion lib/init/grass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ""
Expand Down
10 changes: 10 additions & 0 deletions raster/r.mask.status/Makefile
Original file line number Diff line number Diff line change
@@ -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
168 changes: 168 additions & 0 deletions raster/r.mask.status/main.c
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <grass/gis.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(_("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(&params, argc, argv);
return report_status(&params);
}
35 changes: 35 additions & 0 deletions raster/r.mask.status/r.mask.status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<h2>DESCRIPTION</h2>

<em>r.mask.status</em> reports presence or absence of a raster mask.

<h2>NOTES</h2>

<h2>EXAMPLES</h2>

<h3>Generate JSON output</h3>

<div class="code"><pre>
r.mask.status format=json
</pre></div>

<h3>Use as the test utility</h3>

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

<div class="code"><pre>
r.mask.status -t
</pre></div>

<h2>SEE ALSO</h2>

<em>
<a href="r.mask.html">r.mask</a>,
<a href="g.region.html">g.region</a>
</em>

<h2>AUTHORS</h2>

Vaclav Petras, NC State University, Center for Geospatial Analytics

0 comments on commit 59b171d

Please sign in to comment.