GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
raster/cats.c
Go to the documentation of this file.
1 /*!
2  * \file lib/raster/cats.c
3  *
4  * \brief Raster Library - Raster categories management
5  *
6  * Code in this file works with category files. There are two formats:
7  * Pre 3.0 direct category encoding form:
8  *
9  * 2 categories
10  * Map Title
11  * Elevation: 1000.00 to 1005.00 feet
12  * Elevation: 1005.00 to 1010.00 feet
13  * Elevation: 1010.00 to 1015.00 feet
14  *
15  * 3.0 format
16  *
17  * # 2 categories
18  * Map Title
19  * Elevation: $1.2 to $2.2 feet ## Format Statement
20  * 5.0 1000 5.0 1005 ## Coefficients
21  *
22  * The coefficient line can be followed by explicit category labels
23  * which override the format label generation.
24  * 0:no data
25  * 2: .
26  * 5: . ## explicit category labels
27  * 7: .
28  * explicit labels can be also of the form:
29  * 5.5:5:9 label description
30  * or
31  * 15:30 label description
32  *
33  * In the format line
34  * $1 refers to the value num*5.0+1000 (ie, using the first 2 coefficients)
35  * $2 refers to the value num*5.0+1005 (ie, using the last 2 coefficients)
36  *
37  * $1.2 will print $1 with 2 decimal places.
38  *
39  * Also, the form $?xxx$yyy$ translates into yyy if the category is 1, xxx
40  * otherwise. The $yyy$ is optional. Thus
41  *
42  * $1 meter$?s
43  *
44  * will become: 1 meter (for category 1)
45  * 2 meters (for category 2), etc.
46  *
47  * The format and coefficients above would be used to generate the
48  * following statement in creation of the format appropriate category
49  * string for category "num":
50  *
51  * sprintf(buff,"Elevation: %.2f to %.2f feet", num*5.0+1000, num*5.0*1005)
52  *
53  * Note: while both the format and coefficient lines must be present
54  * a blank line for the fmt will effectively suppress automatic
55  * label generation
56  *
57  * Note: quant rules of Categories structures are heavily dependent
58  * on the fact that rules are stored in the same order they are entered.
59  * since i-th rule and i-th label are entered at the same time, we
60  * know that i-th rule maps fp range to i, thus we know for sure
61  * that cats.labels[i] corresponds to i-th quant rule
62  *
63  * (C) 2001-2009 by the GRASS Development Team
64  *
65  * This program is free software under the GNU General Public License
66  * (>=v2). Read the file COPYING that comes with GRASS for details.
67  *
68  * \author Original author CERL
69  */
70 
71 #include <stdlib.h>
72 #include <string.h>
73 
74 #include <grass/gis.h>
75 #include <grass/raster.h>
76 #include <grass/glocale.h>
77 
78 static void get_cond(char **, char *, DCELL);
79 static int get_fmt(char **, char *, int *);
80 static int cmp(const void *, const void *);
81 
82 static void write_cats(const char *element, const char *name,
83  struct Categories *cats);
84 static CELL read_cats(const char *element, const char *name,
85  const char *mapset, struct Categories *pcats, int full);
86 
87 static struct Categories save_cats;
88 
89 /*!
90  * \brief Read raster category file
91  *
92  * The category file for raster map <i>name</i> in <i>mapset</i> is
93  * read into the <i>cats</i> structure. If there is an error reading
94  * the category file, a diagnostic message is printed and -1 is
95  * returned. Otherwise, 0 is returned.
96  *
97  * \param name raster map name
98  * \param mapset mapset name
99  * \param[out] pcats pointer to Cats structure
100  *
101  * \return -1 on error
102  * \return 0 on success
103  */
104 int Rast_read_cats(const char *name,
105  const char *mapset, struct Categories *pcats)
106 {
107  switch (read_cats("cats", name, mapset, pcats, 1)) {
108  case -2:
109  G_warning(_("Category support for <%s@%s> missing"), name, mapset);
110  break;
111  case -1:
112  G_warning(_("Category support for <%s@%s> invalid"), name, mapset);
113  break;
114  default:
115  return 0;
116  }
117 
118  return -1;
119 }
120 
121 /*!
122  * \brief Read vector category file
123  *
124  * <b>Note:</b> This function works with <b>old</b> vector format.
125  *
126  * \todo: To be moved to the vector library
127  *
128  * The category file for vector map <i>name</i> in <i>mapset</i> is
129  * read into the <i>cats</i> structure. If there is an error reading
130  * the category file, a diagnostic message is printed and -1 is
131  * returned. Otherwise, 0 is returned.
132  *
133  * \param name vector map name
134  * \param mapset mapset name
135  * \param[out] pcats pointer to Cats structure
136  *
137  * \return -1 on error
138  * \return 0 on success
139  */
140 int Rast_read_vector_cats(const char *name,
141  const char *mapset, struct Categories *pcats)
142 {
143  switch (read_cats("dig_cats", name, mapset, pcats, 1)) {
144  case -2:
145  G_warning(_("Category support for vector map <%s@%s> missing"),
146  name, mapset);
147  break;
148  case -1:
149  G_warning(_("Category support for vector map <%s@%s> invalid"),
150  name, mapset);
151  break;
152  default:
153  return 0;
154  }
155 
156  return -1;
157 }
158 
159 /*!
160  \brief Get the max category number
161 
162  Return the max category number of a raster map
163  of type CELL.
164 
165  \param name raster map name
166  \param mapset mapset name
167 
168  \return -1 on error
169  \return number of cats
170  */
171 CELL Rast_get_max_c_cat(const char *name, const char *mapset)
172 {
173  struct Range range;
174  CELL min, max;
175 
176  /* return the max category number */
177  if (Rast_read_range(name, mapset, &range) < 0)
178  return -1;
179  Rast_get_range_min_max(&range, &min, &max);
180  if (Rast_is_c_null_value(&max))
181  max = 0;
182  return max;
183 }
184 
185 static CELL read_cats(const char *element,
186  const char *name,
187  const char *mapset, struct Categories *pcats, int full)
188 {
189  FILE *fd;
190  char buff[1024];
191  CELL cat1, cat2;
192  DCELL val1, val2;
193  int old = 0, fp_map;
194  long num = -1;
195 
196 
197  if (strncmp(element, "dig", 3) == 0)
198  fp_map = 0;
199  else
200  fp_map = Rast_map_is_fp(name, mapset);
201 
202  if (!(fd = G_fopen_old(element, name, mapset)))
203  return -2;
204 
205  /* Read the number of categories */
206  if (G_getl(buff, sizeof buff, fd) == 0)
207  goto error;
208 
209  if (sscanf(buff, "# %ld", &num) == 1)
210  old = 0;
211  else if (sscanf(buff, "%ld", &num) == 1)
212  old = 1;
213 
214  if (!full) {
215  fclose(fd);
216  if (num < 0)
217  return 0; /* coorect */
218  return (CELL) num;
219  }
220 
221  /* Read the title for the file */
222  if (G_getl(buff, sizeof buff, fd) == 0)
223  goto error;
224  G_strip(buff);
225  /* G_ascii_check(buff) ; */
226 
227  Rast_init_cats(buff, pcats);
228  if (num >= 0)
229  pcats->num = num;
230 
231  if (!old) {
232  char fmt[256];
233  float m1, a1, m2, a2;
234 
235  if (G_getl(fmt, sizeof fmt, fd) == 0)
236  goto error;
237  /* next line contains equation coefficients */
238  if (G_getl(buff, sizeof buff, fd) == 0)
239  goto error;
240  if (sscanf(buff, "%f %f %f %f", &m1, &a1, &m2, &a2) != 4)
241  goto error;
242  Rast_set_cats_fmt(fmt, m1, a1, m2, a2, pcats);
243  }
244 
245  /* Read all category names */
246  for (cat1 = 0;; cat1++) {
247  char label[1024];
248 
249  if (G_getl(buff, sizeof buff, fd) == 0)
250  break;
251  if (old)
252  Rast_set_c_cat(&cat1, &cat1, buff, pcats);
253  else {
254  *label = 0;
255  if (sscanf(buff, "%1s", label) != 1)
256  continue;
257  if (*label == '#')
258  continue;
259  *label = 0;
260  /* for fp maps try to read a range of data */
261  if (fp_map
262  && sscanf(buff, "%lf:%lf:%[^\n]", &val1, &val2, label) == 3)
263  Rast_set_cat(&val1, &val2, label, pcats, DCELL_TYPE);
264  else if (!fp_map
265  && sscanf(buff, "%d:%d:%[^\n]", &cat1, &cat2, label) == 3)
266  Rast_set_cat(&cat1, &cat2, label, pcats, CELL_TYPE);
267  else if (sscanf(buff, "%d:%[^\n]", &cat1, label) >= 1)
268  Rast_set_cat(&cat1, &cat1, label, pcats, CELL_TYPE);
269  else if (sscanf(buff, "%lf:%[^\n]", &val1, label) >= 1)
270  Rast_set_cat(&val1, &val1, label, pcats, DCELL_TYPE);
271  else
272  goto error;
273  }
274  }
275 
276  fclose(fd);
277  return 0;
278  error:
279  fclose(fd);
280  return -1;
281 }
282 
283 /*!
284  * \brief Get title from category structure struct
285  *
286  * \todo Remove from GIS Library, replace by Rast_get_c_cats_title().
287  *
288  * Map layers store a one-line title in the category structure as
289  * well. This routine returns a pointer to the title contained in the
290  * <i>cats</i> structure. A legal pointer is always returned. If the
291  * map layer does not have a title, then a pointer to the empty string
292  * "" is returned.
293  *
294  * \param pcats pointer to Categories structure
295  *
296  * \return title
297  * \return "" if missing
298  */
299 char *Rast_get_cats_title(const struct Categories *pcats)
300 {
301  return pcats->title ? pcats->title : "";
302 }
303 
304 /*!
305  * \brief Get a raster category label (CELL)
306  *
307  * This routine looks up category <i>rast</i> in the <i>pcats</i>
308  * structure and returns a pointer to a string which is the label for
309  * the category. A legal pointer is always returned. If the category
310  * does not exist in <i>pcats</i>, then a pointer to the empty string
311  * "" is returned.
312  *
313  * <b>Warning:</b> The pointer that is returned points to a hidden
314  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
315  * buffer.
316  *
317  * \param rast cell value
318  * \param pcats pointer to Categories structure
319  *
320  * \return pointer to category label
321  * \return "" if category is not found
322  */
323 char *Rast_get_c_cat(CELL * rast, struct Categories *pcats)
324 {
325  return Rast_get_cat(rast, pcats, CELL_TYPE);
326 }
327 
328 /*!
329  * \brief Get a raster category label (FCELL)
330  *
331  * This routine looks up category <i>rast</i> in the <i>pcats</i>
332  * structure and returns a pointer to a string which is the label for
333  * the category. A legal pointer is always returned. If the category
334  * does not exist in <i>pcats</i>, then a pointer to the empty string
335  * "" is returned.
336  *
337  * <b>Warning:</b> The pointer that is returned points to a hidden
338  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
339  * buffer.
340  *
341  * \param rast cell value
342  * \param pcats pointer to Categories structure
343  *
344  * \return pointer to category label
345  * \return "" if category is not found
346  */
347 char *Rast_get_f_cat(FCELL * rast, struct Categories *pcats)
348 {
349  return Rast_get_cat(rast, pcats, FCELL_TYPE);
350 }
351 
352 /*!
353  * \brief Get a raster category label (DCELL)
354  *
355  * This routine looks up category <i>rast</i> in the <i>pcats</i>
356  * structure and returns a pointer to a string which is the label for
357  * the category. A legal pointer is always returned. If the category
358  * does not exist in <i>pcats</i>, then a pointer to the empty string
359  * "" is returned.
360  *
361  * <b>Warning:</b> The pointer that is returned points to a hidden
362  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
363  * buffer.
364  *
365  * \param rast cell value
366  * \param pcats pointer to Categories structure
367  *
368  * \return pointer to category label
369  * \return "" if category is not found
370  */
371 char *Rast_get_d_cat(DCELL * rast, struct Categories *pcats)
372 {
373  return Rast_get_cat(rast, pcats, DCELL_TYPE);
374 }
375 
376 /*!
377  * \brief Get a raster category label
378  *
379  * This routine looks up category <i>rast</i> in the <i>pcats</i>
380  * structure and returns a pointer to a string which is the label for
381  * the category. A legal pointer is always returned. If the category
382  * does not exist in <i>pcats</i>, then a pointer to the empty string
383  * "" is returned.
384  *
385  * <b>Warning:</b> The pointer that is returned points to a hidden
386  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
387  * buffer.
388  *
389  * \param rast cell value
390  * \param pcats pointer to Categories structure
391  * \param data_type map type (CELL, FCELL, DCELL)
392  *
393  * \return pointer to category label
394  * \return "" if category is not found
395  */
396 char *Rast_get_cat(void *rast,
397  struct Categories *pcats, RASTER_MAP_TYPE data_type)
398 {
399  static char label[1024];
400  char *f, *l, *v;
401  CELL i;
402  DCELL val;
403  float a[2];
404  char fmt[30], value_str[30];
405 
406  if (Rast_is_null_value(rast, data_type)) {
407  sprintf(label, "no data");
408  return label;
409  }
410 
411  /* first search the list of labels */
412  *label = 0;
413  val = Rast_get_d_value(rast, data_type);
414  i = Rast_quant_get_cell_value(&pcats->q, val);
415 
416  G_debug(5, "Rast_get_cat(): val %lf found i %d", val, i);
417 
418  if (!Rast_is_c_null_value(&i) && i < pcats->ncats) {
419  if (pcats->labels[i] != NULL)
420  return pcats->labels[i];
421  return label;
422  }
423 
424  /* generate the label */
425  if ((f = pcats->fmt) == NULL)
426  return label;
427 
428  a[0] = (float)val *pcats->m1 + pcats->a1;
429  a[1] = (float)val *pcats->m2 + pcats->a2;
430 
431  l = label;
432  while (*f) {
433  if (*f == '$') {
434  f++;
435  if (*f == '$')
436  *l++ = *f++;
437  else if (*f == '?') {
438  f++;
439  get_cond(&f, v = value_str, val);
440  while (*v)
441  *l++ = *v++;
442  }
443  else if (get_fmt(&f, fmt, &i)) {
444  sprintf(v = value_str, fmt, a[i]);
445  while (*v)
446  *l++ = *v++;
447  }
448  else
449  *l++ = '$';
450  }
451  else {
452  *l++ = *f++;
453  }
454  }
455  *l = 0;
456  return label;
457 }
458 
459 /*!
460  * \brief Sets marks for all categories to 0.
461  *
462  * This initializes Categories structure for subsequent calls to
463  * Rast_mark_cats() for each row of data, where non-zero mark for
464  * i-th label means that some of the cells in rast_row are labeled
465  * with i-th label and fall into i-th data range. These marks help
466  * determine from the Categories structure which labels were used and
467  * which weren't.
468  *
469  * \param pcats pointer to Categories structure
470  */
471 void Rast_unmark_cats(struct Categories *pcats)
472 {
473  int i;
474 
475  for (i = 0; i < pcats->ncats; i++)
476  pcats->marks[i] = 0;
477 }
478 
479 /*!
480  * \brief Looks up the category label for each raster value (CELL).
481  *
482  * Looks up the category label for each raster value in the
483  * <i>rast_row</i> and updates the marks for labels found.
484  *
485  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
486  * raster cells read so far which are labeled with i-th label and fall
487  * into i-th data range.
488  *
489  * \param rast_row raster row to update stats
490  * \param ncols number of columns
491  * \param pcats pointer to Categories structure
492  *
493  */
494 void Rast_mark_c_cats(const CELL * rast_row,
495  int ncols, struct Categories *pcats)
496 {
497  Rast_mark_cats(rast_row, ncols, pcats, CELL_TYPE);
498 }
499 
500 /*!
501  * \brief Looks up the category label for each raster value (FCELL).
502  *
503  * Looks up the category label for each raster value in the
504  * <i>rast_row</i> and updates the marks for labels found.
505  *
506  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
507  * raster cells read so far which are labeled with i-th label and fall
508  * into i-th data range.
509  *
510  * \param rast_row raster row to update stats
511  * \param ncols number of columns
512  * \param pcats pointer to Categories structure
513  *
514  */
515 void Rast_mark_f_cats(const FCELL * rast_row,
516  int ncols, struct Categories *pcats)
517 {
518  Rast_mark_cats(rast_row, ncols, pcats, FCELL_TYPE);
519 }
520 
521 /*!
522  * \brief Looks up the category label for each raster value (DCELL).
523  *
524  * Looks up the category label for each raster value in the
525  * <i>rast_row</i> and updates the marks for labels found.
526  *
527  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
528  * raster cells read so far which are labeled with i-th label and fall
529  * into i-th data range.
530  *
531  * \param rast_row raster row to update stats
532  * \param ncols number of columns
533  * \param pcats pointer to Categories structure
534  *
535  */
536 void Rast_mark_d_cats(const DCELL * rast_row,
537  int ncols, struct Categories *pcats)
538 {
539  Rast_mark_cats(rast_row, ncols, pcats, DCELL_TYPE);
540 }
541 
542 /*!
543  * \brief Looks up the category label for each raster value (DCELL).
544  *
545  * Looks up the category label for each raster value in the
546  * <i>rast_row</i> and updates the marks for labels found.
547  *
548  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
549  * raster cells read so far which are labeled with i-th label and fall
550  * into i-th data range.
551  *
552  * \param rast_row raster row to update stats
553  * \param ncols number of columns
554  * \param pcats pointer to Categories structure
555  * \param data_type map type
556  *
557  * \return -1 on error
558  * \return 1 on success
559  */
560 int Rast_mark_cats(const void *rast_row,
561  int ncols, struct Categories *pcats,
562  RASTER_MAP_TYPE data_type)
563 {
564  size_t size = Rast_cell_size(data_type);
565  CELL i;
566 
567  while (ncols-- > 0) {
568  i = Rast_quant_get_cell_value(&pcats->q,
569  Rast_get_d_value(rast_row, data_type));
570  if (Rast_is_c_null_value(&i))
571  continue;
572  if (i > pcats->ncats)
573  return -1;
574  pcats->marks[i]++;
575  rast_row = G_incr_void_ptr(rast_row, size);
576  }
577  return 1;
578 }
579 
580 /*!
581  * \brief Rewind raster categories
582  *
583  * After call to this function Rast_get_next_marked_cat() returns
584  * the first marked cat label.
585  *
586  * \param pcats pointer to Categories structure
587  */
588 void Rast_rewind_cats(struct Categories *pcats)
589 {
590  pcats->last_marked_rule = -1;
591 }
592 
593 /*!
594  \brief Get next marked raster categories (DCELL)
595 
596  \param pcats pointer to Categories structure
597  \param rast1, rast2 cell values (raster range)
598  \param[out] count count
599 
600  \return NULL if not found
601  \return description if found
602  */
604  DCELL * rast1, DCELL * rast2, long *count)
605 {
606  char *descr = NULL;
607  int found, i;
608 
609  found = 0;
610  /* pcats->ncats should be == Rast_quant_nof_rules(&pcats->q) */
611 
612  G_debug(3, "last marked %d nrules %d\n", pcats->last_marked_rule,
613  Rast_quant_nof_rules(&pcats->q));
614 
615  for (i = pcats->last_marked_rule + 1; i < Rast_quant_nof_rules(&pcats->q);
616  i++) {
617  descr = Rast_get_ith_d_cat(pcats, i, rast1, rast2);
618  G_debug(5, "%d %d", i, pcats->marks[i]);
619  if (pcats->marks[i]) {
620  found = 1;
621  break;
622  }
623  }
624 
625  if (!found)
626  return NULL;
627 
628  *count = pcats->marks[i];
629  pcats->last_marked_rule = i;
630  return descr;
631 }
632 
633 /*!
634  \brief Get next marked raster categories (CELL)
635 
636  \param pcats pointer to Categories structure
637  \param rast1, rast2 cell values (raster range)
638  \param[out] count count
639 
640  \return NULL if not found
641  \return description if found
642  */
644  CELL * rast1, CELL * rast2, long *count)
645 {
646  return Rast_get_next_marked_cat(pcats, rast1, rast2, count, CELL_TYPE);
647 }
648 
649 /*!
650  \brief Get next marked raster categories (FCELL)
651 
652  \param pcats pointer to Categories structure
653  \param rast1, rast2 cell values (raster range)
654  \param[out] count count
655 
656  \return NULL if not found
657  \return description if found
658  */
660  FCELL * rast1, FCELL * rast2, long *count)
661 {
662  return Rast_get_next_marked_cat(pcats, rast1, rast2, count, FCELL_TYPE);
663 }
664 
665 /*!
666  \brief Get next marked raster categories
667 
668  \param pcats pointer to Categories structure
669  \param rast1, rast2 cell values (raster range)
670  \param[out] count count
671  \param data_type map type
672 
673  \return NULL if not found
674  \return description if found
675  */
677  void *rast1, void *rast2,
678  long *count, RASTER_MAP_TYPE data_type)
679 {
680  DCELL val1, val2;
681  char *lab;
682 
683  lab = Rast_get_next_marked_d_cat(pcats, &val1, &val2, count);
684  Rast_set_d_value(rast1, val1, data_type);
685  Rast_set_d_value(rast2, val2, data_type);
686  return lab;
687 }
688 
689 static int get_fmt(char **f, char *fmt, int *i)
690 {
691  char *ff;
692 
693  ff = *f;
694  if (*ff == 0)
695  return 0;
696  if (*ff == '$') {
697  *f = ff + 1;
698  return 0;
699  }
700  switch (*ff++) {
701  case '1':
702  *i = 0;
703  break;
704  case '2':
705  *i = 1;
706  break;
707  default:
708  return 0;
709  }
710  *fmt++ = '%';
711  *fmt++ = '.';
712  if (*ff++ != '.') {
713  *f = ff - 1;
714  *fmt++ = '0';
715  *fmt++ = 'f';
716  *fmt = 0;
717  return 1;
718  }
719  *fmt = '0';
720  while (*ff >= '0' && *ff <= '9')
721  *fmt++ = *ff++;
722  *fmt++ = 'f';
723  *fmt = 0;
724  *f = ff;
725  return 1;
726 }
727 
728 static void get_cond(char **f, char *value, DCELL val)
729 {
730  char *ff;
731 
732  ff = *f;
733  if (val == 1.) {
734  while (*ff)
735  if (*ff++ == '$')
736  break;
737  }
738 
739  while (*ff)
740  if (*ff == '$') {
741  ff++;
742  break;
743  }
744  else
745  *value++ = *ff++;
746 
747  if (val != 1.) {
748  while (*ff)
749  if (*ff++ == '$')
750  break;
751  }
752  *value = 0;
753  *f = ff;
754 }
755 
756 /*!
757  * \brief Set a raster category label (CELL)
758  *
759  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
760  * category structure <i>pcats</i>.
761  *
762  * \param rast1, rast2 raster values (range)
763  * \param label category label
764  * \param pcats pointer to Categories structure
765  *
766  * \return -1 on error
767  * \return 0 if null value detected
768  * \return 1 on success
769  */
770 int Rast_set_c_cat(const CELL * rast1, const CELL * rast2,
771  const char *label, struct Categories *pcats)
772 {
773  return Rast_set_cat(rast1, rast2, label, pcats, CELL_TYPE);
774 }
775 
776 /*!
777  * \brief Set a raster category label (FCELL)
778  *
779  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
780  * category structure <i>pcats</i>.
781  *
782  * \param rast1, rast2 raster values (range)
783  * \param label category label
784  * \param pcats pointer to Categories structure
785  *
786  * \return
787  */
788 int Rast_set_f_cat(const FCELL * rast1, const FCELL * rast2,
789  const char *label, struct Categories *pcats)
790 {
791  return Rast_set_cat(rast1, rast2, label, pcats, FCELL_TYPE);
792 }
793 
794 /*!
795  * \brief Set a raster category label (DCELL)
796  *
797  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
798  * category structure <i>pcats</i>.
799  *
800  * \param rast1, rast2 raster values (range)
801  * \param label category label
802  * \param pcats pointer to Categories structure
803  *
804  * \return -1 on error
805  * \return 0 if null value detected
806  * \return 1 on success
807  */
808 int Rast_set_d_cat(const DCELL * rast1, const DCELL * rast2,
809  const char *label, struct Categories *pcats)
810 {
811  long len;
812  DCELL dtmp1, dtmp2;
813  int i;
814  char *descr;
815 
816  /* DEBUG fprintf(stderr,"Rast_set_d_cat(rast1 = %p,rast2 = %p,label = '%s',pcats = %p)\n",
817  rast1,rast2,label,pcats); */
818  if (Rast_is_d_null_value(rast1))
819  return 0;
820  if (Rast_is_d_null_value(rast2))
821  return 0;
822  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): adding quant rule: %f %f %d %d\n", *rast1, *rast2, pcats->ncats, pcats->ncats); */
823  /* the set_cat() functions are used in many places to reset the labels
824  for the range (or cat) with existing label. In this case we don't
825  want to store both rules with identical range even though the result
826  of get_cat() will be correct, since it will use rule added later.
827  we don't want to overuse memory and we don't want rules which are
828  not used to be written out in cats file. So we first look if
829  the label for this range has been sen, and if it has, overwrite it */
830 
831  for (i = 0; i < pcats->ncats; i++) {
832  descr = Rast_get_ith_d_cat(pcats, i, &dtmp1, &dtmp2);
833  if ((dtmp1 == *rast1 && dtmp2 == *rast2)
834  || (dtmp1 == *rast2 && dtmp2 == *rast1)) {
835  if (pcats->labels[i] != NULL)
836  G_free(pcats->labels[i]);
837  pcats->labels[i] = G_store(label);
838  G_newlines_to_spaces(pcats->labels[i]);
839  G_strip(pcats->labels[i]);
840  return 1;
841  }
842  }
843  /* when rule for this range does not exist */
844  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): New rule: adding %d %p\n", i, pcats->labels); */
845  Rast_quant_add_rule(&pcats->q, *rast1, *rast2, pcats->ncats,
846  pcats->ncats);
847  pcats->ncats++;
848  if (pcats->nalloc < pcats->ncats) {
849  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): need more space nalloc = %d ncats = %d\n", pcats->nalloc,pcats->ncats); */
850  len = (pcats->nalloc + 256) * sizeof(char *);
851  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): allocating %d labels(%d)\n", pcats->nalloc + 256,(int)len); */
852  if (len != (int)len) { /* make sure len doesn't overflow int */
853  pcats->ncats--;
854  return -1;
855  }
856  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): pcats->nalloc = %d, pcats->labels = (%p), len = %d\n",pcats->nalloc,pcats->labels,(int)len); */
857  if (pcats->nalloc) {
858  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): Realloc-ing pcats->labels (%p)\n",pcats->labels); */
859  pcats->labels =
860  (char **)G_realloc((char *)pcats->labels, (int)len);
861  }
862  else {
863  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): alloc-ing new labels pointer array\n"); */
864  pcats->labels = (char **)G_malloc((int)len);
865  }
866  /* fflush(stderr); */
867  /* DEBUG fprintf (stderr, "Rast_set_d_cats(): allocating %d marks(%d)\n", pcats->nalloc + 256,(int)len); */
868  len = (pcats->nalloc + 256) * sizeof(int);
869  if (len != (int)len) { /* make sure len doesn't overflow int */
870  pcats->ncats--;
871  return -1;
872  }
873  if (pcats->nalloc)
874  pcats->marks = (int *)G_realloc((char *)pcats->marks, (int)len);
875  else
876  pcats->marks = (int *)G_malloc((int)len);
877  pcats->nalloc += 256;
878  }
879  /* DEBUG fprintf(stderr,"Rast_set_d_cats(): store new label\n"); */
880  pcats->labels[pcats->ncats - 1] = G_store(label);
881  G_newlines_to_spaces(pcats->labels[pcats->ncats - 1]);
882  G_strip(pcats->labels[pcats->ncats - 1]);
883  /* DEBUG
884  fprintf (stderr, "%d %s\n", pcats->ncats - 1, pcats->labels[pcats->ncats - 1]);
885  */
886  /* updates cats.num = max cat values. This is really just used in old
887  raster programs, and I am doing it for backwards cmpatibility (Olga) */
888  if ((CELL) * rast1 > pcats->num)
889  pcats->num = (CELL) * rast1;
890  if ((CELL) * rast2 > pcats->num)
891  pcats->num = (CELL) * rast2;
892  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): done\n"); */
893  /* DEBUG fflush(stderr); */
894  return 1;
895 }
896 
897 
898 /*!
899  * \brief Set a raster category label
900  *
901  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
902  * category structure <i>pcats</i>.
903  *
904  * \param rast1, rast2 raster values (range)
905  * \param label category label
906  * \param pcats pointer to Categories structure
907  * \param data_type map type
908  *
909  * \return -1 on error
910  * \return 0 if null value detected
911  * \return 1 on success
912  */
913 
914 int Rast_set_cat(const void *rast1, const void *rast2,
915  const char *label,
916  struct Categories *pcats, RASTER_MAP_TYPE data_type)
917 {
918  DCELL val1, val2;
919 
920  val1 = Rast_get_d_value(rast1, data_type);
921  val2 = Rast_get_d_value(rast2, data_type);
922  return Rast_set_d_cat(&val1, &val2, label, pcats);
923 }
924 
925 /*!
926  * \brief Write raster category file
927  *
928  * \todo To be removed, replaced by Rast_write_cats().
929  *
930  * Writes the category file for the raster map <i>name</i> in the
931  * current mapset from the <i>cats</i> structure.
932  *
933  * \param name map name
934  * \param cats pointer to Categories structure
935  *
936  * \return void
937  */
938 void Rast_write_cats(const char *name, struct Categories *cats)
939 {
940  write_cats("cats", name, cats);
941 }
942 
943 /*!
944  * \brief Write vector category file
945  *
946  * <b>Note:</b> Used for only old vector format!
947  *
948  * \todo Move to the vector library.
949  *
950  * \param name map name
951  * \param cats pointer to Categories structure
952  *
953  * \return void
954  */
955 void Rast_write_vector_cats(const char *name, struct Categories *cats)
956 {
957  write_cats("dig_cats", name, cats);
958 }
959 
960 static void write_cats(const char *element, const char *name,
961  struct Categories *cats)
962 {
963  FILE *fd;
964  int i, fp_map;
965  char *descr;
966  DCELL val1, val2;
967  char str1[100], str2[100];
968 
969  fd = G_fopen_new(element, name);
970  if (!fd)
971  G_fatal_error(_("Unable to open %s file for map <%s>"), element, name);
972 
973  /* write # cats - note # indicate 3.0 or later */
974  fprintf(fd, "# %ld categories\n", (long)cats->num);
975 
976  /* title */
977  fprintf(fd, "%s\n", cats->title != NULL ? cats->title : "");
978 
979  /* write format and coefficients */
980  fprintf(fd, "%s\n", cats->fmt != NULL ? cats->fmt : "");
981  fprintf(fd, "%.2f %.2f %.2f %.2f\n",
982  cats->m1, cats->a1, cats->m2, cats->a2);
983 
984  /* if the map is integer or if this is a vector map, sort labels */
985  if (strncmp(element, "dig", 3) == 0)
986  fp_map = 0;
987  else
988  fp_map = Rast_map_is_fp(name, G_mapset());
989  if (!fp_map)
990  Rast_sort_cats(cats);
991 
992  /* write the cat numbers:label */
993  for (i = 0; i < Rast_quant_nof_rules(&cats->q); i++) {
994  descr = Rast_get_ith_d_cat(cats, i, &val1, &val2);
995  if ((cats->fmt && cats->fmt[0])
996  || (descr && descr[0])) {
997  if (val1 == val2) {
998  sprintf(str1, "%.10f", val1);
999  G_trim_decimal(str1);
1000  fprintf(fd, "%s:%s\n", str1, descr != NULL ? descr : "");
1001  }
1002  else {
1003  sprintf(str1, "%.10f", val1);
1004  G_trim_decimal(str1);
1005  sprintf(str2, "%.10f", val2);
1006  G_trim_decimal(str2);
1007  fprintf(fd, "%s:%s:%s\n", str1, str2,
1008  descr != NULL ? descr : "");
1009  }
1010  }
1011  }
1012  fclose(fd);
1013 }
1014 
1015 /*!
1016  * \brief Get category description (DCELL)
1017  *
1018  * Returns i-th description and i-th data range from the list of
1019  * category descriptions with corresponding data ranges. end points of
1020  * data interval in <i>rast1</i> and <i>rast2</i>.
1021  *
1022  * \param pcats pointer to Categories structure
1023  * \param i index
1024  * \param rast1, rast2 raster values (range)
1025  *
1026  * \return "" on error
1027  * \return pointer to category description
1028  */
1029 char *Rast_get_ith_d_cat(const struct Categories *pcats,
1030  int i, DCELL * rast1, DCELL * rast2)
1031 {
1032  int index;
1033 
1034  if (i > pcats->ncats) {
1035  Rast_set_d_null_value(rast1, 1);
1036  Rast_set_d_null_value(rast2, 1);
1037  return "";
1038  }
1039  Rast_quant_get_ith_rule(&pcats->q, i, rast1, rast2, &index, &index);
1040  return pcats->labels[index];
1041 }
1042 
1043 /*!
1044  * \brief Get category description (FCELL)
1045  *
1046  * Returns i-th description and i-th data range from the list of
1047  * category descriptions with corresponding data ranges. end points of
1048  * data interval in <i>rast1</i> and <i>rast2</i>.
1049  *
1050  * \param pcats pointer to Categories structure
1051  * \param i index
1052  * \param rast1, rast2 raster values (range)
1053  *
1054  * \return "" on error
1055  * \return pointer to category description
1056  */
1057 char *Rast_get_ith_f_cat(const struct Categories *pcats,
1058  int i, void *rast1, void *rast2)
1059 {
1060  RASTER_MAP_TYPE data_type = FCELL_TYPE;
1061  char *tmp;
1062  DCELL val1, val2;
1063 
1064  tmp = Rast_get_ith_d_cat(pcats, i, &val1, &val2);
1065  Rast_set_d_value(rast1, val1, data_type);
1066  Rast_set_d_value(rast2, val2, data_type);
1067  return tmp;
1068 }
1069 
1070 /*!
1071  * \brief Get category description (CELL)
1072  *
1073  * Returns i-th description and i-th data range from the list of
1074  * category descriptions with corresponding data ranges. end points of
1075  * data interval in <i>rast1</i> and <i>rast2</i>.
1076  *
1077  * \param pcats pointer to Categories structure
1078  * \param i index
1079  * \param rast1, rast2 raster values (range)
1080  *
1081  * \return "" on error
1082  * \return pointer to category description
1083  */
1084 char *Rast_get_ith_c_cat(const struct Categories *pcats,
1085  int i, void *rast1, void *rast2)
1086 {
1087  RASTER_MAP_TYPE data_type = CELL_TYPE;
1088  char *tmp;
1089  DCELL val1, val2;
1090 
1091  tmp = Rast_get_ith_d_cat(pcats, i, &val1, &val2);
1092  Rast_set_d_value(rast1, val1, data_type);
1093  Rast_set_d_value(rast2, val2, data_type);
1094  return tmp;
1095 }
1096 
1097 /*!
1098  * \brief Get category description
1099  *
1100  * Returns i-th description and i-th data range from the list of
1101  * category descriptions with corresponding data ranges. end points of
1102  * data interval in <i>rast1</i> and <i>rast2</i>.
1103  *
1104  * \param pcats pointer to Categories structure
1105  * \param i index
1106  * \param rast1, rast2 raster values (range)
1107  * \param data_type map type
1108  *
1109  * \return "" on error
1110  * \return pointer to category description
1111  */
1112 char *Rast_get_ith_cat(const struct Categories *pcats, int i, void *rast1,
1113  void *rast2, RASTER_MAP_TYPE data_type)
1114 {
1115  char *tmp;
1116  DCELL val1, val2;
1117 
1118  tmp = Rast_get_ith_d_cat(pcats, i, &val1, &val2);
1119  Rast_set_d_value(rast1, val1, data_type);
1120  Rast_set_d_value(rast2, val2, data_type);
1121  return tmp;
1122 }
1123 
1124 /*!
1125  * \brief Initialize category structure
1126  *
1127  * To construct a new category file, the structure must first be
1128  * initialized. This routine initializes the <i>cats</i> structure,
1129  * and copies the <i>title</i> into the structure. The number of
1130  * categories is set initially to <i>n</i>.
1131  *
1132  * For example:
1133  \code
1134  struct Categories cats;
1135  Rast_init_cats ("", &cats);
1136  \endcode
1137  *
1138  * \todo Eliminate pcats->num. Num has no meaning in new Categories
1139  * structure and only stores (int) largets data value for backwards
1140  * compatibility.
1141  *
1142  * \param title title
1143  * \param pcats pointer to Categories structure
1144  */
1145 void Rast_init_cats(const char *title, struct Categories *pcats)
1146 {
1147  Rast_set_cats_title(title, pcats);
1148  pcats->labels = NULL;
1149  pcats->nalloc = 0;
1150  pcats->ncats = 0;
1151  pcats->num = 0;
1152  pcats->fmt = NULL;
1153  pcats->m1 = 0.0;
1154  pcats->a1 = 0.0;
1155  pcats->m2 = 0.0;
1156  pcats->a2 = 0.0;
1157  pcats->last_marked_rule = -1;
1158  Rast_quant_init(&pcats->q);
1159 }
1160 
1161 /*!
1162  * \brief Set title in category structure
1163  *
1164  * \todo To be removed, replaced by Rast_set_cats_title().
1165  *
1166  * The <i>title</i> is copied into the <i>pcats</i> structure.
1167  *
1168  * \param title title
1169  * \param pcats pointer to Categories structure
1170  */
1171 void Rast_set_cats_title(const char *title, struct Categories *pcats)
1172 {
1173  if (title == NULL)
1174  title = "";
1175  pcats->title = G_store(title);
1176  G_newlines_to_spaces(pcats->title);
1177  G_strip(pcats->title);
1178 }
1179 
1180 /*!
1181  \brief Set category fmt (?)
1182 
1183  \param fmt
1184  \param m1
1185  \param a1
1186  \param m2
1187  \param a2
1188  \param pcats pointer to Categories structure
1189  */
1190 void Rast_set_cats_fmt(const char *fmt, double m1, double a1, double m2,
1191  double a2, struct Categories *pcats)
1192 {
1193  pcats->m1 = m1;
1194  pcats->a1 = a1;
1195  pcats->m2 = m2;
1196  pcats->a2 = a2;
1197 
1198  pcats->fmt = G_store(fmt);
1199  G_newlines_to_spaces(pcats->fmt);
1200  G_strip(pcats->fmt);
1201 }
1202 
1203 /*!
1204  * \brief Free category structure memory
1205  *
1206  * \todo To be removed, replaced by Rast_free_cats().
1207  *
1208  * Frees memory allocated by Rast_read_cats(), Rast_init_cats() and
1209  * Rast_set_c_cat().
1210  *
1211  * \param pcats pointer to Categories structure
1212  */
1213 void Rast_free_cats(struct Categories *pcats)
1214 {
1215  int i;
1216 
1217  if (pcats->title != NULL) {
1218  G_free(pcats->title);
1219  pcats->title = NULL;
1220  }
1221  if (pcats->fmt != NULL) {
1222  G_free(pcats->fmt);
1223  pcats->fmt = NULL;
1224  }
1225  if (pcats->ncats > 0) {
1226  for (i = 0; i < pcats->ncats; i++)
1227  if (pcats->labels[i] != NULL)
1228  G_free(pcats->labels[i]);
1229  G_free(pcats->labels);
1230  G_free(pcats->marks);
1231  pcats->labels = NULL;
1232  }
1233  Rast_quant_free(&pcats->q);
1234  pcats->ncats = 0;
1235  pcats->nalloc = 0;
1236 }
1237 
1238 /*!
1239  * \brief Copy raster categories
1240  *
1241  * Allocates NEW space for quant rules and labels n <i>pcats_to</i>
1242  * and copies all info from <i>pcats_from</i> cats to
1243  * <i>pcats_to</i> cats.
1244  *
1245  * \param pcats_to pointer to destination Categories structure
1246  * \param pcats_from pointer to source Categories structure
1247  */
1248 void Rast_copy_cats(struct Categories *pcats_to,
1249  const struct Categories *pcats_from)
1250 {
1251  int i;
1252  char *descr;
1253  DCELL d1, d2;
1254 
1255  Rast_init_cats(pcats_from->title, pcats_to);
1256  for (i = 0; i < pcats_from->ncats; i++) {
1257  descr = Rast_get_ith_d_cat(pcats_from, i, &d1, &d2);
1258  Rast_set_d_cat(&d1, &d2, descr, pcats_to);
1259  }
1260 }
1261 
1262 /*!
1263  \brief Get number of raster categories
1264 
1265  \param pcats pointer to Categories structure
1266 
1267  \return number of categories
1268  */
1270 {
1271  return pcats->ncats;
1272 }
1273 
1274 /*!
1275  \brief Sort categories
1276 
1277  \param pcats pointer to Categories structure
1278 
1279  \return -1 on error (nothing to sort)
1280  \return 0 on success
1281  */
1282 int Rast_sort_cats(struct Categories *pcats)
1283 {
1284  int *indexes, i, ncats;
1285  char *descr;
1286  DCELL d1, d2;
1287 
1288  if (pcats->ncats <= 1)
1289  return -1;
1290 
1291  ncats = pcats->ncats;
1292  G_debug(3, "Rast_sort_cats(): Copying to save cats buffer");
1293  Rast_copy_cats(&save_cats, pcats);
1294  Rast_free_cats(pcats);
1295 
1296  indexes = (int *)G_malloc(sizeof(int) * ncats);
1297  for (i = 0; i < ncats; i++)
1298  indexes[i] = i;
1299 
1300  qsort(indexes, ncats, sizeof(int), cmp);
1301  Rast_init_cats(save_cats.title, pcats);
1302  for (i = 0; i < ncats; i++) {
1303  descr = Rast_get_ith_d_cat(&save_cats, indexes[i], &d1, &d2);
1304  G_debug(4, " Write sorted cats, pcats = %p pcats->labels = %p",
1305  (void *)pcats, (void *)pcats->labels);
1306  Rast_set_d_cat(&d1, &d2, descr, pcats);
1307  }
1308  Rast_free_cats(&save_cats);
1309 
1310  return 0;
1311 }
1312 
1313 static int cmp(const void *aa, const void *bb)
1314 {
1315  const int *a = aa, *b = bb;
1316  DCELL min_rast1, min_rast2, max_rast1, max_rast2;
1317  CELL index;
1318 
1319  Rast_quant_get_ith_rule(&(save_cats.q), *a,
1320  &min_rast1, &max_rast1, &index, &index);
1321  Rast_quant_get_ith_rule(&(save_cats.q), *b,
1322  &min_rast2, &max_rast2, &index, &index);
1323  if (min_rast1 < min_rast2)
1324  return -1;
1325  if (min_rast1 > min_rast2)
1326  return 1;
1327  return 0;
1328 }
#define CELL_TYPE
Definition: raster.h:11
#define G_malloc(n)
Definition: defs/gis.h:112
CELL Rast_get_max_c_cat(const char *name, const char *mapset)
Get the max category number.
Definition: raster/cats.c:171
int G_getl(char *, int, FILE *)
Gets a line of text from a file.
Definition: getl.c:31
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int Rast_mark_cats(const void *rast_row, int ncols, struct Categories *pcats, RASTER_MAP_TYPE data_type)
Looks up the category label for each raster value (DCELL).
Definition: raster/cats.c:560
float m2
Definition: raster.h:137
float a1
Definition: raster.h:136
DCELL Rast_get_d_value(const void *, RASTER_MAP_TYPE)
Retrieves the value of given type from pointer p (DCELL)
int Rast_read_cats(const char *name, const char *mapset, struct Categories *pcats)
Read raster category file.
Definition: raster/cats.c:104
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:414
Definition: lz4.c:487
#define min(x, y)
Definition: draw2.c:31
char * Rast_get_ith_f_cat(const struct Categories *pcats, int i, void *rast1, void *rast2)
Get category description (FCELL)
Definition: raster/cats.c:1057
char * Rast_get_f_cat(FCELL *rast, struct Categories *pcats)
Get a raster category label (FCELL)
Definition: raster/cats.c:347
void Rast_mark_c_cats(const CELL *rast_row, int ncols, struct Categories *pcats)
Looks up the category label for each raster value (CELL).
Definition: raster/cats.c:494
double DCELL
Definition: gis.h:614
int * marks
Definition: raster.h:142
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
int count
int Rast_read_vector_cats(const char *name, const char *mapset, struct Categories *pcats)
Read vector category file.
Definition: raster/cats.c:140
#define G_incr_void_ptr(ptr, size)
Definition: defs/gis.h:100
char * Rast_get_c_cat(CELL *rast, struct Categories *pcats)
Get a raster category label (CELL)
Definition: raster/cats.c:323
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
char * Rast_get_d_cat(DCELL *rast, struct Categories *pcats)
Get a raster category label (DCELL)
Definition: raster/cats.c:371
void Rast_mark_f_cats(const FCELL *rast_row, int ncols, struct Categories *pcats)
Looks up the category label for each raster value (FCELL).
Definition: raster/cats.c:515
int Rast_set_c_cat(const CELL *rast1, const CELL *rast2, const char *label, struct Categories *pcats)
Set a raster category label (CELL)
Definition: raster/cats.c:770
void Rast_set_cats_fmt(const char *fmt, double m1, double a1, double m2, double a2, struct Categories *pcats)
Set category fmt (?)
Definition: raster/cats.c:1190
#define NULL
Definition: ccmath.h:32
#define max(x, y)
Definition: draw2.c:32
int Rast_number_of_cats(struct Categories *pcats)
Get number of raster categories.
Definition: raster/cats.c:1269
void Rast_quant_init(struct Quant *)
Initialize the structure.
Definition: quant.c:174
int Rast_quant_nof_rules(const struct Quant *)
Returns the number of quantization rules defined.
Definition: quant.c:310
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
Definition: range.c:160
void Rast_quant_free(struct Quant *)
Resets and frees allocated memory.
Definition: quant.c:55
Definition: lidar.h:86
int Rast_set_f_cat(const FCELL *rast1, const FCELL *rast2, const char *label, struct Categories *pcats)
Set a raster category label (FCELL)
Definition: raster/cats.c:788
char * Rast_get_next_marked_f_cat(struct Categories *pcats, FCELL *rast1, FCELL *rast2, long *count)
Get next marked raster categories (FCELL)
Definition: raster/cats.c:659
double l
Definition: r_raster.c:39
CELL Rast_quant_get_cell_value(struct Quant *, DCELL)
Returns a CELL category for the floating-point value based on the quantization rules in q...
Definition: quant.c:596
#define DCELL_TYPE
Definition: raster.h:13
char * Rast_get_cat(void *rast, struct Categories *pcats, RASTER_MAP_TYPE data_type)
Get a raster category label.
Definition: raster/cats.c:396
void Rast_rewind_cats(struct Categories *pcats)
Rewind raster categories.
Definition: raster/cats.c:588
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition: gis/open.c:220
char * Rast_get_ith_d_cat(const struct Categories *pcats, int i, DCELL *rast1, DCELL *rast2)
Get category description (DCELL)
Definition: raster/cats.c:1029
void Rast_init_cats(const char *title, struct Categories *pcats)
Initialize category structure.
Definition: raster/cats.c:1145
double b
Definition: r_raster.c:39
CELL num
Definition: raster.h:130
char * Rast_get_ith_cat(const struct Categories *pcats, int i, void *rast1, void *rast2, RASTER_MAP_TYPE data_type)
Get category description.
Definition: raster/cats.c:1112
size_t Rast_cell_size(RASTER_MAP_TYPE)
Returns size of a raster cell in bytes.
Definition: alloc_cell.c:39
struct field_info * ff
char * title
Definition: raster.h:133
char * fmt
Definition: raster.h:134
char * Rast_get_next_marked_cat(struct Categories *pcats, void *rast1, void *rast2, long *count, RASTER_MAP_TYPE data_type)
Get next marked raster categories.
Definition: raster/cats.c:676
char * Rast_get_cats_title(const struct Categories *pcats)
Get title from category structure struct.
Definition: raster/cats.c:299
char * Rast_get_next_marked_c_cat(struct Categories *pcats, CELL *rast1, CELL *rast2, long *count)
Get next marked raster categories (CELL)
Definition: raster/cats.c:643
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition: gis/open.c:253
Definition: raster.h:225
float FCELL
Definition: gis.h:615
CELL ncats
Definition: raster.h:129
int Rast_set_d_cat(const DCELL *rast1, const DCELL *rast2, const char *label, struct Categories *pcats)
Set a raster category label (DCELL)
Definition: raster/cats.c:808
void Rast_set_d_value(void *, DCELL, RASTER_MAP_TYPE)
Places a DCELL raster value.
void Rast_copy_cats(struct Categories *pcats_to, const struct Categories *pcats_from)
Copy raster categories.
Definition: raster/cats.c:1248
float m1
Definition: raster.h:135
char ** labels
Definition: raster.h:141
int last_marked_rule
Definition: raster.h:144
void Rast_quant_add_rule(struct Quant *, DCELL, DCELL, CELL, CELL)
Adds a new rule to the set of quantization rules.
Definition: quant.c:473
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
void Rast_quant_get_ith_rule(const struct Quant *, int, DCELL *, DCELL *, CELL *, CELL *)
Returns the i&#39;th quantization rule.
Definition: quant.c:328
void G_warning(const char *,...) __attribute__((format(printf
int CELL
Definition: gis.h:613
char * Rast_get_next_marked_d_cat(struct Categories *pcats, DCELL *rast1, DCELL *rast2, long *count)
Get next marked raster categories (DCELL)
Definition: raster/cats.c:603
#define G_realloc(p, n)
Definition: defs/gis.h:114
#define _(str)
Definition: glocale.h:10
int RASTER_MAP_TYPE
Definition: raster.h:25
#define FCELL_TYPE
Definition: raster.h:12
void Rast_unmark_cats(struct Categories *pcats)
Sets marks for all categories to 0.
Definition: raster/cats.c:471
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
void Rast_write_vector_cats(const char *name, struct Categories *cats)
Write vector category file.
Definition: raster/cats.c:955
char * Rast_get_ith_c_cat(const struct Categories *pcats, int i, void *rast1, void *rast2)
Get category description (CELL)
Definition: raster/cats.c:1084
const char * name
Definition: named_colr.c:7
void Rast_mark_d_cats(const DCELL *rast_row, int ncols, struct Categories *pcats)
Looks up the category label for each raster value (DCELL).
Definition: raster/cats.c:536
int Rast_set_cat(const void *rast1, const void *rast2, const char *label, struct Categories *pcats, RASTER_MAP_TYPE data_type)
Set a raster category label.
Definition: raster/cats.c:914
int nalloc
Definition: raster.h:143
void Rast_write_cats(const char *name, struct Categories *cats)
Write raster category file.
Definition: raster/cats.c:938
void Rast_set_cats_title(const char *title, struct Categories *pcats)
Set title in category structure.
Definition: raster/cats.c:1171
#define Rast_is_c_null_value(cellVal)
Definition: defs/raster.h:410
int G_debug(int, const char *,...) __attribute__((format(printf
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition: null_val.c:155
float a2
Definition: raster.h:138
struct Quant q
Definition: raster.h:139
int Rast_map_is_fp(const char *, const char *)
Check if raster map is floating-point.
Definition: raster/open.c:847
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
Definition: range.c:714
int Rast_is_null_value(const void *, RASTER_MAP_TYPE)
To check if a raster value is set to NULL.
Definition: null_val.c:179
void Rast_free_cats(struct Categories *pcats)
Free category structure memory.
Definition: raster/cats.c:1213
int Rast_sort_cats(struct Categories *pcats)
Sort categories.
Definition: raster/cats.c:1282
void G_trim_decimal(char *)
Removes trailing zeros from decimal number.
Definition: trim_dec.c:24
void G_newlines_to_spaces(char *)
Definition: nl_to_spaces.c:3