reclass.c

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

Generated on Wed Aug 23 17:49:23 2006 for GRASS by  doxygen 1.4.7