GRASS 8 Programmer's Manual  8.5.0dev(2025)-9d806b45d8
mask_info.c
Go to the documentation of this file.
1 /**
2  * \file lib/raster/mask_info.c
3  *
4  * \brief Raster Library - Get mask information
5  *
6  * (C) 1999-2024 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  * \author CERL
13  * \author Vaclav Petras, NC State University, Center for Geospatial Analytics
14  */
15 
16 #include <string.h>
17 #include <stdbool.h>
18 #include <stdlib.h>
19 
20 #if defined(_OPENMP)
21 #include <omp.h>
22 #endif
23 
24 #include <grass/gis.h>
25 #include <grass/raster.h>
26 #include <grass/glocale.h>
27 
28 /**
29  * @brief Get a printable text with information about raster mask
30  *
31  * Determines if 2D raster mask is present and returns textual information about
32  * the mask suitable for end-user display. The resulting text is translated.
33  * Caller is responsible for freeing the memory of the returned string.
34  *
35  * @return New string with textual information
36  *
37  * @see Rast_mask_status()
38  */
39 char *Rast_mask_info(void)
40 {
41  char text[GNAME_MAX + GMAPSET_MAX + 16];
42  char name[GNAME_MAX];
43  char mapset[GMAPSET_MAX];
44 
45  switch (Rast__mask_info(name, mapset)) {
46  case 1:
47  snprintf(text, sizeof(text), _("<%s> in mapset <%s>"), name, mapset);
48  break;
49  case -1:
50  strcpy(text, _("none"));
51  break;
52  default:
53  strcpy(text, _("not known"));
54  break;
55  }
56 
57  return G_store(text);
58 }
59 
60 /**
61  * @brief Retrieves the name of the raster mask to use.
62  *
63  * The returned raster map name is fully qualified, i.e., in the form
64  * "name@mapset". The mask name is returned whether the mask is present or not.
65  *
66  * This function checks if an environment variable "GRASS_MASK" is set.
67  * If it is set, the value of the environment variable is returned
68  * as the mask name. If it is not set, the function will default to the
69  * mask name "MASK@<mapset>", where <mapset> is the current mapset.
70  *
71  * The memory for the returned mask name is dynamically allocated using
72  * G_store(). It is the caller's responsibility to free the memory with
73  * G_free() when it is no longer needed.
74  *
75  * @returns A dynamically allocated string containing the mask name.
76  */
77 char *Rast_mask_name(void)
78 {
79  // First, see if the environment variable is defined.
80  const char *env_variable = getenv("GRASS_MASK");
81  if (env_variable != NULL && strcmp(env_variable, "") != 0) {
82  // Variable exists and is not empty.
83  // While the function does not document that, the provided mapset
84  // is a fallback, so we don't have to parse the name to find out
85  // ourselves what to do.
86  return G_fully_qualified_name(env_variable, G_mapset());
87  }
88 
89  // Mask name defaults to "MASK@<current mapset>".
90  return G_fully_qualified_name("MASK", G_mapset());
91 }
92 
93 /**
94  * @brief Get name of a mask if it is present
95  *
96  * Unlike, Rast__mask_info() this always returns name of the mask
97  * if it is present regardless of the mask being a reclass or not.
98  *
99  * @param[out] name Name of the raster map used as mask
100  * @param[out] mapset Name of the map's mapset
101  *
102  * @return true if mask is present, false otherwise
103  */
104 static bool Rast__get_present_mask(char *name, char *mapset)
105 {
106  char rname[GNAME_MAX], rmapset[GMAPSET_MAX];
107  char *full_name = Rast_mask_name();
108  if (!G_find_raster2(full_name, ""))
109  return false;
110  G_unqualified_name(full_name, "", rname, rmapset);
111  strncpy(name, rname, GMAPSET_MAX);
112  strncpy(mapset, rmapset, GMAPSET_MAX);
113  G_free(full_name);
114  return true;
115 }
116 
117 /**
118  * @brief Get raster mask status information
119  *
120  * _is_mask_reclass_ is a pointer to a bool variable which
121  * will be set to true if mask raster is a reclass and false otherwise.
122  *
123  * If you are not interested in the underlying reclassified raster map,
124  * pass NULL pointers for the three reclass parameters:
125  *
126  * ```
127  * Rast_mask_status(name, mapset, NULL, NULL, NULL);
128  * ```
129  *
130  * @param[out] name Name of the raster map used as mask
131  * @param[out] mapset Name of the mapset the raster is in
132  * @param[out] is_mask_reclass Will be set to true if mask raster is a reclass
133  * @param[out] reclass_name Name of the underlying reclassified raster map
134  * @param[out] reclass_mapset Name of the mapset the reclassified raster is in
135  *
136  * @return true if mask is present, false otherwise
137  */
138 bool Rast_mask_status(char *name, char *mapset, bool *is_mask_reclass,
139  char reclass_name[GNAME_MAX],
140  char reclass_mapset[GMAPSET_MAX])
141 {
142  bool present = Rast__get_present_mask(name, mapset);
143 
144  if (is_mask_reclass && reclass_name && reclass_mapset) {
145  if (present) {
146  *is_mask_reclass =
147  Rast_is_reclass(name, mapset, reclass_name, reclass_mapset) > 0;
148  }
149  else {
150  *is_mask_reclass = false;
151  }
152  }
153  return present;
154 }
155 
156 /**
157  * @brief Get information about the current mask
158  *
159  * Determines the status of the automatic masking and the name of the 2D
160  * raster which forms the mask. Typically, mask is raster called MASK in the
161  * current mapset, but when used with r.mask, it is usually a reclassed
162  * raster, and so when a mask raster is present and it is a reclass raster,
163  * the name and mapset of the underlying reclassed raster are returned.
164  *
165  * The name and mapset is written to the parameter which need to be defined
166  * with a sufficient size, least as `char name[GNAME_MAX], mapset[GMAPSET_MAX]`.
167  *
168  * When the masking is not active, -1 is returned and name and mapset are
169  * undefined. When the masking is active, 1 is returned and name and mapset
170  * will hold the name and mapset of the underlying raster.
171  *
172  * @param[out] name Name of the raster map used as mask
173  * @param[out] mapset Name of the map's mapset
174  *
175  * @return 1 if mask is present, -1 otherwise
176  *
177  * @see Rast_mask_status(), Rast_mask_name()
178  */
179 int Rast__mask_info(char *name, char *mapset)
180 {
181  char rname[GNAME_MAX], rmapset[GMAPSET_MAX];
182  bool present = Rast__get_present_mask(name, mapset);
183  if (!present)
184  return -1;
185 
186  if (Rast_is_reclass(name, mapset, rname, rmapset) > 0) {
187  strcpy(name, rname);
188  strcpy(mapset, rmapset);
189  }
190  return 1;
191 }
192 
193 /**
194  * @brief Check presence of 2D raster mask
195  *
196  * @return true if mask is present, false otherwise
197  */
199 {
200  char *name = Rast_mask_name();
201  bool present = G_find_raster2(name, "") != NULL;
202  return present;
203 }
204 
205 /**
206  * \brief Disable OpenMP if raster mask is present
207  *
208  * This helper function can be removed when raster reading is made
209  * thread safe.
210  *
211  * \param nprocs number of threads to use
212  * \return number of threads in use
213  */
215 {
216 
217 #if defined(_OPENMP)
218  if (nprocs > 1 && Rast_mask_is_present()) {
219  omp_set_num_threads(1);
220  G_verbose_message(_("Single thread processing enforced due to "
221  "raster mask being present."));
222  nprocs = 1;
223  }
224 #else
225  nprocs = 1;
226 #endif
227 
228  return nprocs;
229 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:147
int G_unqualified_name(const char *, const char *, char *, char *)
Returns unqualified map name (without @ mapset)
Definition: nme_in_mps.c:134
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don't touch)
Definition: find_rast.c:76
void void G_verbose_message(const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition: nme_in_mps.c:101
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
int Rast_is_reclass(const char *, const char *, char[256], char[256])
Check if raster map is reclassified.
Definition: reclass.c:44
#define GMAPSET_MAX
Definition: gis.h:197
#define GNAME_MAX
Definition: gis.h:196
#define _(str)
Definition: glocale.h:10
int Rast_disable_omp_on_mask(int nprocs)
Disable OpenMP if raster mask is present.
Definition: mask_info.c:214
bool Rast_mask_status(char *name, char *mapset, bool *is_mask_reclass, char reclass_name[256], char reclass_mapset[256])
Get raster mask status information.
Definition: mask_info.c:138
char * Rast_mask_name(void)
Retrieves the name of the raster mask to use.
Definition: mask_info.c:77
char * Rast_mask_info(void)
Get a printable text with information about raster mask.
Definition: mask_info.c:39
int Rast__mask_info(char *name, char *mapset)
Get information about the current mask.
Definition: mask_info.c:179
bool Rast_mask_is_present(void)
Check presence of 2D raster mask.
Definition: mask_info.c:198
const char * name
Definition: named_colr.c:6
#define strcpy
Definition: parson.c:66