GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
reclass.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <grass/gis.h>
3 #include <grass/glocale.h>
4 
5 static char *NULL_STRING = "null";
6 static int reclass_type(FILE *, char **, char **);
7 static FILE *fopen_cellhd_old(const char *, const char *);
8 static FILE *fopen_cellhd_new(const char *);
9 static int get_reclass_table(FILE *, struct Reclass *);
10 
11 
30 int G_is_reclass(const char *name, const char *mapset, char *rname,
31  char *rmapset)
32 {
33  FILE *fd;
34  int type;
35 
36  fd = fopen_cellhd_old(name, mapset);
37  if (fd == NULL)
38  return -1;
39 
40  type = reclass_type(fd, &rname, &rmapset);
41  fclose(fd);
42  if (type < 0)
43  return -1;
44  else
45  return type != 0;
46 }
47 
48 
66 int G_is_reclassed_to(const char *name, const char *mapset, int *nrmaps,
67  char ***rmaps)
68 {
69  FILE *fd;
70  int i, j, k, l;
71  char buf2[256], buf3[256];
72 
73  fd = G_fopen_old_misc("cell_misc", "reclassed_to", name, mapset);
74 
75  if (fd == NULL) {
76  return -1;
77  }
78 
79  if (rmaps)
80  *rmaps = NULL;
81  for (i = 0; !feof(fd) && fgets(buf2, 255, fd);) {
82  l = strlen(buf2);
83  for (j = 0, k = 0; j < l; j++) {
84  if (buf2[j] == '#' ||
85  ((buf2[j] == ' ' || buf2[j] == '\t' || buf2[j] == '\n') && k))
86  break;
87  else if (buf2[j] != ' ' && buf2[j] != '\t')
88  buf3[k++] = buf2[j];
89  }
90 
91  if (k) {
92  buf3[k] = 0;
93  i++;
94  if (rmaps) {
95  *rmaps = (char **)G_realloc(*rmaps, i * sizeof(char *));
96  (*rmaps)[i - 1] = (char *)G_malloc(k + 1);
97  strncpy((*rmaps)[i - 1], buf3, k);
98  (*rmaps)[i - 1][k] = 0;
99  }
100  }
101  }
102 
103  if (nrmaps)
104  *nrmaps = i;
105 
106  if (i && rmaps) {
107  i++;
108  *rmaps = (char **)G_realloc(*rmaps, i * sizeof(char *));
109  (*rmaps)[i - 1] = NULL;
110  }
111 
112  fclose(fd);
113 
114  return i;
115 }
116 
117 int G_get_reclass(const char *name, const char *mapset,
118  struct Reclass *reclass)
119 {
120  FILE *fd;
121  int stat;
122 
123  fd = fopen_cellhd_old(name, mapset);
124  if (fd == NULL)
125  return -1;
126  reclass->name = NULL;
127  reclass->mapset = NULL;
128  reclass->type = reclass_type(fd, &reclass->name, &reclass->mapset);
129  if (reclass->type <= 0) {
130  fclose(fd);
131  return reclass->type;
132  }
133 
134  switch (reclass->type) {
135  case RECLASS_TABLE:
136  stat = get_reclass_table(fd, reclass);
137  break;
138  default:
139  stat = -1;
140  }
141 
142  fclose(fd);
143  if (stat < 0) {
144  if (stat == -2)
145  G_warning(_("Too many reclass categories for [%s in %s]"),
146  name, mapset);
147  else
148  G_warning(_("Illegal reclass format in header file for [%s in %s]"),
149  name, mapset);
150  stat = -1;
151  }
152  return stat;
153 }
154 
155 int G_free_reclass(struct Reclass *reclass)
156 {
157  switch (reclass->type) {
158  case RECLASS_TABLE:
159  if (reclass->num > 0)
160  G_free(reclass->table);
161  reclass->num = 0;
162  if (reclass->name)
163  G_free(reclass->name);
164  if (reclass->mapset)
165  G_free(reclass->mapset);
166  reclass->name = NULL;
167  reclass->mapset = NULL;
168  break;
169  default:
170  break;
171  }
172 
173  return 0;
174 }
175 
176 static int reclass_type(FILE * fd, char **rname, char **rmapset)
177 {
178  char buf[128];
179  char label[128], arg[128];
180  int i;
181  int type;
182 
183  /* Check to see if this is a reclass file */
184  if (fgets(buf, sizeof(buf), fd) == NULL)
185  return 0;
186  if (strncmp(buf, "reclas", 6))
187  return 0;
188  /* later may add other types of reclass */
189  type = RECLASS_TABLE;
190 
191  /* Read the mapset and file name of the REAL cell file */
192  if (*rname)
193  **rname = '\0';
194  if (*rmapset)
195  **rmapset = '\0';
196  for (i = 0; i < 2; i++) {
197  if (fgets(buf, sizeof buf, fd) == NULL)
198  return -1;
199  if (sscanf(buf, "%[^:]:%s", label, arg) != 2)
200  return -1;
201  if (strncmp(label, "maps", 4) == 0) {
202  if (*rmapset)
203  strcpy(*rmapset, arg);
204  else
205  *rmapset = G_store(arg);
206  }
207  else if (strncmp(label, "name", 4) == 0) {
208  if (*rname)
209  strcpy(*rname, arg);
210  else
211  *rname = G_store(arg);
212  }
213  else
214  return -1;
215  }
216  if (**rmapset && **rname)
217  return type;
218  else
219  return -1;
220 }
221 
222 static FILE *fopen_cellhd_old(const char *name, const char *mapset)
223 {
224  return G_fopen_old("cellhd", name, mapset);
225 }
226 
227 int G_put_reclass(const char *name, const struct Reclass *reclass)
228 {
229  FILE *fd;
230  long min, max;
231  int found;
232  char buf1[GPATH_MAX], buf2[GNAME_MAX], *p;
233  char *xname;
234 
235  switch (reclass->type) {
236  case RECLASS_TABLE:
237  if (reclass->min > reclass->max || reclass->num <= 0) {
238  G_fatal_error(_("Illegal reclass request"));
239  return -1;
240  }
241  break;
242  default:
243  G_fatal_error(_("Illegal reclass type"));
244  return -1;
245  }
246 
247  fd = fopen_cellhd_new(name);
248  if (fd == NULL) {
249  G_warning(_("Unable to create header file for [%s in %s]"),
250  name, G_mapset());
251  return -1;
252  }
253 
254  fprintf(fd, "reclass\n");
255  fprintf(fd, "name: %s\n", reclass->name);
256  fprintf(fd, "mapset: %s\n", reclass->mapset);
257 
258  /* find first non-null entry */
259  for (min = 0; min < reclass->num; min++)
260  if (!G_is_c_null_value(&reclass->table[min]))
261  break;
262  /* find last non-zero entry */
263  for (max = reclass->num - 1; max >= 0; max--)
264  if (!G_is_c_null_value(&reclass->table[max]))
265  break;
266 
267  /*
268  * if the resultant table is empty, write out a dummy table
269  * else write out the table
270  * first entry is #min
271  * rest are translations for cat min+i
272  */
273  if (min > max)
274  fprintf(fd, "0\n");
275  else {
276  fprintf(fd, "#%ld\n", (long)reclass->min + min);
277  while (min <= max) {
278  if (G_is_c_null_value(&reclass->table[min]))
279  fprintf(fd, "%s\n", NULL_STRING);
280  else
281  fprintf(fd, "%ld\n", (long)reclass->table[min]);
282  min++;
283  }
284  }
285  fclose(fd);
286 
287  strcpy(buf2, reclass->name);
288  if ((p = strchr(buf2, '@')))
289  *p = 0;
290 
291  G__file_name_misc(buf1, "cell_misc", "reclassed_to", reclass->name,
292  reclass->mapset);
293 
294  fd = fopen(buf1, "a+");
295  if (fd == NULL) {
296 #if 0
297  G_warning(_("Unable to create dependency file in [%s in %s]"),
298  buf2, reclass->mapset);
299 #endif
300  return 1;
301  }
302 
303  fseek(fd, 0L, SEEK_SET);
304 
305  xname = G_fully_qualified_name(name, G_mapset());
306  found = 0;
307  for (;;) {
308  char buf[GNAME_MAX + GMAPSET_MAX];
309  if (!G_getl2(buf, sizeof(buf), fd))
310  break;
311  if (strcmp(xname, buf) == 0) {
312  found = 1;
313  break;
314  }
315  }
316 
317  if (!found)
318  fprintf(fd, "%s\n", xname);
319 
320  G_free(xname);
321  fclose(fd);
322 
323  return 1;
324 }
325 
326 static FILE *fopen_cellhd_new(const char *name)
327 {
328  return G_fopen_new("cellhd", name);
329 }
330 
331 static int get_reclass_table(FILE * fd, struct Reclass *reclass)
332 {
333  char buf[128];
334  int n;
335  int first, null_str_size;
336  CELL cat;
337  long len;
338 
339  /*
340  * allocate the table, expanding as each entry is read
341  * note that G_realloc() will become G_malloc() if ptr in
342  * NULL
343  */
344  reclass->min = 0;
345  reclass->table = NULL;
346  null_str_size = strlen(NULL_STRING);
347  n = 0;
348  first = 1;
349  while (fgets(buf, sizeof buf, fd)) {
350  if (first) {
351  first = 0;
352  if (sscanf(buf, "#%d", &cat) == 1) {
353  reclass->min = cat;
354  continue;
355  }
356  }
357  if (strncmp(buf, NULL_STRING, null_str_size) == 0)
358  G_set_c_null_value(&cat, 1);
359  else {
360  if (sscanf(buf, "%d", &cat) != 1)
361  return -1;
362  }
363  n++;
364  len = (long)n *sizeof(CELL);
365 
366  if (len != (int)len) { /* check for int overflow */
367  if (reclass->table != NULL)
368  G_free(reclass->table);
369  return -2;
370  }
371  reclass->table = (CELL *) G_realloc((char *)reclass->table, (int)len);
372  reclass->table[n - 1] = cat;
373  }
374  reclass->max = reclass->min + n - 1;
375  reclass->num = n;
376  return 1;
377 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
int G_is_c_null_value(const CELL *cellVal)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int...
Definition: null_val.c:244
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
int l
Definition: dataquad.c:292
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
char * G__file_name_misc(char *path, const char *dir, const char *element, const char *name, const char *mapset)
Definition: file_name.c:70
tuple label
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _(&quot;width&quot;)), pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
Definition: tools.py:1366
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
#define min(x, y)
Definition: draw2.c:68
FILE * G_fopen_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:200
#define max(x, y)
Definition: draw2.c:69
int G_getl2(char *buf, int n, FILE *fd)
gets a line of text from a file of any pedigree
Definition: getl.c:52
int G_is_reclassed_to(const char *name, const char *mapset, int *nrmaps, char ***rmaps)
get child reclass maps list
Definition: reclass.c:66
int stat
Definition: g3dcolor.c:369
int
Definition: g3dcolor.c:48
int G_put_reclass(const char *name, const struct Reclass *reclass)
Definition: reclass.c:227
int first
Definition: form/open.c:25
int G_is_reclass(const char *name, const char *mapset, char *rname, char *rmapset)
reclass file?
Definition: reclass.c:30
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:197
return NULL
Definition: dbfopen.c:1394
int G_free_reclass(struct Reclass *reclass)
Definition: reclass.c:155
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
fclose(fd)
char buf2[200]
Definition: g3dcats.c:89
char * G_fully_qualified_name(const char *name, const char *mapset)
fully qualified file name
Definition: nme_in_mps.c:118
void G_set_c_null_value(CELL *cellVals, int numVals)
Definition: null_val.c:142
int G_get_reclass(const char *name, const char *mapset, struct Reclass *reclass)
Definition: reclass.c:117
CELL cat
Definition: g3dcats.c:90
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:226
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
char xname[512]
Definition: g3dcats.c:89
int n
Definition: dataquad.c:291