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

quant_io.c

Go to the documentation of this file.
00001 
00002 /**********************************************************************
00003  *
00004  *  int
00005  *  G__quant_import (name, mapset, quant)
00006  *
00007  *      char *name;
00008  *      char *mapset;
00009  *      struct Quant *quant;
00010  * 
00011  *  reads quantization rules for "name" in "mapset" and stores them
00012  *  in the quantization structure "quant". If the map is in another
00013  *  mapset, first checks for quant2 table for this map in current
00014  *  mapset.
00015  *  
00016  *  returns: -2 if raster map is of type integer.
00017  *           -1 if (! G__name_is_fully_qualified ()).
00018  *            0 if quantization file does not exist, or the file is empty, 
00019  *            1 if non-empty quantization file exists.
00020  *                 read.
00021  *           
00022  *  note: in the case of negative return value, the result of using the 
00023  *        quantization structure is not defined.
00024  *        in case of return value 0, calls to G_quant_perform_d () 
00025  *        and G_quant_perform_f () return NO_DATA (see description of 
00026  *        G_quant_perform_d () for more details). in case of
00027  *        return values 2 and 3, the explicit rule for quant is set:
00028  *        floating range is mapped to integer range.
00029  *
00030  *  note: use G_quant_init () to allocate and initialize the quantization
00031  *        staructure quant before the first usage of G_quant_import ().
00032  *
00033  *  note: this function uses G_quant_free () to clear all previously
00034  *        stored rules in quant.
00035  * 
00036  **********************************************************************
00037  *
00038  *  int
00039  *  G__quant_export (name, mapset, quant)
00040  *
00041  *     char *name, *mapset;
00042  *     struct Quant *quant;
00043  *
00044  *  writes the quantization rules stored in "quant" for "name" . if the
00045  *  mapset is the same as the current mapset, the quant file is created
00046  *  in cell_misc/name directory, otherwise it is created in quant2/mapset
00047  *  directory, much like writing colors for map in another mapset.
00048  *  The rules are written in decreasing order
00049  *  of priority (i.e. rules added earlier are written later).
00050  *
00051  *  returns: -1 if (! G__name_is_fully_qualified) or file could not be
00052  *                 opened.
00053  *            1 otherwise.
00054  *
00055  *  note: if no rules are defined an empty file is created. 
00056  *
00057  **********************************************************************/
00058 
00059 /*--------------------------------------------------------------------------*/
00060 
00061 #include <grass/gis.h>
00062 #include <grass/glocale.h>
00063 #include <string.h>
00064 
00065 /*--------------------------------------------------------------------------*/
00066 
00067 #define QUANT_FILE_NAME "f_quant"
00068 
00069 /*--------------------------------------------------------------------------*/
00070 
00071 static int quant_parse_file(FILE *, struct Quant *);
00072 
00073 #if 0
00074 static int
00075 /* redundant: integer range doesn't exist now: it is defined by
00076    the quant rules */
00077 quant_load_range(struct Quant *quant, const char *name, const char *mapset)
00078 {
00079     struct FPRange fprange;
00080     struct Range range;
00081     char buf[300];
00082     DCELL dMin, dMax;
00083     CELL min, max;
00084 
00085     if (G_read_fp_range(name, mapset, &fprange) <= 0)
00086         return 0;
00087     G_get_fp_range_min_max(&fprange, &dMin, &dMax);
00088     if (G_is_d_null_value(&dMin) || G_is_d_null_value(&dMax)) {
00089         sprintf(buf, _("The floating data range for %s@%s is empty"), name,
00090                 mapset);
00091         G_warning(buf);
00092         return -3;
00093     }
00094 
00095     if (G_read_range(name, mapset, &range) < 0)
00096         return 0;
00097     G_get_range_min_max(&range, &min, &max);
00098     if (G_is_c_null_value(&min) && G_is_c_null_value(&max)) {
00099         sprintf(buf, _("The integer data range for %s@%s is empty"), name,
00100                 mapset);
00101         G_warning(buf);
00102         return -3;
00103     }
00104 
00105     G_quant_add_rule(quant, dMin, dMax, min, max);
00106 
00107     return 1;
00108 }
00109 #endif
00110 
00111 /*--------------------------------------------------------------------------*/
00112 
00113 int G__quant_import(const char *name, const char *mapset, struct Quant *quant)
00114 {
00115     char buf[1024];
00116     char *err;
00117     char xname[GNAME_MAX], xmapset[GMAPSET_MAX], element[GNAME_MAX + 7];
00118     int parsStat;
00119     FILE *fd;
00120 
00121     G_quant_free(quant);
00122 
00123     if (G_raster_map_type(name, mapset) == CELL_TYPE) {
00124         sprintf(buf,
00125                 "G__quant_import: attempt to open quantization table for CELL_TYPE file [%s] in mapset {%s]",
00126                 name, mapset);
00127         G_warning(buf);
00128         return -2;
00129     }
00130 
00131     if (G__name_is_fully_qualified(name, xname, xmapset)) {
00132         if (strcmp(xmapset, mapset) != 0)
00133             return -1;
00134         name = xname;
00135     }
00136 
00137     /* first check if quant2/mapset/name exists in the current mapset */
00138     sprintf(element, "quant2/%s", mapset);
00139     if ((fd = G_fopen_old(element, name, G_mapset()))) {
00140         parsStat = quant_parse_file(fd, quant);
00141         fclose(fd);
00142         if (parsStat)
00143             return 1;
00144         sprintf(buf,
00145                 "quantization file in quant2 for [%s] in mapset [%s] is empty",
00146                 name, mapset);
00147     }
00148 
00149     /* now try reading regular : cell_misc/name/quant file */
00150     if (!(fd = G_fopen_old_misc("cell_misc", QUANT_FILE_NAME, name, mapset))) {
00151 
00152         /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 3; */
00153         err = "missing";
00154 
00155     }
00156     else {
00157         parsStat = quant_parse_file(fd, quant);
00158         fclose(fd);
00159 
00160         if (parsStat)
00161             return 1;
00162         /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 2; */
00163 
00164         err = "empty";
00165     }
00166 
00167     sprintf(buf,
00168             _("quantization file [%s] in mapset [%s] %s"), name, mapset, err);
00169     G_warning(buf);
00170 
00171     return 0;
00172 }
00173 
00174 /*--------------------------------------------------------------------------*/
00175 
00176 /* parse input lines with the following formats
00177  *
00178  *   d_high:d_low:c_high:c_low
00179  *   d_high:d_low:c_val          (i.e. c_high == c_low)
00180  *   *:d_val:c_val               (interval [inf, d_val])  (**)
00181  *   d_val:*:c_val               (interval [d_val, inf])  (**)
00182  *
00183  *   all other lines are ignored
00184  *
00185  *  (**) only the first appearances in the file are considered.
00186  *
00187  */
00188 
00189 /*--------------------------------------------------------------------------*/
00190 
00191 static int quant_parse_file(FILE * fd, struct Quant *quant)
00192 {
00193     CELL cLow, cHigh;
00194     DCELL dLow, dHigh;
00195     char buf[1024];
00196     int foundNegInf = 0, foundPosInf = 0;
00197 
00198     while (fgets(buf, sizeof(buf), fd)) {
00199         if (strncmp(buf, "truncate", 8) == 0) {
00200             quant->truncate_only = 1;
00201             return 1;
00202         }
00203         if (strncmp(buf, "round", 5) == 0) {
00204             quant->round_only = 1;
00205             return 1;
00206         }
00207         switch (sscanf(buf, "%lf:%lf:%d:%d", &dLow, &dHigh, &cLow, &cHigh)) {
00208         case 3:
00209             G_quant_add_rule(quant, dLow, dHigh, cLow, cLow);
00210             break;
00211         case 4:
00212             G_quant_add_rule(quant, dLow, dHigh, cLow, cHigh);
00213             break;
00214         default:
00215             switch (sscanf(buf, "*:%lf:%d", &dLow, &cLow)) {
00216             case 2:
00217                 if (!foundNegInf) {
00218                     G_quant_set_neg_infinite_rule(quant, dLow, cLow);
00219                     foundNegInf = 1;
00220                 }
00221                 break;
00222             default:
00223                 switch (sscanf(buf, "%lf:*:%d", &dLow, &cLow)) {
00224                 case 2:
00225                     if (!foundPosInf) {
00226                         G_quant_set_pos_infinite_rule(quant, dLow, cLow);
00227                         foundPosInf = 1;
00228                     }
00229                     break;
00230                 default:
00231                     continue;   /* other lines are ignored */
00232                 }
00233             }
00234         }
00235     }
00236 
00237     if (G_quant_nof_rules(quant) > 0)
00238         G_quant_reverse_rule_order(quant);
00239 
00240     return ((G_quant_nof_rules(quant) > 0) ||
00241             (G_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0) ||
00242             (G_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0));
00243 }
00244 
00245 /*--------------------------------------------------------------------------*/
00246 
00247 /*--------------------------------------------------------------------------*/
00248 
00249 static void quant_write(FILE * fd, const struct Quant *quant)
00250 {
00251     DCELL dLow, dHigh;
00252     CELL cLow, cHigh;
00253     int i;
00254 
00255     if (quant->truncate_only) {
00256         fprintf(fd, "truncate");
00257         return;
00258     }
00259     if (quant->round_only) {
00260         fprintf(fd, "round");
00261         return;
00262     }
00263     if (G_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0)
00264         fprintf(fd, "*:%.20g:%d\n", dLow, cLow);
00265 
00266     if (G_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0)
00267         fprintf(fd, "%.20g:*:%d\n", dLow, cLow);
00268 
00269     for (i = G_quant_nof_rules(quant) - 1; i >= 0; i--) {
00270         G_quant_get_ith_rule(quant, i, &dLow, &dHigh, &cLow, &cHigh);
00271         fprintf(fd, "%.20g:%.20g:%d", dLow, dHigh, cLow);
00272         if (cLow != cHigh)
00273             fprintf(fd, ":%d", cHigh);
00274         fprintf(fd, "\n");
00275     }
00276 }
00277 
00278 /*--------------------------------------------------------------------------*/
00279 
00280 int
00281 G__quant_export(const char *name, const char *mapset,
00282                 const struct Quant *quant)
00283 {
00284     char element[GNAME_MAX + 7];
00285     char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
00286     FILE *fd;
00287 
00288     if (G__name_is_fully_qualified(name, xname, xmapset)) {
00289         if (strcmp(xmapset, mapset) != 0)
00290             return -1;
00291         name = xname;
00292     }
00293 
00294     if (strcmp(G_mapset(), mapset) == 0) {
00295         G_remove_misc("cell_misc", QUANT_FILE_NAME, name);
00296         G__make_mapset_element_misc("cell_misc", name);
00297         if (!(fd = G_fopen_new_misc("cell_misc", QUANT_FILE_NAME, name)))
00298             return -1;
00299     }
00300     else {
00301         sprintf(element, "quant2/%s", mapset);
00302         G_remove(element, name);
00303         G__make_mapset_element(element);
00304         if (!(fd = G_fopen_new(element, name)))
00305             return -1;
00306     }
00307 
00308 
00309 
00310     quant_write(fd, quant);
00311     fclose(fd);
00312 
00313     return 1;
00314 }
00315 
00316 /*--------------------------------------------------------------------------*/
00317 
00318 /*--------------------------------------------------------------------------*/
00319 
00320 /*--------------------------------------------------------------------------*/

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