quant_io.c

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

Generated on Wed Dec 19 14:59:06 2007 for GRASS by  doxygen 1.5.4