GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
quant_io.c
Go to the documentation of this file.
1 
2 /**********************************************************************
3  *
4  * int
5  * G__quant_import (name, mapset, quant)
6  *
7  * char *name;
8  * char *mapset;
9  * struct Quant *quant;
10  *
11  * reads quantization rules for "name" in "mapset" and stores them
12  * in the quantization structure "quant". If the map is in another
13  * mapset, first checks for quant2 table for this map in current
14  * mapset.
15  *
16  * returns: -2 if raster map is of type integer.
17  * -1 if (! G__name_is_fully_qualified ()).
18  * 0 if quantization file does not exist, or the file is empty,
19  * 1 if non-empty quantization file exists.
20  * read.
21  *
22  * note: in the case of negative return value, the result of using the
23  * quantization structure is not defined.
24  * in case of return value 0, calls to G_quant_perform_d ()
25  * and G_quant_perform_f () return NO_DATA (see description of
26  * G_quant_perform_d () for more details). in case of
27  * return values 2 and 3, the explicit rule for quant is set:
28  * floating range is mapped to integer range.
29  *
30  * note: use G_quant_init () to allocate and initialize the quantization
31  * staructure quant before the first usage of G_quant_import ().
32  *
33  * note: this function uses G_quant_free () to clear all previously
34  * stored rules in quant.
35  *
36  **********************************************************************
37  *
38  * int
39  * G__quant_export (name, mapset, quant)
40  *
41  * char *name, *mapset;
42  * struct Quant *quant;
43  *
44  * writes the quantization rules stored in "quant" for "name" . if the
45  * mapset is the same as the current mapset, the quant file is created
46  * in cell_misc/name directory, otherwise it is created in quant2/mapset
47  * directory, much like writing colors for map in another mapset.
48  * The rules are written in decreasing order
49  * of priority (i.e. rules added earlier are written later).
50  *
51  * returns: -1 if (! G__name_is_fully_qualified) or file could not be
52  * opened.
53  * 1 otherwise.
54  *
55  * note: if no rules are defined an empty file is created.
56  *
57  **********************************************************************/
58 
59 /*--------------------------------------------------------------------------*/
60 
61 #include <grass/gis.h>
62 #include <grass/glocale.h>
63 #include <string.h>
64 
65 /*--------------------------------------------------------------------------*/
66 
67 #define QUANT_FILE_NAME "f_quant"
68 
69 /*--------------------------------------------------------------------------*/
70 
71 static int quant_parse_file(FILE *, struct Quant *);
72 
73 #if 0
74 static int
75 /* redundant: integer range doesn't exist now: it is defined by
76  the quant rules */
77 quant_load_range(struct Quant *quant, const char *name, const char *mapset)
78 {
79  struct FPRange fprange;
80  struct Range range;
81  char buf[300];
82  DCELL dMin, dMax;
83  CELL min, max;
84 
85  if (G_read_fp_range(name, mapset, &fprange) <= 0)
86  return 0;
87  G_get_fp_range_min_max(&fprange, &dMin, &dMax);
88  if (G_is_d_null_value(&dMin) || G_is_d_null_value(&dMax)) {
89  sprintf(buf, _("The floating data range for %s@%s is empty"), name,
90  mapset);
91  G_warning(buf);
92  return -3;
93  }
94 
95  if (G_read_range(name, mapset, &range) < 0)
96  return 0;
97  G_get_range_min_max(&range, &min, &max);
98  if (G_is_c_null_value(&min) && G_is_c_null_value(&max)) {
99  sprintf(buf, _("The integer data range for %s@%s is empty"), name,
100  mapset);
101  G_warning(buf);
102  return -3;
103  }
104 
105  G_quant_add_rule(quant, dMin, dMax, min, max);
106 
107  return 1;
108 }
109 #endif
110 
111 /*--------------------------------------------------------------------------*/
112 
113 int G__quant_import(const char *name, const char *mapset, struct Quant *quant)
114 {
115  char buf[1024];
116  char *err;
117  char xname[GNAME_MAX], xmapset[GMAPSET_MAX], element[GNAME_MAX + 7];
118  int parsStat;
119  FILE *fd;
120 
121  G_quant_free(quant);
122 
123  if (G_raster_map_type(name, mapset) == CELL_TYPE) {
124  sprintf(buf,
125  "G__quant_import: attempt to open quantization table for CELL_TYPE file [%s] in mapset {%s]",
126  name, mapset);
127  G_warning(buf);
128  return -2;
129  }
130 
131  if (G__name_is_fully_qualified(name, xname, xmapset)) {
132  if (strcmp(xmapset, mapset) != 0)
133  return -1;
134  name = xname;
135  }
136 
137  /* first check if quant2/mapset/name exists in the current mapset */
138  sprintf(element, "quant2/%s", mapset);
139  if ((fd = G_fopen_old(element, name, G_mapset()))) {
140  parsStat = quant_parse_file(fd, quant);
141  fclose(fd);
142  if (parsStat)
143  return 1;
144  sprintf(buf,
145  "quantization file in quant2 for [%s] in mapset [%s] is empty",
146  name, mapset);
147  }
148 
149  /* now try reading regular : cell_misc/name/quant file */
150  if (!(fd = G_fopen_old_misc("cell_misc", QUANT_FILE_NAME, name, mapset))) {
151 
152  /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 3; */
153  err = "missing";
154 
155  }
156  else {
157  parsStat = quant_parse_file(fd, quant);
158  fclose(fd);
159 
160  if (parsStat)
161  return 1;
162  /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 2; */
163 
164  err = "empty";
165  }
166 
167  sprintf(buf,
168  _("quantization file [%s] in mapset [%s] %s"), name, mapset, err);
169  G_warning(buf);
170 
171  return 0;
172 }
173 
174 /*--------------------------------------------------------------------------*/
175 
176 /* parse input lines with the following formats
177  *
178  * d_high:d_low:c_high:c_low
179  * d_high:d_low:c_val (i.e. c_high == c_low)
180  * *:d_val:c_val (interval [inf, d_val]) (**)
181  * d_val:*:c_val (interval [d_val, inf]) (**)
182  *
183  * all other lines are ignored
184  *
185  * (**) only the first appearances in the file are considered.
186  *
187  */
188 
189 /*--------------------------------------------------------------------------*/
190 
191 static int quant_parse_file(FILE * fd, struct Quant *quant)
192 {
193  CELL cLow, cHigh;
194  DCELL dLow, dHigh;
195  char buf[1024];
196  int foundNegInf = 0, foundPosInf = 0;
197 
198  while (fgets(buf, sizeof(buf), fd)) {
199  if (strncmp(buf, "truncate", 8) == 0) {
200  quant->truncate_only = 1;
201  return 1;
202  }
203  if (strncmp(buf, "round", 5) == 0) {
204  quant->round_only = 1;
205  return 1;
206  }
207  switch (sscanf(buf, "%lf:%lf:%d:%d", &dLow, &dHigh, &cLow, &cHigh)) {
208  case 3:
209  G_quant_add_rule(quant, dLow, dHigh, cLow, cLow);
210  break;
211  case 4:
212  G_quant_add_rule(quant, dLow, dHigh, cLow, cHigh);
213  break;
214  default:
215  switch (sscanf(buf, "*:%lf:%d", &dLow, &cLow)) {
216  case 2:
217  if (!foundNegInf) {
218  G_quant_set_neg_infinite_rule(quant, dLow, cLow);
219  foundNegInf = 1;
220  }
221  break;
222  default:
223  switch (sscanf(buf, "%lf:*:%d", &dLow, &cLow)) {
224  case 2:
225  if (!foundPosInf) {
226  G_quant_set_pos_infinite_rule(quant, dLow, cLow);
227  foundPosInf = 1;
228  }
229  break;
230  default:
231  continue; /* other lines are ignored */
232  }
233  }
234  }
235  }
236 
237  if (G_quant_nof_rules(quant) > 0)
239 
240  return ((G_quant_nof_rules(quant) > 0) ||
241  (G_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0) ||
242  (G_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0));
243 }
244 
245 /*--------------------------------------------------------------------------*/
246 
247 /*--------------------------------------------------------------------------*/
248 
249 static void quant_write(FILE * fd, const struct Quant *quant)
250 {
251  DCELL dLow, dHigh;
252  CELL cLow, cHigh;
253  int i;
254 
255  if (quant->truncate_only) {
256  fprintf(fd, "truncate");
257  return;
258  }
259  if (quant->round_only) {
260  fprintf(fd, "round");
261  return;
262  }
263  if (G_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0)
264  fprintf(fd, "*:%.20g:%d\n", dLow, cLow);
265 
266  if (G_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0)
267  fprintf(fd, "%.20g:*:%d\n", dLow, cLow);
268 
269  for (i = G_quant_nof_rules(quant) - 1; i >= 0; i--) {
270  G_quant_get_ith_rule(quant, i, &dLow, &dHigh, &cLow, &cHigh);
271  fprintf(fd, "%.20g:%.20g:%d", dLow, dHigh, cLow);
272  if (cLow != cHigh)
273  fprintf(fd, ":%d", cHigh);
274  fprintf(fd, "\n");
275  }
276 }
277 
278 /*--------------------------------------------------------------------------*/
279 
280 int
281 G__quant_export(const char *name, const char *mapset,
282  const struct Quant *quant)
283 {
284  char element[GNAME_MAX + 7];
285  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
286  FILE *fd;
287 
288  if (G__name_is_fully_qualified(name, xname, xmapset)) {
289  if (strcmp(xmapset, mapset) != 0)
290  return -1;
291  name = xname;
292  }
293 
294  if (strcmp(G_mapset(), mapset) == 0) {
295  G_remove_misc("cell_misc", QUANT_FILE_NAME, name);
296  G__make_mapset_element_misc("cell_misc", name);
297  if (!(fd = G_fopen_new_misc("cell_misc", QUANT_FILE_NAME, name)))
298  return -1;
299  }
300  else {
301  sprintf(element, "quant2/%s", mapset);
302  G_remove(element, name);
303  G__make_mapset_element(element);
304  if (!(fd = G_fopen_new(element, name)))
305  return -1;
306  }
307 
308 
309 
310  quant_write(fd, quant);
311  fclose(fd);
312 
313  return 1;
314 }
315 
316 /*--------------------------------------------------------------------------*/
317 
318 /*--------------------------------------------------------------------------*/
319 
320 /*--------------------------------------------------------------------------*/
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
int G_is_c_null_value(const CELL *cellVal)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int...
Definition: null_val.c:244
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void G_quant_free(struct Quant *q)
Definition: quant.c:316
void G_quant_set_neg_infinite_rule(struct Quant *q, DCELL dLeft, CELL c)
Definition: quant.c:595
char xmapset[512]
Definition: g3dcats.c:89
int G_quant_get_neg_infinite_rule(const struct Quant *q, DCELL *dLeft, CELL *c)
Definition: quant.c:611
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
#define min(x, y)
Definition: draw2.c:68
FILE * G_fopen_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:200
const char * err
Definition: g3dcolor.c:50
#define max(x, y)
Definition: draw2.c:69
int G_read_range(const char *name, const char *mapset, struct Range *range)
read raster range
Definition: range.c:226
void G_quant_get_ith_rule(const struct Quant *q, int i, DCELL *dLow, DCELL *dHigh, CELL *cLow, CELL *cHigh)
Definition: quant.c:562
int G_get_range_min_max(const struct Range *range, CELL *min, CELL *max)
get range min and max
Definition: range.c:608
int G__quant_import(const char *name, const char *mapset, struct Quant *quant)
Definition: quant_io.c:113
int G_is_d_null_value(const DCELL *dcellVal)
Returns 1 if dcell is NULL, 0 otherwise. This will test if the value dcell is a NaN. Same test as in G_is_f_null_value().
Definition: null_val.c:306
void G_quant_reverse_rule_order(struct Quant *q)
Definition: quant.c:694
int G__quant_export(const char *name, const char *mapset, const struct Quant *quant)
Definition: quant_io.c:281
int G_remove(const char *element, const char *name)
Remove a database file.
Definition: remove.c:47
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int G_quant_nof_rules(const struct Quant *q)
Definition: quant.c:555
int G__make_mapset_element_misc(const char *dir, const char *name)
Create misc element in the current mapset.
Definition: mapset_msc.c:82
void G_quant_add_rule(struct Quant *q, DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
Definition: quant.c:655
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:197
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_get_fp_range_min_max(const struct FPRange *range, DCELL *min, DCELL *max)
Extract the min/max from the range structure r. If the range structure has no defined min/max (first!...
Definition: range.c:667
fclose(fd)
FILE * G_fopen_new_misc(const char *dir, const char *element, const char *name)
open a new database file
Definition: open_misc.c:172
int G_read_fp_range(const char *name, const char *mapset, struct FPRange *drange)
Read the floating point range file f_range. This file is written in binary using XDR format...
Definition: range.c:139
int G__make_mapset_element(const char *p_element)
Create element in the current mapset.
Definition: mapset_msc.c:34
int G_remove_misc(const char *dir, const char *element, const char *name)
Remove a database misc file.
Definition: remove.c:67
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:226
RASTER_MAP_TYPE G_raster_map_type(const char *name, const char *mapset)
Determine raster data type.
Definition: opencell.c:1001
tuple range
Definition: tools.py:1406
void G_quant_set_pos_infinite_rule(struct Quant *q, DCELL dRight, CELL c)
Definition: quant.c:625
char xname[512]
Definition: g3dcats.c:89
#define QUANT_FILE_NAME
Definition: quant_io.c:67
int G_quant_get_pos_infinite_rule(const struct Quant *q, DCELL *dRight, CELL *c)
Definition: quant.c:641
int G__name_is_fully_qualified(const char *fullname, char *name, char *mapset)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:57