GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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, const char *mapset,
85  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, const char *mapset,
105  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, const char *mapset,
141  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"), name,
146  mapset);
147  break;
148  case -1:
149  G_warning(_("Category support for vector map <%s@%s> invalid"), name,
150  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);
181  max = 0;
182  return max;
183 }
184 
185 static CELL read_cats(const char *element, const char *name, const char *mapset,
186  struct Categories *pcats, int full)
187 {
188  FILE *fd;
189  char buff[1024];
190  CELL cat1, cat2;
191  DCELL val1, val2;
192  int old = 0, fp_map;
193  long num = -1;
194 
195  if (strncmp(element, "dig", 3) == 0)
196  fp_map = 0;
197  else
198  fp_map = Rast_map_is_fp(name, mapset);
199 
200  if (!(fd = G_fopen_old(element, name, mapset)))
201  return -2;
202 
203  /* Read the number of categories */
204  if (G_getl(buff, sizeof buff, fd) == 0)
205  goto error;
206 
207  if (sscanf(buff, "# %ld", &num) == 1)
208  old = 0;
209  else if (sscanf(buff, "%ld", &num) == 1)
210  old = 1;
211 
212  if (!full) {
213  fclose(fd);
214  if (num < 0)
215  return 0; /* coorect */
216  return (CELL)num;
217  }
218 
219  /* Read the title for the file */
220  if (G_getl(buff, sizeof buff, fd) == 0)
221  goto error;
222  G_strip(buff);
223  /* G_ascii_check(buff) ; */
224 
225  Rast_init_cats(buff, pcats);
226  if (num >= 0)
227  pcats->num = num;
228 
229  if (!old) {
230  char fmt[256];
231  float m1, a1, m2, a2;
232 
233  if (G_getl(fmt, sizeof fmt, fd) == 0)
234  goto error;
235  /* next line contains equation coefficients */
236  if (G_getl(buff, sizeof buff, fd) == 0)
237  goto error;
238  if (sscanf(buff, "%f %f %f %f", &m1, &a1, &m2, &a2) != 4)
239  goto error;
240  Rast_set_cats_fmt(fmt, m1, a1, m2, a2, pcats);
241  }
242 
243  /* Read all category names */
244  for (cat1 = 0;; cat1++) {
245  char label[1024];
246 
247  if (G_getl(buff, sizeof buff, fd) == 0)
248  break;
249  if (old)
250  Rast_set_c_cat(&cat1, &cat1, buff, pcats);
251  else {
252  *label = 0;
253  if (sscanf(buff, "%1s", label) != 1)
254  continue;
255  if (*label == '#')
256  continue;
257  *label = 0;
258  /* for fp maps try to read a range of data */
259  if (fp_map &&
260  sscanf(buff, "%lf:%lf:%[^\n]", &val1, &val2, label) == 3)
261  Rast_set_cat(&val1, &val2, label, pcats, DCELL_TYPE);
262  else if (!fp_map &&
263  sscanf(buff, "%d:%d:%[^\n]", &cat1, &cat2, label) == 3)
264  Rast_set_cat(&cat1, &cat2, label, pcats, CELL_TYPE);
265  else if (sscanf(buff, "%d:%[^\n]", &cat1, label) >= 1)
266  Rast_set_cat(&cat1, &cat1, label, pcats, CELL_TYPE);
267  else if (sscanf(buff, "%lf:%[^\n]", &val1, label) >= 1)
268  Rast_set_cat(&val1, &val1, label, pcats, DCELL_TYPE);
269  else
270  goto error;
271  }
272  }
273 
274  fclose(fd);
275  return 0;
276 error:
277  fclose(fd);
278  return -1;
279 }
280 
281 /*!
282  * \brief Get title from category structure struct
283  *
284  * \todo Remove from GIS Library, replace by Rast_get_c_cats_title().
285  *
286  * Map layers store a one-line title in the category structure as
287  * well. This routine returns a pointer to the title contained in the
288  * <i>cats</i> structure. A legal pointer is always returned. If the
289  * map layer does not have a title, then a pointer to the empty string
290  * "" is returned.
291  *
292  * \param pcats pointer to Categories structure
293  *
294  * \return title
295  * \return "" if missing
296  */
297 char *Rast_get_cats_title(const struct Categories *pcats)
298 {
299  return pcats->title ? pcats->title : "";
300 }
301 
302 /*!
303  * \brief Get a raster category label (CELL)
304  *
305  * This routine looks up category <i>rast</i> in the <i>pcats</i>
306  * structure and returns a pointer to a string which is the label for
307  * the category. A legal pointer is always returned. If the category
308  * does not exist in <i>pcats</i>, then a pointer to the empty string
309  * "" is returned.
310  *
311  * <b>Warning:</b> The pointer that is returned points to a hidden
312  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
313  * buffer.
314  *
315  * \param rast cell value
316  * \param pcats pointer to Categories structure
317  *
318  * \return pointer to category label
319  * \return "" if category is not found
320  */
321 char *Rast_get_c_cat(CELL *rast, struct Categories *pcats)
322 {
323  return Rast_get_cat(rast, pcats, CELL_TYPE);
324 }
325 
326 /*!
327  * \brief Get a raster category label (FCELL)
328  *
329  * This routine looks up category <i>rast</i> in the <i>pcats</i>
330  * structure and returns a pointer to a string which is the label for
331  * the category. A legal pointer is always returned. If the category
332  * does not exist in <i>pcats</i>, then a pointer to the empty string
333  * "" is returned.
334  *
335  * <b>Warning:</b> The pointer that is returned points to a hidden
336  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
337  * buffer.
338  *
339  * \param rast cell value
340  * \param pcats pointer to Categories structure
341  *
342  * \return pointer to category label
343  * \return "" if category is not found
344  */
345 char *Rast_get_f_cat(FCELL *rast, struct Categories *pcats)
346 {
347  return Rast_get_cat(rast, pcats, FCELL_TYPE);
348 }
349 
350 /*!
351  * \brief Get a raster category label (DCELL)
352  *
353  * This routine looks up category <i>rast</i> in the <i>pcats</i>
354  * structure and returns a pointer to a string which is the label for
355  * the category. A legal pointer is always returned. If the category
356  * does not exist in <i>pcats</i>, then a pointer to the empty string
357  * "" is returned.
358  *
359  * <b>Warning:</b> The pointer that is returned points to a hidden
360  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
361  * buffer.
362  *
363  * \param rast cell value
364  * \param pcats pointer to Categories structure
365  *
366  * \return pointer to category label
367  * \return "" if category is not found
368  */
369 char *Rast_get_d_cat(DCELL *rast, struct Categories *pcats)
370 {
371  return Rast_get_cat(rast, pcats, DCELL_TYPE);
372 }
373 
374 /*!
375  * \brief Get a raster category label
376  *
377  * This routine looks up category <i>rast</i> in the <i>pcats</i>
378  * structure and returns a pointer to a string which is the label for
379  * the category. A legal pointer is always returned. If the category
380  * does not exist in <i>pcats</i>, then a pointer to the empty string
381  * "" is returned.
382  *
383  * <b>Warning:</b> The pointer that is returned points to a hidden
384  * static buffer. Successive calls to Rast_get_c_cat() overwrite this
385  * buffer.
386  *
387  * \param rast cell value
388  * \param pcats pointer to Categories structure
389  * \param data_type map type (CELL, FCELL, DCELL)
390  *
391  * \return pointer to category label
392  * \return "" if category is not found
393  */
394 char *Rast_get_cat(void *rast, struct Categories *pcats,
395  RASTER_MAP_TYPE data_type)
396 {
397  static char label[1024];
398  char *f, *l, *v;
399  CELL i;
400  DCELL val;
401  float a[2];
402  char fmt[30], value_str[30];
403 
404  if (Rast_is_null_value(rast, data_type)) {
405  sprintf(label, "no data");
406  return label;
407  }
408 
409  /* first search the list of labels */
410  *label = 0;
411  val = Rast_get_d_value(rast, data_type);
412  i = Rast_quant_get_cell_value(&pcats->q, val);
413 
414  G_debug(5, "Rast_get_cat(): val %lf found i %d", val, i);
415 
416  if (!Rast_is_c_null_value(&i) && i < pcats->ncats) {
417  if (pcats->labels[i] != NULL)
418  return pcats->labels[i];
419  return label;
420  }
421 
422  /* generate the label */
423  if ((f = pcats->fmt) == NULL)
424  return label;
425 
426  a[0] = (float)val * pcats->m1 + pcats->a1;
427  a[1] = (float)val * pcats->m2 + pcats->a2;
428 
429  l = label;
430  while (*f) {
431  if (*f == '$') {
432  f++;
433  if (*f == '$')
434  *l++ = *f++;
435  else if (*f == '?') {
436  f++;
437  get_cond(&f, v = value_str, val);
438  while (*v)
439  *l++ = *v++;
440  }
441  else if (get_fmt(&f, fmt, &i)) {
442  sprintf(v = value_str, fmt, a[i]);
443  while (*v)
444  *l++ = *v++;
445  }
446  else
447  *l++ = '$';
448  }
449  else {
450  *l++ = *f++;
451  }
452  }
453  *l = 0;
454  return label;
455 }
456 
457 /*!
458  * \brief Sets marks for all categories to 0.
459  *
460  * This initializes Categories structure for subsequent calls to
461  * Rast_mark_cats() for each row of data, where non-zero mark for
462  * i-th label means that some of the cells in rast_row are labeled
463  * with i-th label and fall into i-th data range. These marks help
464  * determine from the Categories structure which labels were used and
465  * which weren't.
466  *
467  * \param pcats pointer to Categories structure
468  */
469 void Rast_unmark_cats(struct Categories *pcats)
470 {
471  int i;
472 
473  for (i = 0; i < pcats->ncats; i++)
474  pcats->marks[i] = 0;
475 }
476 
477 /*!
478  * \brief Looks up the category label for each raster value (CELL).
479  *
480  * Looks up the category label for each raster value in the
481  * <i>rast_row</i> and updates the marks for labels found.
482  *
483  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
484  * raster cells read so far which are labeled with i-th label and fall
485  * into i-th data range.
486  *
487  * \param rast_row raster row to update stats
488  * \param ncols number of columns
489  * \param pcats pointer to Categories structure
490  *
491  */
492 void Rast_mark_c_cats(const CELL *rast_row, int ncols, struct Categories *pcats)
493 {
494  Rast_mark_cats(rast_row, ncols, pcats, CELL_TYPE);
495 }
496 
497 /*!
498  * \brief Looks up the category label for each raster value (FCELL).
499  *
500  * Looks up the category label for each raster value in the
501  * <i>rast_row</i> and updates the marks for labels found.
502  *
503  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
504  * raster cells read so far which are labeled with i-th label and fall
505  * into i-th data range.
506  *
507  * \param rast_row raster row to update stats
508  * \param ncols number of columns
509  * \param pcats pointer to Categories structure
510  *
511  */
512 void Rast_mark_f_cats(const FCELL *rast_row, int ncols,
513  struct Categories *pcats)
514 {
515  Rast_mark_cats(rast_row, ncols, pcats, FCELL_TYPE);
516 }
517 
518 /*!
519  * \brief Looks up the category label for each raster value (DCELL).
520  *
521  * Looks up the category label for each raster value in the
522  * <i>rast_row</i> and updates the marks for labels found.
523  *
524  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
525  * raster cells read so far which are labeled with i-th label and fall
526  * into i-th data range.
527  *
528  * \param rast_row raster row to update stats
529  * \param ncols number of columns
530  * \param pcats pointer to Categories structure
531  *
532  */
533 void Rast_mark_d_cats(const DCELL *rast_row, int ncols,
534  struct Categories *pcats)
535 {
536  Rast_mark_cats(rast_row, ncols, pcats, DCELL_TYPE);
537 }
538 
539 /*!
540  * \brief Looks up the category label for each raster value (DCELL).
541  *
542  * Looks up the category label for each raster value in the
543  * <i>rast_row</i> and updates the marks for labels found.
544  *
545  * <b>Note:</b> Non-zero mark for i-th label stores the number of of
546  * raster cells read so far which are labeled with i-th label and fall
547  * into i-th data range.
548  *
549  * \param rast_row raster row to update stats
550  * \param ncols number of columns
551  * \param pcats pointer to Categories structure
552  * \param data_type map type
553  *
554  * \return -1 on error
555  * \return 1 on success
556  */
557 int Rast_mark_cats(const void *rast_row, int ncols, struct Categories *pcats,
558  RASTER_MAP_TYPE data_type)
559 {
560  size_t size = Rast_cell_size(data_type);
561  CELL i;
562 
563  while (ncols-- > 0) {
564  i = Rast_quant_get_cell_value(&pcats->q,
565  Rast_get_d_value(rast_row, data_type));
566  if (Rast_is_c_null_value(&i))
567  continue;
568  if (i > pcats->ncats)
569  return -1;
570  pcats->marks[i]++;
571  rast_row = G_incr_void_ptr(rast_row, size);
572  }
573  return 1;
574 }
575 
576 /*!
577  * \brief Rewind raster categories
578  *
579  * After call to this function Rast_get_next_marked_cat() returns
580  * the first marked cat label.
581  *
582  * \param pcats pointer to Categories structure
583  */
584 void Rast_rewind_cats(struct Categories *pcats)
585 {
586  pcats->last_marked_rule = -1;
587 }
588 
589 /*!
590  \brief Get next marked raster categories (DCELL)
591 
592  \param pcats pointer to Categories structure
593  \param rast1, rast2 cell values (raster range)
594  \param[out] count count
595 
596  \return NULL if not found
597  \return description if found
598  */
599 char *Rast_get_next_marked_d_cat(struct Categories *pcats, DCELL *rast1,
600  DCELL *rast2, long *count)
601 {
602  char *descr = NULL;
603  int found, i;
604 
605  found = 0;
606  /* pcats->ncats should be == Rast_quant_nof_rules(&pcats->q) */
607 
608  G_debug(3, "last marked %d nrules %d\n", pcats->last_marked_rule,
609  Rast_quant_nof_rules(&pcats->q));
610 
611  for (i = pcats->last_marked_rule + 1; i < Rast_quant_nof_rules(&pcats->q);
612  i++) {
613  descr = Rast_get_ith_d_cat(pcats, i, rast1, rast2);
614  G_debug(5, "%d %d", i, pcats->marks[i]);
615  if (pcats->marks[i]) {
616  found = 1;
617  break;
618  }
619  }
620 
621  if (!found)
622  return NULL;
623 
624  *count = pcats->marks[i];
625  pcats->last_marked_rule = i;
626  return descr;
627 }
628 
629 /*!
630  \brief Get next marked raster categories (CELL)
631 
632  \param pcats pointer to Categories structure
633  \param rast1, rast2 cell values (raster range)
634  \param[out] count count
635 
636  \return NULL if not found
637  \return description if found
638  */
639 char *Rast_get_next_marked_c_cat(struct Categories *pcats, CELL *rast1,
640  CELL *rast2, long *count)
641 {
642  return Rast_get_next_marked_cat(pcats, rast1, rast2, count, CELL_TYPE);
643 }
644 
645 /*!
646  \brief Get next marked raster categories (FCELL)
647 
648  \param pcats pointer to Categories structure
649  \param rast1, rast2 cell values (raster range)
650  \param[out] count count
651 
652  \return NULL if not found
653  \return description if found
654  */
655 char *Rast_get_next_marked_f_cat(struct Categories *pcats, FCELL *rast1,
656  FCELL *rast2, long *count)
657 {
658  return Rast_get_next_marked_cat(pcats, rast1, rast2, count, FCELL_TYPE);
659 }
660 
661 /*!
662  \brief Get next marked raster categories
663 
664  \param pcats pointer to Categories structure
665  \param rast1, rast2 cell values (raster range)
666  \param[out] count count
667  \param data_type map type
668 
669  \return NULL if not found
670  \return description if found
671  */
672 char *Rast_get_next_marked_cat(struct Categories *pcats, void *rast1,
673  void *rast2, long *count,
674  RASTER_MAP_TYPE data_type)
675 {
676  DCELL val1, val2;
677  char *lab;
678 
679  lab = Rast_get_next_marked_d_cat(pcats, &val1, &val2, count);
680  Rast_set_d_value(rast1, val1, data_type);
681  Rast_set_d_value(rast2, val2, data_type);
682  return lab;
683 }
684 
685 static int get_fmt(char **f, char *fmt, int *i)
686 {
687  char *ff;
688 
689  ff = *f;
690  if (*ff == 0)
691  return 0;
692  if (*ff == '$') {
693  *f = ff + 1;
694  return 0;
695  }
696  switch (*ff++) {
697  case '1':
698  *i = 0;
699  break;
700  case '2':
701  *i = 1;
702  break;
703  default:
704  return 0;
705  }
706  *fmt++ = '%';
707  *fmt++ = '.';
708  if (*ff++ != '.') {
709  *f = ff - 1;
710  *fmt++ = '0';
711  *fmt++ = 'f';
712  *fmt = 0;
713  return 1;
714  }
715  *fmt = '0';
716  while (*ff >= '0' && *ff <= '9')
717  *fmt++ = *ff++;
718  *fmt++ = 'f';
719  *fmt = 0;
720  *f = ff;
721  return 1;
722 }
723 
724 static void get_cond(char **f, char *value, DCELL val)
725 {
726  char *ff;
727 
728  ff = *f;
729  if (val == 1.) {
730  while (*ff)
731  if (*ff++ == '$')
732  break;
733  }
734 
735  while (*ff)
736  if (*ff == '$') {
737  ff++;
738  break;
739  }
740  else
741  *value++ = *ff++;
742 
743  if (val != 1.) {
744  while (*ff)
745  if (*ff++ == '$')
746  break;
747  }
748  *value = 0;
749  *f = ff;
750 }
751 
752 /*!
753  * \brief Set a raster category label (CELL)
754  *
755  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
756  * category structure <i>pcats</i>.
757  *
758  * \param rast1, rast2 raster values (range)
759  * \param label category label
760  * \param pcats pointer to Categories structure
761  *
762  * \return -1 on error
763  * \return 0 if null value detected
764  * \return 1 on success
765  */
766 int Rast_set_c_cat(const CELL *rast1, const CELL *rast2, const char *label,
767  struct Categories *pcats)
768 {
769  return Rast_set_cat(rast1, rast2, label, pcats, CELL_TYPE);
770 }
771 
772 /*!
773  * \brief Set a raster category label (FCELL)
774  *
775  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
776  * category structure <i>pcats</i>.
777  *
778  * \param rast1, rast2 raster values (range)
779  * \param label category label
780  * \param pcats pointer to Categories structure
781  *
782  * \return
783  */
784 int Rast_set_f_cat(const FCELL *rast1, const FCELL *rast2, const char *label,
785  struct Categories *pcats)
786 {
787  return Rast_set_cat(rast1, rast2, label, pcats, FCELL_TYPE);
788 }
789 
790 /*!
791  * \brief Set a raster category label (DCELL)
792  *
793  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
794  * category structure <i>pcats</i>.
795  *
796  * \param rast1, rast2 raster values (range)
797  * \param label category label
798  * \param pcats pointer to Categories structure
799  *
800  * \return -1 on error
801  * \return 0 if null value detected
802  * \return 1 on success
803  */
804 int Rast_set_d_cat(const DCELL *rast1, const DCELL *rast2, const char *label,
805  struct Categories *pcats)
806 {
807  long len;
808  DCELL dtmp1, dtmp2;
809  int i;
810 
811  /* DEBUG fprintf(stderr,"Rast_set_d_cat(rast1 = %p,rast2 = %p,label =
812  '%s',pcats = %p)\n", rast1,rast2,label,pcats); */
813  if (Rast_is_d_null_value(rast1))
814  return 0;
815  if (Rast_is_d_null_value(rast2))
816  return 0;
817  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): adding quant rule: %f %f %d
818  * %d\n", *rast1, *rast2, pcats->ncats, pcats->ncats); */
819  /* the set_cat() functions are used in many places to reset the labels
820  for the range (or cat) with existing label. In this case we don't
821  want to store both rules with identical range even though the result
822  of get_cat() will be correct, since it will use rule added later.
823  we don't want to overuse memory and we don't want rules which are
824  not used to be written out in cats file. So we first look if
825  the label for this range has been sen, and if it has, overwrite it */
826 
827  for (i = 0; i < pcats->ncats; i++) {
828  Rast_get_ith_d_cat(pcats, i, &dtmp1, &dtmp2);
829  if ((dtmp1 == *rast1 && dtmp2 == *rast2) ||
830  (dtmp1 == *rast2 && dtmp2 == *rast1)) {
831  if (pcats->labels[i] != NULL)
832  G_free(pcats->labels[i]);
833  pcats->labels[i] = G_store(label);
834  G_newlines_to_spaces(pcats->labels[i]);
835  G_strip(pcats->labels[i]);
836  return 1;
837  }
838  }
839  /* when rule for this range does not exist */
840  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): New rule: adding %d %p\n", i,
841  * pcats->labels); */
842  Rast_quant_add_rule(&pcats->q, *rast1, *rast2, pcats->ncats, pcats->ncats);
843  pcats->ncats++;
844  if (pcats->nalloc < pcats->ncats) {
845  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): need more space nalloc = %d
846  * ncats = %d\n", pcats->nalloc,pcats->ncats); */
847  len = (pcats->nalloc + 256) * sizeof(char *);
848  /* DEBUG fprintf (stderr, "Rast_set_d_cat(): allocating %d
849  * labels(%d)\n", pcats->nalloc + 256,(int)len); */
850  if (len != (int)len) { /* make sure len doesn't overflow int */
851  pcats->ncats--;
852  return -1;
853  }
854  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): pcats->nalloc = %d,
855  * pcats->labels = (%p), len =
856  * %d\n",pcats->nalloc,pcats->labels,(int)len); */
857  if (pcats->nalloc) {
858  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): Realloc-ing pcats->labels
859  * (%p)\n",pcats->labels); */
860  pcats->labels = (char **)G_realloc((char *)pcats->labels, (int)len);
861  }
862  else {
863  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): alloc-ing new labels
864  * pointer array\n"); */
865  pcats->labels = (char **)G_malloc((int)len);
866  }
867  /* fflush(stderr); */
868  /* DEBUG fprintf (stderr, "Rast_set_d_cats(): allocating %d
869  * marks(%d)\n", pcats->nalloc + 256,(int)len); */
870  len = (pcats->nalloc + 256) * sizeof(int);
871  if (len != (int)len) { /* make sure len doesn't overflow int */
872  pcats->ncats--;
873  return -1;
874  }
875  if (pcats->nalloc)
876  pcats->marks = (int *)G_realloc((char *)pcats->marks, (int)len);
877  else
878  pcats->marks = (int *)G_malloc((int)len);
879  pcats->nalloc += 256;
880  }
881  /* DEBUG fprintf(stderr,"Rast_set_d_cats(): store new label\n"); */
882  pcats->labels[pcats->ncats - 1] = G_store(label);
883  G_newlines_to_spaces(pcats->labels[pcats->ncats - 1]);
884  G_strip(pcats->labels[pcats->ncats - 1]);
885  /* DEBUG
886  fprintf (stderr, "%d %s\n", pcats->ncats - 1, pcats->labels[pcats->ncats
887  - 1]);
888  */
889  /* updates cats.num = max cat values. This is really just used in old
890  raster programs, and I am doing it for backwards cmpatibility (Olga) */
891  if ((CELL)*rast1 > pcats->num)
892  pcats->num = (CELL)*rast1;
893  if ((CELL)*rast2 > pcats->num)
894  pcats->num = (CELL)*rast2;
895  /* DEBUG fprintf(stderr,"Rast_set_d_cat(): done\n"); */
896  /* DEBUG fflush(stderr); */
897  return 1;
898 }
899 
900 /*!
901  * \brief Set a raster category label
902  *
903  * Adds the label for range <i>rast1</i> through <i>rast2</i> in
904  * category structure <i>pcats</i>.
905  *
906  * \param rast1, rast2 raster values (range)
907  * \param label category label
908  * \param pcats pointer to Categories structure
909  * \param data_type map type
910  *
911  * \return -1 on error
912  * \return 0 if null value detected
913  * \return 1 on success
914  */
915 
916 int Rast_set_cat(const void *rast1, const void *rast2, const char *label,
917  struct Categories *pcats, RASTER_MAP_TYPE data_type)
918 {
919  DCELL val1, val2;
920 
921  val1 = Rast_get_d_value(rast1, data_type);
922  val2 = Rast_get_d_value(rast2, data_type);
923  return Rast_set_d_cat(&val1, &val2, label, pcats);
924 }
925 
926 /*!
927  * \brief Write raster category file
928  *
929  * \todo To be removed, replaced by Rast_write_cats().
930  *
931  * Writes the category file for the raster map <i>name</i> in the
932  * current mapset from the <i>cats</i> structure.
933  *
934  * \param name map name
935  * \param cats pointer to Categories structure
936  *
937  * \return void
938  */
939 void Rast_write_cats(const char *name, struct Categories *cats)
940 {
941  write_cats("cats", name, cats);
942 }
943 
944 /*!
945  * \brief Write vector category file
946  *
947  * <b>Note:</b> Used for only old vector format!
948  *
949  * \todo Move to the vector library.
950  *
951  * \param name map name
952  * \param cats pointer to Categories structure
953  *
954  * \return void
955  */
956 void Rast_write_vector_cats(const char *name, struct Categories *cats)
957 {
958  write_cats("dig_cats", name, cats);
959 }
960 
961 static void write_cats(const char *element, const char *name,
962  struct Categories *cats)
963 {
964  FILE *fd;
965  int i, fp_map;
966  char *descr;
967  DCELL val1, val2;
968  char str1[100], str2[100];
969 
970  fd = G_fopen_new(element, name);
971  if (!fd)
972  G_fatal_error(_("Unable to open %s file for map <%s>"), element, name);
973 
974  /* write # cats - note # indicate 3.0 or later */
975  fprintf(fd, "# %ld categories\n", (long)cats->num);
976 
977  /* title */
978  fprintf(fd, "%s\n", cats->title != NULL ? cats->title : "");
979 
980  /* write format and coefficients */
981  fprintf(fd, "%s\n", cats->fmt != NULL ? cats->fmt : "");
982  fprintf(fd, "%.2f %.2f %.2f %.2f\n", cats->m1, cats->a1, cats->m2,
983  cats->a2);
984 
985  /* if the map is integer or if this is a vector map, sort labels */
986  if (strncmp(element, "dig", 3) == 0)
987  fp_map = 0;
988  else
989  fp_map = Rast_map_is_fp(name, G_mapset());
990  if (!fp_map)
991  Rast_sort_cats(cats);
992 
993  /* write the cat numbers:label */
994  for (i = 0; i < Rast_quant_nof_rules(&cats->q); i++) {
995  descr = Rast_get_ith_d_cat(cats, i, &val1, &val2);
996  if ((cats->fmt && cats->fmt[0]) || (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, int i, DCELL *rast1,
1030  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, int i, void *rast1,
1058  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, int i, void *rast1,
1085  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) largest 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, &min_rast1, &max_rast1, &index,
1320  &index);
1321  Rast_quant_get_ith_rule(&(save_cats.q), *b, &min_rast2, &max_rast2, &index,
1322  &index);
1323  if (min_rast1 < min_rast2)
1324  return -1;
1325  if (min_rast1 > min_rast2)
1326  return 1;
1327  return 0;
1328 }
#define NULL
Definition: ccmath.h:32
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition: gis/open.c:251
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_realloc(p, n)
Definition: defs/gis.h:96
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
void G_newlines_to_spaces(char *)
Definition: nl_to_spaces.c:3
#define G_malloc(n)
Definition: defs/gis.h:94
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
void G_trim_decimal(char *)
Removes trailing zeros from decimal number.
Definition: trim_dec.c:24
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
#define G_incr_void_ptr(ptr, size)
Definition: defs/gis.h:81
int G_getl(char *, int, FILE *)
Gets a line of text from a file.
Definition: getl.c:33
int G_debug(int, const char *,...) __attribute__((format(printf
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition: gis/open.c:219
int Rast_is_null_value(const void *, RASTER_MAP_TYPE)
To check if a raster value is set to NULL.
Definition: null_val.c:176
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:592
void Rast_quant_free(struct Quant *)
Resets and frees allocated memory.
Definition: quant.c:55
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition: null_val.c:153
void Rast_set_d_value(void *, DCELL, RASTER_MAP_TYPE)
Places a DCELL raster value.
void Rast_quant_add_rule(struct Quant *, DCELL, DCELL, CELL, CELL)
Adds a new rule to the set of quantization rules.
Definition: quant.c:469
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
Definition: raster/range.c:718
size_t Rast_cell_size(RASTER_MAP_TYPE)
Returns size of a raster cell in bytes.
Definition: alloc_cell.c:38
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
Definition: raster/range.c:160
void Rast_quant_get_ith_rule(const struct Quant *, int, DCELL *, DCELL *, CELL *, CELL *)
Returns the i'th quantization rule.
Definition: quant.c:327
int Rast_map_is_fp(const char *, const char *)
Check if raster map is floating-point.
Definition: raster/open.c:861
void Rast_quant_init(struct Quant *)
Initialize the structure.
Definition: quant.c:175
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:408
#define Rast_is_c_null_value(cellVal)
Definition: defs/raster.h:404
DCELL Rast_get_d_value(const void *, RASTER_MAP_TYPE)
Retrieves the value of given type from pointer p (DCELL)
int Rast_quant_nof_rules(const struct Quant *)
Returns the number of quantization rules defined.
Definition: quant.c:309
#define min(x, y)
Definition: draw2.c:29
#define max(x, y)
Definition: draw2.c:30
float FCELL
Definition: gis.h:630
double DCELL
Definition: gis.h:629
int CELL
Definition: gis.h:628
#define _(str)
Definition: glocale.h:10
struct field_info * ff
int count
const char * name
Definition: named_colr.c:6
double b
Definition: r_raster.c:39
double l
Definition: r_raster.c:39
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
char * Rast_get_cats_title(const struct Categories *pcats)
Get title from category structure struct.
Definition: raster/cats.c:297
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:655
int Rast_number_of_cats(struct Categories *pcats)
Get number of raster categories.
Definition: raster/cats.c:1269
char * Rast_get_c_cat(CELL *rast, struct Categories *pcats)
Get a raster category label (CELL)
Definition: raster/cats.c:321
char * Rast_get_d_cat(DCELL *rast, struct Categories *pcats)
Get a raster category label (DCELL)
Definition: raster/cats.c:369
void Rast_free_cats(struct Categories *pcats)
Free category structure memory.
Definition: raster/cats.c:1213
char * Rast_get_cat(void *rast, struct Categories *pcats, RASTER_MAP_TYPE data_type)
Get a raster category label.
Definition: raster/cats.c:394
void Rast_rewind_cats(struct Categories *pcats)
Rewind raster categories.
Definition: raster/cats.c:584
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:672
void Rast_write_cats(const char *name, struct Categories *cats)
Write raster category file.
Definition: raster/cats.c:939
CELL Rast_get_max_c_cat(const char *name, const char *mapset)
Get the max category number.
Definition: raster/cats.c:171
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:766
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:804
int Rast_read_vector_cats(const char *name, const char *mapset, struct Categories *pcats)
Read vector category file.
Definition: raster/cats.c:140
int Rast_sort_cats(struct Categories *pcats)
Sort categories.
Definition: raster/cats.c:1282
char * Rast_get_f_cat(FCELL *rast, struct Categories *pcats)
Get a raster category label (FCELL)
Definition: raster/cats.c:345
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
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:557
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
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:916
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:639
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:784
void Rast_copy_cats(struct Categories *pcats_to, const struct Categories *pcats_from)
Copy raster categories.
Definition: raster/cats.c:1248
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:599
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:533
void Rast_unmark_cats(struct Categories *pcats)
Sets marks for all categories to 0.
Definition: raster/cats.c:469
int Rast_read_cats(const char *name, const char *mapset, struct Categories *pcats)
Read raster category file.
Definition: raster/cats.c:104
void Rast_write_vector_cats(const char *name, struct Categories *cats)
Write vector category file.
Definition: raster/cats.c:956
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:492
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
void Rast_init_cats(const char *title, struct Categories *pcats)
Initialize category structure.
Definition: raster/cats.c:1145
void Rast_set_cats_title(const char *title, struct Categories *pcats)
Set title in category structure.
Definition: raster/cats.c:1171
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:512
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
#define FCELL_TYPE
Definition: raster.h:12
#define DCELL_TYPE
Definition: raster.h:13
#define CELL_TYPE
Definition: raster.h:11
int RASTER_MAP_TYPE
Definition: raster.h:25
int * marks
Definition: raster.h:135
float a2
Definition: raster.h:131
char ** labels
Definition: raster.h:134
float m2
Definition: raster.h:130
CELL num
Definition: raster.h:123
char * fmt
Definition: raster.h:127
float m1
Definition: raster.h:128
char * title
Definition: raster.h:126
int nalloc
Definition: raster.h:136
float a1
Definition: raster.h:129
CELL ncats
Definition: raster.h:122
int last_marked_rule
Definition: raster.h:137
struct Quant q
Definition: raster.h:132
Definition: raster.h:211
Definition: lidar.h:85