GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
range.c
Go to the documentation of this file.
1 
2 /**********************************************************************
3  *
4  * G_read_range (name, mapset, range)
5  * const char *name name of map
6  * const char *mapset mapset that map belongs to
7  * struct Range *range struct to hold range info
8  *
9  * Reads the data range information associated with map layer "map"
10  * in mapset "mapset"
11  *
12  * returns: 1 if successful
13  * 2 range is empty
14  * 3 map is fp: get range from quant rules
15  * -1 on fail
16  *
17  * note: a warning message is printed if the file is missing or incorrect
18  *
19  **********************************************************************
20  *
21  * G_read_fp_range (name, mapset, range)
22  * const char *name name of map
23  * const char *mapset mapset that map belongs to
24  * struct FPRange *range struct to hold range info
25  *
26  * Reads the fp data range information associated with map layer "map"
27  * in mapset "mapset" . If map is integer, the integer range is read
28  * and the max and min values are casted to doubles and copied to FPRange
29  *
30  * returns: 1 if successful
31  * 2 range is empty
32  * -1 on fail
33  *
34  * note: a warning message is printed if the file is missing or incorrect
35  *
36  **********************************************************************
37  *
38  * G_write_[fp_]range (name, range)
39  * const char *name name of map
40  * struct [FP]Range *range struct holding range info
41  *
42  * Writes the range information associated with map layer "map"
43  *
44  * returns: 0 if successful
45  * -1 on fail (or if the map is fp )
46  *
47  **********************************************************************
48  *
49  * G_init_[fp_]range (range)
50  * struct [FP]Range *range struct for range info
51  *
52  * initializes range structure for call to G_update_[fp_]range()
53  *
54  **********************************************************************
55  *
56  * G_construct_default_range (range)
57  * struct Range *range struct for range info
58  *
59  * returns 1 and range is set to DEFAULT_CELL_MIN
60  * and DEFAULT_SET_MAX, otherwise returns -1
61  *
62  **********************************************************************
63  *
64  * G_update_[fp_]range (cat, range)
65  * DCELL cat cat to be factored into range
66  * struct [FP]Range *range struct for range info
67  **********************************************************************
68  *
69  * G_row_update_[fp_]range (rast, range, data_type)
70  * void *rast raster row to be factored into range
71  * struct [FP]Range *range struct for range info
72  * RASTER_MAP_TYPE data_type;
73  **********************************************************************
74  *
75  * G_get_[fp_]range_min_max (range, min, max)
76  * struct [FP]Range *range;
77  * [D]CELL *min, *max;
78  **********************************************************************/
79 
80 #include <unistd.h>
81 #include <rpc/types.h> /* need this for sgi */
82 #include <rpc/xdr.h>
83 #include "G.h"
84 #include <grass/glocale.h>
85 #define DEFAULT_CELL_MIN 1
86 #define DEFAULT_CELL_MAX 255
87 
88 /*-------------------------------------------------------------------------*/
89 
90 /*-------------------------------------------------------------------------*/
91 
92 /* range functions for type "Range" */
93 
94 /*-------------------------------------------------------------------------*/
95 int G__remove_fp_range(const char *name)
96 {
97  G_remove_misc("cell_misc", "f_range", name);
98 
99  return 0;
100 }
101 
102 
113 {
116 
117  return 0;
118 }
119 
120 
139 int G_read_fp_range(const char *name, const char *mapset,
140  struct FPRange *drange)
141 {
142  struct Range range;
143  int fd;
144  char buf[200], xdr_buf[100];
145  DCELL dcell1, dcell2;
146  XDR xdr_str;
147 
148  G_init_fp_range(drange);
149 
150  if (G_raster_map_type(name, mapset) == CELL_TYPE) {
151  /* if map is integer
152  read integer range and convert it to double */
153 
154  if (G_read_range(name, mapset, &range) >= 0) {
155  /* if the integer range is empty */
156  if (range.first_time)
157  return 2;
158 
159  G_update_fp_range((DCELL) range.min, drange);
160  G_update_fp_range((DCELL) range.max, drange);
161  return 1;
162  }
163  return -1;
164  }
165 
166  fd = -1;
167 
168  if (G_find_file2_misc("cell_misc", "f_range", name, mapset)) {
169  fd = G_open_old_misc("cell_misc", "f_range", name, mapset);
170  if (fd < 0)
171  goto error;
172 
173  if (read(fd, xdr_buf, 2 * XDR_DOUBLE_NBYTES) != 2 * XDR_DOUBLE_NBYTES)
174  return 2;
175 
176  xdrmem_create(&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
177  XDR_DECODE);
178 
179  /* if the f_range file exists, but empty */
180  if (!xdr_double(&xdr_str, &dcell1) || !xdr_double(&xdr_str, &dcell2))
181  goto error;
182 
183  G_update_fp_range(dcell1, drange);
184  G_update_fp_range(dcell2, drange);
185  close(fd);
186  return 1;
187  }
188 
189  error:
190  if (fd > 0)
191  close(fd);
192  sprintf(buf, _("can't read f_range file for [%s in %s]"), name, mapset);
193  G_warning(buf);
194  return -1;
195 }
196 
197 /*-------------------------------------------------------------------------*/
198 
199 
226 int G_read_range(const char *name, const char *mapset, struct Range *range)
227 {
228  FILE *fd;
229  CELL x[4];
230  char buf[200];
231  int n, count;
232  struct Quant quant;
233  struct FPRange drange;
234 
235  G_init_range(range);
236  fd = NULL;
237 
238  /* if map is not integer, read quant rules, and get limits */
239  if (G_raster_map_type(name, mapset) != CELL_TYPE) {
240  DCELL dmin, dmax;
241 
242  if (G_read_quant(name, mapset, &quant) < 0) {
243  sprintf(buf,
244  "G_read_range(): can't read quant rules for fp map %s@%s",
245  name, mapset);
246  G_warning(buf);
247  return -1;
248  }
249  if (G_quant_is_truncate(&quant) || G_quant_is_round(&quant)) {
250  if (G_read_fp_range(name, mapset, &drange) >= 0) {
251  G_get_fp_range_min_max(&drange, &dmin, &dmax);
252  if (G_quant_is_truncate(&quant)) {
253  x[0] = (CELL) dmin;
254  x[1] = (CELL) dmax;
255  }
256  else { /* round */
257 
258  if (dmin > 0)
259  x[0] = (CELL) (dmin + .5);
260  else
261  x[0] = (CELL) (dmin - .5);
262  if (dmax > 0)
263  x[1] = (CELL) (dmax + .5);
264  else
265  x[1] = (CELL) (dmax - .5);
266  }
267  }
268  else
269  return -1;
270  }
271  else
272  G_quant_get_limits(&quant, &dmin, &dmax, &x[0], &x[1]);
273 
274  G_update_range(x[0], range);
275  G_update_range(x[1], range);
276  return 3;
277  }
278 
279  if (G_find_file2_misc("cell_misc", "range", name, mapset)) {
280  fd = G_fopen_old_misc("cell_misc", "range", name, mapset);
281  if (!fd)
282  goto error;
283 
284  /* if range file exists but empty */
285  if (!fgets(buf, sizeof buf, fd))
286  return 2;
287 
288  x[0] = x[1] = x[2] = x[3] = 0;
289  count = sscanf(buf, "%d%d%d%d", &x[0], &x[1], &x[2], &x[3]);
290 
291  /* if wrong format */
292  if (count <= 0)
293  goto error;
294 
295  for (n = 0; n < count; n++) {
296  /* if count==4, the range file is old (4.1) and 0's in it
297  have to be ignored */
298  if (count < 4 || x[n])
299  G_update_range((CELL) x[n], range);
300  }
301  fclose(fd);
302  return 1;
303  }
304 
305  error:
306  if (fd)
307  fclose(fd);
308  sprintf(buf, _("can't read range file for [%s in %s]"), name, mapset);
309  G_warning(buf);
310  return -1;
311 }
312 
313 /*-------------------------------------------------------------------------*/
314 
315 
334 int G_write_range(const char *name, const struct Range *range)
335 {
336  FILE *fd;
337  char buf[200];
338 
339  if (G_raster_map_type(name, G_mapset()) != CELL_TYPE) {
340  sprintf(buf, "G_write_range(): the map is floating point!");
341  goto error;
342  }
343  fd = G_fopen_new_misc("cell_misc", "range", name);
344  if (!fd)
345  goto error;
346 
347  if (range->first_time)
348  /* if range hasn't been updated */
349  {
350  fclose(fd);
351  return 0;
352  }
353  fprintf(fd, "%ld %ld\n", (long)range->min, (long)range->max);
354  fclose(fd);
355  return 0;
356 
357  error:
358  G_remove_misc("cell_misc", "range", name); /* remove the old file with this name */
359  sprintf(buf, _("can't write range file for [%s in %s]"),
360  name, G_mapset());
361  G_warning(buf);
362  return -1;
363 }
364 
365 /*-------------------------------------------------------------------------*/
366 
367 
380 int G_write_fp_range(const char *name, const struct FPRange *range)
381 {
382  int fd;
383  char buf[200], xdr_buf[100];
384  XDR xdr_str;
385 
386  sprintf(buf, "cell_misc/%s", name);
387  fd = G_open_new(buf, "f_range");
388  if (fd < 0)
389  goto error;
390 
391  if (range->first_time)
392  /* if range hasn't been updated, write empty file meaning Nulls */
393  {
394  close(fd);
395  return 0;
396  }
397 
398  xdrmem_create(&xdr_str, xdr_buf, (u_int) XDR_DOUBLE_NBYTES * 2,
399  XDR_ENCODE);
400 
401  if (!xdr_double(&xdr_str, (double *)&(range->min)))
402  goto error;
403  if (!xdr_double(&xdr_str, (double *)&(range->max)))
404  goto error;
405 
406  write(fd, xdr_buf, XDR_DOUBLE_NBYTES * 2);
407  close(fd);
408  return 0;
409 
410  error:
411  G_remove(buf, "f_range"); /* remove the old file with this name */
412  sprintf(buf, _("can't write range file for [%s in %s]"),
413  name, G_mapset());
414  G_warning(buf);
415  return -1;
416 }
417 
418 /*-------------------------------------------------------------------------*/
419 
420 
436 int G_update_range(CELL cat, struct Range *range)
437 {
438  if (!G_is_c_null_value(&cat)) {
439  if (range->first_time) {
440  range->first_time = 0;
441  range->min = cat;
442  range->max = cat;
443  return 0;
444  }
445  if (cat < range->min)
446  range->min = cat;
447  if (cat > range->max)
448  range->max = cat;
449  }
450 
451  return 0;
452 }
453 
454 /*-------------------------------------------------------------------------*/
455 
456 int G_update_fp_range(DCELL val, struct FPRange *range)
457 {
458  if (!G_is_d_null_value(&val)) {
459  if (range->first_time) {
460  range->first_time = 0;
461  range->min = val;
462  range->max = val;
463  return 0;
464  }
465  if (val < range->min)
466  range->min = val;
467  if (val > range->max)
468  range->max = val;
469  }
470  return 0;
471 }
472 
473 /*-------------------------------------------------------------------------*/
474 
475 
489 int G_row_update_range(const CELL * cell, int n, struct Range *range)
490 {
491  G__row_update_range(cell, n, range, 0);
492 
493  return 0;
494 }
495 
496 /*-------------------------------------------------------------------------*/
497 
498 int G__row_update_range(const CELL * cell, int n,
499  struct Range *range, int ignore_zeros)
500 {
501  CELL cat;
502 
503  while (n-- > 0) {
504  cat = *cell++;
505  if (G_is_c_null_value(&cat) || (ignore_zeros && !cat))
506  continue;
507  if (range->first_time) {
508  range->first_time = 0;
509  range->min = cat;
510  range->max = cat;
511  continue;
512  }
513  if (cat < range->min)
514  range->min = cat;
515  if (cat > range->max)
516  range->max = cat;
517  }
518 
519  return 0;
520 }
521 
522 /*-------------------------------------------------------------------------*/
523 
524 int G_row_update_fp_range(const void *rast, int n,
525  struct FPRange *range, RASTER_MAP_TYPE data_type)
526 {
527  DCELL val = 0L;
528 
529  while (n-- > 0) {
530  switch (data_type) {
531  case CELL_TYPE:
532  val = (DCELL) * ((CELL *) rast);
533  break;
534  case FCELL_TYPE:
535  val = (DCELL) * ((FCELL *) rast);
536  break;
537  case DCELL_TYPE:
538  val = *((DCELL *) rast);
539  break;
540  }
541 
542  if (G_is_null_value(rast, data_type)) {
543  rast = G_incr_void_ptr(rast, G_raster_size(data_type));
544  continue;
545  }
546  if (range->first_time) {
547  range->first_time = 0;
548  range->min = val;
549  range->max = val;
550  }
551  else {
552  if (val < range->min)
553  range->min = val;
554  if (val > range->max)
555  range->max = val;
556  }
557 
558  rast = G_incr_void_ptr(rast, G_raster_size(data_type));
559  }
560 
561  return 0;
562 }
563 
564 /*-------------------------------------------------------------------------*/
565 
579 int G_init_range(struct Range *range)
580 {
581  G_set_c_null_value(&(range->min), 1);
582  G_set_c_null_value(&(range->max), 1);
583  range->first_time = 1;
584 
585  return 0;
586 }
587 
588 /*-------------------------------------------------------------------------*/
589 
590 
608 int G_get_range_min_max(const struct Range *range, CELL * min, CELL * max)
609 {
610  if (range->first_time) {
611  G_set_c_null_value(min, 1);
612  G_set_c_null_value(max, 1);
613  }
614  else {
615  if (G_is_c_null_value(&(range->min)))
616  G_set_c_null_value(min, 1);
617  else
618  *min = range->min;
619 
620  if (G_is_c_null_value(&(range->max)))
621  G_set_c_null_value(max, 1);
622  else
623  *max = range->max;
624  }
625 
626  return 0;
627 }
628 
629 /*-------------------------------------------------------------------------*/
630 
642 int G_init_fp_range(struct FPRange *range)
643 {
644  G_set_d_null_value(&(range->min), 1);
645  G_set_d_null_value(&(range->max), 1);
646  range->first_time = 1;
647 
648  return 0;
649 }
650 
651 /*-------------------------------------------------------------------------*/
652 
653 
667 int G_get_fp_range_min_max(const struct FPRange *range,
668  DCELL * min, DCELL * max)
669 {
670  if (range->first_time) {
671  G_set_d_null_value(min, 1);
672  G_set_d_null_value(max, 1);
673  }
674  else {
675  if (G_is_d_null_value(&(range->min)))
676  G_set_d_null_value(min, 1);
677  else
678  *min = range->min;
679 
680  if (G_is_d_null_value(&(range->max)))
681  G_set_d_null_value(max, 1);
682  else
683  *max = range->max;
684  }
685 
686  return 0;
687 }
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)
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
#define min(x, y)
Definition: draw2.c:68
void G_set_d_null_value(DCELL *dcellVals, int numVals)
Definition: null_val.c:176
int G_read_quant(const char *name, const char *mapset, struct Quant *quant)
reads quantization rules for &quot;name&quot; in &quot;mapset&quot; and stores them in the quantization structure &quot;quant&quot;...
Definition: quant_rw.c:245
DCELL dcell1
Definition: g3drange.c:65
int G_quant_is_truncate(const struct Quant *quant)
Definition: quant.c:435
char * G_find_file2_misc(const char *dir, const char *element, const char *name, const char *mapset)
Definition: find_file.c:196
int G_write_fp_range(const char *name, const struct FPRange *range)
Write the floating point range file f_range. This file is written in binary using XDR format...
Definition: range.c:380
char xdr_buf[100]
Definition: g3drange.c:64
int count
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
int G_update_range(CELL cat, struct Range *range)
update range structure
Definition: range.c:436
#define max(x, y)
Definition: draw2.c:69
DCELL dmin
Definition: g3dcolor.c:53
void * G_incr_void_ptr(const void *ptr, const size_t size)
Advance void pointer.
Definition: gis/raster.c:33
int G_row_update_fp_range(const void *rast, int n, struct FPRange *range, RASTER_MAP_TYPE data_type)
Definition: range.c:524
int G_update_fp_range(DCELL val, struct FPRange *range)
Definition: range.c:456
int G_read_range(const char *name, const char *mapset, struct Range *range)
read raster range
Definition: range.c:226
int G_open_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:124
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__row_update_range(const CELL *cell, int n, struct Range *range, int ignore_zeros)
Definition: range.c:498
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
int G_row_update_range(const CELL *cell, int n, struct Range *range)
update range structure
Definition: range.c:489
int G_quant_get_limits(const struct Quant *q, DCELL *dMin, DCELL *dMax, CELL *cMin, CELL *cMax)
Extracts the minimum and maximum floating-point and integer values from all the rules (except the &quot;in...
Definition: quant.c:534
size_t G_raster_size(RASTER_MAP_TYPE data_type)
Returns size of a raster CELL in bytes.
Definition: alloc_cell.c:38
int G_quant_is_round(const struct Quant *quant)
Definition: quant.c:442
XDR xdr_str
Definition: g3drange.c:66
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_init_range(struct Range *range)
initialize range structure
Definition: range.c:579
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_construct_default_range(struct Range *range)
Sets the integer range r to [1,255].
Definition: range.c:112
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
DCELL dcell2
Definition: g3drange.c:65
int G_open_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:125
#define XDR_DOUBLE_NBYTES
Definition: G.h:10
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
void G_set_c_null_value(CELL *cellVals, int numVals)
Definition: null_val.c:142
CELL cat
Definition: g3dcats.c:90
int G_remove_misc(const char *dir, const char *element, const char *name)
Remove a database misc file.
Definition: remove.c:67
G_init_fp_range(drange)
int G__remove_fp_range(const char *name)
Definition: range.c:95
DCELL dmax
Definition: g3dcolor.c:53
struct FPRange drange
Definition: g3dcolor.c:52
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
#define DEFAULT_CELL_MIN
Definition: range.c:85
int n
Definition: dataquad.c:291
int G_write_range(const char *name, const struct Range *range)
write raster range file
Definition: range.c:334
#define DEFAULT_CELL_MAX
Definition: range.c:86
int G_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
If the data_type is CELL_TYPE, calls G_is_c_null_value ((CELL *) rast); If the data_type is FCELL_TYP...
Definition: null_val.c:207