00001 #include <string.h>
00002 #include <grass/gis.h>
00003 #include <grass/glocale.h>
00004
00005 static char *NULL_STRING = "null";
00006 static int reclass_type(FILE *, char **, char **);
00007 static FILE *fopen_cellhd_old(const char *, const char *);
00008 static FILE *fopen_cellhd_new(const char *);
00009 static int get_reclass_table(FILE *, struct Reclass *);
00010
00011
00030 int G_is_reclass(const char *name, const char *mapset, char *rname,
00031 char *rmapset)
00032 {
00033 FILE *fd;
00034 int type;
00035
00036 fd = fopen_cellhd_old(name, mapset);
00037 if (fd == NULL)
00038 return -1;
00039
00040 type = reclass_type(fd, &rname, &rmapset);
00041 fclose(fd);
00042 if (type < 0)
00043 return -1;
00044 else
00045 return type != 0;
00046 }
00047
00048
00066 int G_is_reclassed_to(const char *name, const char *mapset, int *nrmaps,
00067 char ***rmaps)
00068 {
00069 FILE *fd;
00070 int i, j, k, l;
00071 char buf2[256], buf3[256];
00072
00073 fd = G_fopen_old_misc("cell_misc", "reclassed_to", name, mapset);
00074
00075 if (fd == NULL) {
00076 return -1;
00077 }
00078
00079 if (rmaps)
00080 *rmaps = NULL;
00081 for (i = 0; !feof(fd) && fgets(buf2, 255, fd);) {
00082 l = strlen(buf2);
00083 for (j = 0, k = 0; j < l; j++) {
00084 if (buf2[j] == '#' ||
00085 ((buf2[j] == ' ' || buf2[j] == '\t' || buf2[j] == '\n') && k))
00086 break;
00087 else if (buf2[j] != ' ' && buf2[j] != '\t')
00088 buf3[k++] = buf2[j];
00089 }
00090
00091 if (k) {
00092 buf3[k] = 0;
00093 i++;
00094 if (rmaps) {
00095 *rmaps = (char **)G_realloc(*rmaps, i * sizeof(char *));
00096 (*rmaps)[i - 1] = (char *)G_malloc(k + 1);
00097 strncpy((*rmaps)[i - 1], buf3, k);
00098 (*rmaps)[i - 1][k] = 0;
00099 }
00100 }
00101 }
00102
00103 if (nrmaps)
00104 *nrmaps = i;
00105
00106 if (i && rmaps) {
00107 i++;
00108 *rmaps = (char **)G_realloc(*rmaps, i * sizeof(char *));
00109 (*rmaps)[i - 1] = NULL;
00110 }
00111
00112 return i;
00113 }
00114
00115 int G_get_reclass(const char *name, const char *mapset,
00116 struct Reclass *reclass)
00117 {
00118 FILE *fd;
00119 int stat;
00120
00121 fd = fopen_cellhd_old(name, mapset);
00122 if (fd == NULL)
00123 return -1;
00124 reclass->name = NULL;
00125 reclass->mapset = NULL;
00126 reclass->type = reclass_type(fd, &reclass->name, &reclass->mapset);
00127 if (reclass->type <= 0) {
00128 fclose(fd);
00129 return reclass->type;
00130 }
00131
00132 switch (reclass->type) {
00133 case RECLASS_TABLE:
00134 stat = get_reclass_table(fd, reclass);
00135 break;
00136 default:
00137 stat = -1;
00138 }
00139
00140 fclose(fd);
00141 if (stat < 0) {
00142 if (stat == -2)
00143 G_warning(_("Too many reclass categories for [%s in %s]"),
00144 name, mapset);
00145 else
00146 G_warning(_("Illegal reclass format in header file for [%s in %s]"),
00147 name, mapset);
00148 stat = -1;
00149 }
00150 return stat;
00151 }
00152
00153 int G_free_reclass(struct Reclass *reclass)
00154 {
00155 switch (reclass->type) {
00156 case RECLASS_TABLE:
00157 if (reclass->num > 0)
00158 G_free(reclass->table);
00159 reclass->num = 0;
00160 if (reclass->name)
00161 G_free(reclass->name);
00162 if (reclass->mapset)
00163 G_free(reclass->mapset);
00164 reclass->name = NULL;
00165 reclass->mapset = NULL;
00166 break;
00167 default:
00168 break;
00169 }
00170
00171 return 0;
00172 }
00173
00174 static int reclass_type(FILE * fd, char **rname, char **rmapset)
00175 {
00176 char buf[128];
00177 char label[128], arg[128];
00178 int i;
00179 int type;
00180
00181
00182 if (fgets(buf, sizeof(buf), fd) == NULL)
00183 return 0;
00184 if (strncmp(buf, "reclas", 6))
00185 return 0;
00186
00187 type = RECLASS_TABLE;
00188
00189
00190 if (*rname)
00191 **rname = '\0';
00192 if (*rmapset)
00193 **rmapset = '\0';
00194 for (i = 0; i < 2; i++) {
00195 if (fgets(buf, sizeof buf, fd) == NULL)
00196 return -1;
00197 if (sscanf(buf, "%[^:]:%s", label, arg) != 2)
00198 return -1;
00199 if (strncmp(label, "maps", 4) == 0) {
00200 if (*rmapset)
00201 strcpy(*rmapset, arg);
00202 else
00203 *rmapset = G_store(arg);
00204 }
00205 else if (strncmp(label, "name", 4) == 0) {
00206 if (*rname)
00207 strcpy(*rname, arg);
00208 else
00209 *rname = G_store(arg);
00210 }
00211 else
00212 return -1;
00213 }
00214 if (**rmapset && **rname)
00215 return type;
00216 else
00217 return -1;
00218 }
00219
00220 static FILE *fopen_cellhd_old(const char *name, const char *mapset)
00221 {
00222 return G_fopen_old("cellhd", name, mapset);
00223 }
00224
00225 int G_put_reclass(const char *name, const struct Reclass *reclass)
00226 {
00227 FILE *fd;
00228 long min, max;
00229 int i;
00230 char buf1[GPATH_MAX], buf2[GNAME_MAX], buf3[GNAME_MAX], *p;
00231
00232 switch (reclass->type) {
00233 case RECLASS_TABLE:
00234 if (reclass->min > reclass->max || reclass->num <= 0) {
00235 G_fatal_error(_("Illegal reclass request"));
00236 return -1;
00237 }
00238 break;
00239 default:
00240 G_fatal_error(_("Illegal reclass type"));
00241 return -1;
00242 }
00243
00244 fd = fopen_cellhd_new(name);
00245 if (fd == NULL) {
00246 G_warning(_("Unable to create header file for [%s in %s]"),
00247 name, G_mapset());
00248 return -1;
00249 }
00250
00251 fprintf(fd, "reclass\n");
00252 fprintf(fd, "name: %s\n", reclass->name);
00253 fprintf(fd, "mapset: %s\n", reclass->mapset);
00254
00255
00256 for (min = 0; min < reclass->num; min++)
00257 if (!G_is_c_null_value(&reclass->table[min]))
00258 break;
00259
00260 for (max = reclass->num - 1; max >= 0; max--)
00261 if (!G_is_c_null_value(&reclass->table[max]))
00262 break;
00263
00264
00265
00266
00267
00268
00269
00270 if (min > max)
00271 fprintf(fd, "0\n");
00272 else {
00273 fprintf(fd, "#%ld\n", (long)reclass->min + min);
00274 while (min <= max) {
00275 if (G_is_c_null_value(&reclass->table[min]))
00276 fprintf(fd, "%s\n", NULL_STRING);
00277 else
00278 fprintf(fd, "%ld\n", (long)reclass->table[min]);
00279 min++;
00280 }
00281 }
00282 fclose(fd);
00283
00284 strcpy(buf2, reclass->name);
00285 if ((p = strchr(buf2, '@')))
00286 *p = 0;
00287
00288 G__file_name_misc(buf1, "cell_misc", "reclassed_to", reclass->name,
00289 reclass->mapset);
00290
00291 fd = fopen(buf1, "a+");
00292 if (fd == NULL) {
00293 #if 0
00294 G_warning(_("Unable to create dependency file in [%s in %s]"),
00295 buf2, reclass->mapset);
00296 #endif
00297 return 1;
00298 }
00299
00300 fseek(fd, 0L, SEEK_SET);
00301
00302 sprintf(buf2, "%s@%s\n", name, G_mapset());
00303 for (i = 0; !feof(fd) && fgets(buf3, 255, fd);) {
00304 if (!(strcmp(buf2, buf3))) {
00305 i = 1;
00306 break;
00307 }
00308 }
00309
00310 if (!i) {
00311 fprintf(fd, "%s@%s\n", name, G_mapset());
00312 }
00313
00314 fclose(fd);
00315
00316 return 1;
00317 }
00318
00319 static FILE *fopen_cellhd_new(const char *name)
00320 {
00321 return G_fopen_new("cellhd", name);
00322 }
00323
00324 static int get_reclass_table(FILE * fd, struct Reclass *reclass)
00325 {
00326 char buf[128];
00327 int n;
00328 int first, null_str_size;
00329 CELL cat;
00330 long len;
00331
00332
00333
00334
00335
00336
00337 reclass->min = 0;
00338 reclass->table = NULL;
00339 null_str_size = strlen(NULL_STRING);
00340 n = 0;
00341 first = 1;
00342 while (fgets(buf, sizeof buf, fd)) {
00343 if (first) {
00344 first = 0;
00345 if (sscanf(buf, "#%d", &cat) == 1) {
00346 reclass->min = cat;
00347 continue;
00348 }
00349 }
00350 if (strncmp(buf, NULL_STRING, null_str_size) == 0)
00351 G_set_c_null_value(&cat, 1);
00352 else {
00353 if (sscanf(buf, "%d", &cat) != 1)
00354 return -1;
00355 }
00356 n++;
00357 len = (long)n *sizeof(CELL);
00358
00359 if (len != (int)len) {
00360 if (reclass->table != NULL)
00361 G_free(reclass->table);
00362 return -2;
00363 }
00364 reclass->table = (CELL *) G_realloc((char *)reclass->table, (int)len);
00365 reclass->table[n - 1] = cat;
00366 }
00367 reclass->max = reclass->min + n - 1;
00368 reclass->num = n;
00369 return 1;
00370 }