• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

reclass.c

Go to the documentation of this file.
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     /* Check to see if this is a reclass file */
00182     if (fgets(buf, sizeof(buf), fd) == NULL)
00183         return 0;
00184     if (strncmp(buf, "reclas", 6))
00185         return 0;
00186     /* later may add other types of reclass */
00187     type = RECLASS_TABLE;
00188 
00189     /* Read the mapset and file name of the REAL cell file */
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     /* find first non-null entry */
00256     for (min = 0; min < reclass->num; min++)
00257         if (!G_is_c_null_value(&reclass->table[min]))
00258             break;
00259     /* find last non-zero entry */
00260     for (max = reclass->num - 1; max >= 0; max--)
00261         if (!G_is_c_null_value(&reclass->table[max]))
00262             break;
00263 
00264     /*
00265      * if the resultant table is empty, write out a dummy table
00266      * else write out the table
00267      *   first entry is #min
00268      *   rest are translations for cat min+i
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      * allocate the table, expanding as each entry is read
00334      * note that G_realloc() will become G_malloc() if ptr in
00335      * NULL
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) {  /* check for int overflow */
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 }

Generated on Wed Oct 13 2010 12:09:30 for GRASS Programmer's Manual by  doxygen 1.7.1