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 "gis.h"
00061 #include "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 static int
00073 /* redundant: integer range doesn't exist now: it is defined by
00074    the quant rules */
00075 quant_load_range ( 
00076      struct Quant *quant,
00077      char *name,
00078      char *mapset)
00079 
00080 {
00081   struct FPRange fprange;
00082   struct Range range;
00083   char buf[300];
00084   DCELL dMin, dMax;
00085   CELL min, max;
00086 
00087   if (G_read_fp_range (name, mapset, &fprange) <= 0) return 0;
00088   G_get_fp_range_min_max (&fprange, &dMin, &dMax);
00089   if(G_is_d_null_value(&dMin) || G_is_d_null_value(&dMax))
00090   {
00091      sprintf(buf, _("The floating data range for %s@%s is empty"), name, mapset);
00092      G_warning(buf);
00093      return -3;
00094   }
00095 
00096   if (G_read_range (name, mapset, &range) < 0) 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   {
00100      sprintf(buf, _("The integer data range for %s@%s is empty"), name, 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 
00110 /*--------------------------------------------------------------------------*/
00111 
00112 int
00113 G__quant_import (name, mapset, quant)
00114 
00115     char *name;
00116     char *mapset;
00117     struct Quant *quant;
00118 
00119 {
00120   char buf[1024];
00121   char *err;
00122   char xname[512], xmapset[512], element[512];
00123   int parsStat;
00124   FILE *fd;
00125   
00126   G_quant_free (quant);
00127 
00128   if (G_raster_map_type (name, mapset) == CELL_TYPE) {
00129     sprintf (buf,
00130              "G__quant_import: attempt to open quantization table for CELL_TYPE file [%s] in mapset {%s]", 
00131              name, mapset);
00132     G_warning (buf);
00133     return -2;
00134   }
00135   
00136   if (G__name_is_fully_qualified (name, xname, xmapset)) {
00137     if (strcmp (xmapset, mapset) != 0) return -1;
00138     name = xname;
00139   }
00140   
00141   /* first check if quant2/mapset/name exists in the current mapset */
00142   sprintf (element, "quant2/%s", mapset);
00143   if ((fd = G_fopen_old (element, name, G_mapset())))
00144   {
00145     parsStat = quant_parse_file (fd, quant);
00146     fclose (fd);
00147     if (parsStat) return 1;
00148     sprintf(buf,"quantization file in quant2 for [%s] in mapset [%s] is empty",
00149              name, mapset);
00150   }
00151 
00152   /* now try reading regular : cell_misc/name/quant file */
00153   sprintf (element, "cell_misc/%s", name);
00154 
00155   if (! (fd = G_fopen_old (element, QUANT_FILE_NAME, mapset))) {
00156 
00157     /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 3; */
00158     err = "missing";
00159 
00160   } else {
00161     parsStat = quant_parse_file (fd, quant);
00162     fclose (fd);
00163 
00164     if (parsStat) return 1;
00165     /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 2; */
00166 
00167     err = "empty";
00168   }
00169   
00170   sprintf (buf, 
00171       _("quantization file [%s] in mapset [%s] %s"), 
00172       name, mapset, err);
00173   G_warning (buf);
00174 
00175   return 0;
00176 }
00177 
00178 /*--------------------------------------------------------------------------*/
00179 
00180 /* parse input lines with the following formats
00181  *
00182  *   d_high:d_low:c_high:c_low
00183  *   d_high:d_low:c_val          (i.e. c_high == c_low)
00184  *   *:d_val:c_val               (interval [inf, d_val])  (**)
00185  *   d_val:*:c_val               (interval [d_val, inf])  (**)
00186  *
00187  *   all other lines are ignored
00188  *
00189  *  (**) only the first appearances in the file are considered.
00190  *
00191  */
00192 
00193 /*--------------------------------------------------------------------------*/
00194 
00195 static int quant_parse_file (FILE *fd, struct Quant *quant)
00196 {
00197   CELL cLow, cHigh;
00198   DCELL dLow, dHigh;
00199   char buf[1024];
00200   int foundNegInf = 0, foundPosInf = 0;
00201   
00202   while (fgets (buf, sizeof (buf), fd)) 
00203   {
00204     if(strncmp(buf, "truncate", 8) == 0)
00205     {
00206         quant->truncate_only = 1;
00207         return 1;
00208     }
00209     if(strncmp(buf, "round", 5) == 0)
00210     {
00211         quant->round_only = 1;
00212         return 1;
00213     }
00214     switch (sscanf (buf, "%lf:%lf:%d:%d", &dLow, &dHigh, &cLow, &cHigh)) {
00215       case 3: G_quant_add_rule (quant, dLow, dHigh, cLow, cLow); break;
00216       case 4: G_quant_add_rule (quant, dLow, dHigh, cLow, cHigh); break;
00217       default:
00218         switch (sscanf (buf, "*:%lf:%d", &dLow, &cLow)) {
00219           case 2: 
00220             if (! foundNegInf) {
00221               G_quant_set_neg_infinite_rule (quant, dLow, cLow); 
00222               foundNegInf = 1;
00223             }
00224             break;
00225           default:
00226             switch (sscanf (buf, "%lf:*:%d", &dLow, &cLow)) {
00227               case 2: 
00228                 if (! foundPosInf) {
00229                   G_quant_set_pos_infinite_rule (quant, dLow, cLow); 
00230                   foundPosInf = 1;
00231                 }
00232                 break;
00233               default: continue;        /* other lines are ignored */
00234             }
00235         }
00236     }
00237   }
00238   
00239   if (G_quant_nof_rules (quant) > 0) G_quant_reverse_rule_order (quant);
00240 
00241   return ((G_quant_nof_rules (quant) > 0) || 
00242           (G_quant_get_neg_infinite_rule (quant, &dLow, &cLow) > 0) ||
00243           (G_quant_get_pos_infinite_rule (quant, &dLow, &cLow) > 0));
00244 }
00245 
00246 /*--------------------------------------------------------------------------*/
00247 /*--------------------------------------------------------------------------*/
00248 
00249 static void
00250 quant_write (fd, quant)
00251 
00252      FILE *fd;
00253      struct Quant *quant;
00254 
00255 {
00256   DCELL dLow, dHigh;
00257   CELL cLow, cHigh;
00258   int i;
00259 
00260   if(quant->truncate_only)
00261   {
00262     fprintf (fd, "truncate");
00263     return;
00264   }
00265   if(quant->round_only)
00266   {
00267     fprintf (fd, "round");
00268     return;
00269   }
00270   if (G_quant_get_neg_infinite_rule (quant, &dLow, &cLow) > 0)
00271     fprintf (fd, "*:%.20g:%d\n", dLow, cLow);
00272 
00273   if (G_quant_get_pos_infinite_rule (quant, &dLow, &cLow) > 0)
00274     fprintf (fd, "%.20g:*:%d\n", dLow, cLow);
00275 
00276   for (i = G_quant_nof_rules (quant) - 1; i >= 0; i--) {
00277     G_quant_get_ith_rule (quant, i, &dLow, &dHigh, &cLow, &cHigh);
00278     fprintf (fd, "%.20g:%.20g:%d", dLow, dHigh, cLow);
00279     if (cLow != cHigh) fprintf (fd, ":%d", cHigh);
00280     fprintf (fd, "\n");
00281   }
00282 }
00283 
00284 /*--------------------------------------------------------------------------*/
00285 
00286 int
00287 G__quant_export (name, mapset, quant)
00288      char *name, *mapset;
00289      struct Quant *quant;
00290 {
00291   char element[512];
00292   char xname[512], xmapset[512];
00293   FILE *fd;
00294 
00295   if (G__name_is_fully_qualified (name, xname, xmapset)) {
00296     if (strcmp (xmapset, mapset) != 0) return -1;
00297     name = xname;
00298   }
00299 
00300   if(strcmp (G_mapset(), mapset) == 0)
00301   {
00302      sprintf (element, "cell_misc/%s", name);
00303      G_remove (element, QUANT_FILE_NAME);
00304      G__make_mapset_element (element);
00305      if (! (fd = G_fopen_new (element, QUANT_FILE_NAME))) return -1;
00306   }
00307   else
00308   {
00309      sprintf (element, "quant2/%s", mapset);
00310      G_remove (element, name);
00311      G__make_mapset_element (element);
00312      if (! (fd = G_fopen_new (element, name))) return -1;
00313   }
00314 
00315 
00316 
00317   quant_write (fd, quant);
00318   fclose (fd);
00319 
00320   return 1;
00321 }
00322 
00323 /*--------------------------------------------------------------------------*/
00324 /*--------------------------------------------------------------------------*/
00325 /*--------------------------------------------------------------------------*/

Generated on Sat Jul 22 22:06:15 2006 for GRASS by  doxygen 1.4.7