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( 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
00191 if (fgets(buf,sizeof(buf),fd) == NULL)
00192 return 0;
00193 if (strncmp(buf,"reclas",6))
00194 return 0;
00195
00196 type = RECLASS_TABLE;
00197
00198
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
00258 for (min = 0; min < reclass->num; min++)
00259 if (!G_is_c_null_value(&reclass->table[min]))
00260 break;
00261
00262 for (max = reclass->num-1; max >= 0; max--)
00263 if (!G_is_c_null_value(&reclass->table[max]))
00264 break;
00265
00266
00267
00268
00269
00270
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
00342
00343
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)
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 }