3
#include <grass/glocale.h>
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 *);
13
* \brief reclass file?
15
* This function determines if the raster map
16
* <b>name</b> in <b>mapset</b> is a reclass file.
17
* If it is, then the name and mapset of the referenced
18
* raster map are copied into the <b>r_name</b> and <b>r_mapset</b>
20
* Returns 1 if <b>name</b> is a reclass file, 0 if it is not, and -1 if
21
* there was a problem reading the raster header for <b>name.</b>
30
int G_is_reclass(const char *name, const char *mapset, char *rname,
36
fd = fopen_cellhd_old(name, mapset);
40
type = reclass_type(fd, &rname, &rmapset);
50
* \brief get child reclass maps list
52
* This function generates a
53
* child reclass maps list from the cell_misc/reclassed_to file which stores
54
* this list. The cell_misc/reclassed_to file is written by
56
* G_is_reclassed_to() is used by g.rename, g.remove and r.reclass to
57
* prevent accidentally deleting the parent map of a reclassed raster map.
66
int G_is_reclassed_to(const char *name, const char *mapset, int *nrmaps,
71
char buf2[256], buf3[256];
73
fd = G_fopen_old_misc("cell_misc", "reclassed_to", name, mapset);
81
for (i = 0; !feof(fd) && fgets(buf2, 255, fd);) {
83
for (j = 0, k = 0; j < l; j++) {
85
((buf2[j] == ' ' || buf2[j] == '\t' || buf2[j] == '\n') && k))
87
else if (buf2[j] != ' ' && buf2[j] != '\t')
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;
108
*rmaps = (char **)G_realloc(*rmaps, i * sizeof(char *));
109
(*rmaps)[i - 1] = NULL;
117
int G_get_reclass(const char *name, const char *mapset,
118
struct Reclass *reclass)
123
fd = fopen_cellhd_old(name, mapset);
126
reclass->name = NULL;
127
reclass->mapset = NULL;
128
reclass->type = reclass_type(fd, &reclass->name, &reclass->mapset);
129
if (reclass->type <= 0) {
131
return reclass->type;
134
switch (reclass->type) {
136
stat = get_reclass_table(fd, reclass);
145
G_warning(_("Too many reclass categories for [%s in %s]"),
148
G_warning(_("Illegal reclass format in header file for [%s in %s]"),
155
int G_free_reclass(struct Reclass *reclass)
157
switch (reclass->type) {
159
if (reclass->num > 0)
160
G_free(reclass->table);
163
G_free(reclass->name);
165
G_free(reclass->mapset);
166
reclass->name = NULL;
167
reclass->mapset = NULL;
176
static int reclass_type(FILE * fd, char **rname, char **rmapset)
179
char label[128], arg[128];
183
/* Check to see if this is a reclass file */
184
if (fgets(buf, sizeof(buf), fd) == NULL)
186
if (strncmp(buf, "reclas", 6))
188
/* later may add other types of reclass */
189
type = RECLASS_TABLE;
191
/* Read the mapset and file name of the REAL cell file */
196
for (i = 0; i < 2; i++) {
197
if (fgets(buf, sizeof buf, fd) == NULL)
199
if (sscanf(buf, "%[^:]:%s", label, arg) != 2)
201
if (strncmp(label, "maps", 4) == 0) {
203
strcpy(*rmapset, arg);
205
*rmapset = G_store(arg);
207
else if (strncmp(label, "name", 4) == 0) {
211
*rname = G_store(arg);
216
if (**rmapset && **rname)
222
static FILE *fopen_cellhd_old(const char *name, const char *mapset)
224
return G_fopen_old("cellhd", name, mapset);
227
int G_put_reclass(const char *name, const struct Reclass *reclass)
232
char buf1[GPATH_MAX], buf2[GNAME_MAX], *p;
235
switch (reclass->type) {
237
if (reclass->min > reclass->max || reclass->num <= 0) {
238
G_fatal_error(_("Illegal reclass request"));
243
G_fatal_error(_("Illegal reclass type"));
247
fd = fopen_cellhd_new(name);
249
G_warning(_("Unable to create header file for [%s in %s]"),
254
fprintf(fd, "reclass\n");
255
fprintf(fd, "name: %s\n", reclass->name);
256
fprintf(fd, "mapset: %s\n", reclass->mapset);
258
/* find first non-null entry */
259
for (min = 0; min < reclass->num; min++)
260
if (!G_is_c_null_value(&reclass->table[min]))
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]))
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
276
fprintf(fd, "#%ld\n", (long)reclass->min + min);
278
if (G_is_c_null_value(&reclass->table[min]))
279
fprintf(fd, "%s\n", NULL_STRING);
281
fprintf(fd, "%ld\n", (long)reclass->table[min]);
287
strcpy(buf2, reclass->name);
288
if ((p = strchr(buf2, '@')))
291
G__file_name_misc(buf1, "cell_misc", "reclassed_to", reclass->name,
294
fd = fopen(buf1, "a+");
297
G_warning(_("Unable to create dependency file in [%s in %s]"),
298
buf2, reclass->mapset);
303
fseek(fd, 0L, SEEK_SET);
305
xname = G_fully_qualified_name(name, G_mapset());
308
char buf[GNAME_MAX + GMAPSET_MAX];
309
if (!G_getl2(buf, sizeof(buf), fd))
311
if (strcmp(xname, buf) == 0) {
318
fprintf(fd, "%s\n", xname);
326
static FILE *fopen_cellhd_new(const char *name)
328
return G_fopen_new("cellhd", name);
331
static int get_reclass_table(FILE * fd, struct Reclass *reclass)
335
int first, null_str_size;
340
* allocate the table, expanding as each entry is read
341
* note that G_realloc() will become G_malloc() if ptr in
345
reclass->table = NULL;
346
null_str_size = strlen(NULL_STRING);
349
while (fgets(buf, sizeof buf, fd)) {
352
if (sscanf(buf, "#%d", &cat) == 1) {
357
if (strncmp(buf, NULL_STRING, null_str_size) == 0)
358
G_set_c_null_value(&cat, 1);
360
if (sscanf(buf, "%d", &cat) != 1)
364
len = (long)n *sizeof(CELL);
366
if (len != (int)len) { /* check for int overflow */
367
if (reclass->table != NULL)
368
G_free(reclass->table);
371
reclass->table = (CELL *) G_realloc((char *)reclass->table, (int)len);
372
reclass->table[n - 1] = cat;
374
reclass->max = reclass->min + n - 1;