GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vector/Vlib/cats.c
Go to the documentation of this file.
1 
21 #include <stdlib.h>
22 #include <string.h>
23 #include <grass/gis.h>
24 #include <grass/Vect.h>
25 #include <grass/glocale.h>
26 
27 static int cmp(const void *pa, const void *pb);
28 struct line_cats *Vect__new_cats_struct(void);
29 
30 
42 struct line_cats *Vect_new_cats_struct()
43 {
44  struct line_cats *p;
45 
46  if (NULL == (p = Vect__new_cats_struct()))
47  G_fatal_error(_("Vect_new_cats_struct(): Out of memory"));
48 
49  return p;
50 }
51 
60 struct line_cats *Vect__new_cats_struct()
61 {
62  struct line_cats *p;
63 
64  p = (struct line_cats *)G_malloc(sizeof(struct line_cats));
65 
66  /* n_cats MUST be initialized to zero */
67  if (p)
68  p->n_cats = 0;
69 
70  if (p)
71  p->alloc_cats = 0;
72 
73  return p;
74 }
75 
83 int Vect_destroy_cats_struct(struct line_cats *p)
84 {
85  if (p) { /* probably a moot test */
86  if (p->n_cats) {
87  G_free((void *)p->field);
88  G_free((void *)p->cat);
89  }
90  G_free((void *)p);
91  }
92 
93  return 0;
94 }
95 
108 int Vect_cat_set(struct line_cats *Cats, int field, int cat)
109 {
110  register int n;
111 
112  /* check input values */
113  /* compiler may warn:
114  * comparison is always 0 due to limited range of data type
115  * but remember that limit is set to portable data type length
116  * and machine native size may be longer */
117  /*
118  if (field < 1 || field > GV_FIELD_MAX || cat < 0 || cat > GV_CAT_MAX)
119  return (-2);
120  */
121 
122  /* go through old cats and find if field/category exists */
123  for (n = 0; n < Cats->n_cats; n++) {
124  if (Cats->field[n] == field && Cats->cat[n] == cat)
125  return (1);
126  }
127 
128  /* field was not found so we shall append new cat */
129  /* test if space exist */
130  if (n >= GV_NCATS_MAX) {
131  G_fatal_error(_("Too many categories (%d), unable to set cat %d (layer %d)"),
132  Cats->n_cats, cat, field);
133  }
134 
135  if (Cats->n_cats == Cats->alloc_cats) {
136  if (0 > dig_alloc_cats(Cats, Cats->n_cats + 100))
137  return (-1);
138  }
139 
140  n = Cats->n_cats;
141  Cats->field[n] = field;
142  Cats->cat[n] = cat;
143  Cats->n_cats++;
144  return (1);
145 }
146 
159 int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
160 {
161  register int n;
162 
163  /* check input value */
164  /*
165  if (field < 1 || field > GV_FIELD_MAX)
166  return (0);
167  */
168 
169  *cat = -1;
170 
171  /* go through cats and find if field exist */
172  for (n = 0; n < Cats->n_cats; n++) {
173  if (Cats->field[n] == field) {
174  *cat = Cats->cat[n];
175  return (1);
176  }
177  }
178 
179  /* field was not found */
180  return (0);
181 }
182 
193 int Vect_field_cat_get(struct line_cats *Cats, int field, struct ilist *cats)
194 {
195  int n;
196 
197  /* reset list of categories */
198  Vect_reset_list(cats);
199 
200  /* check input value */
201  if (field < 1 || field > GV_FIELD_MAX)
202  return -1;
203 
204  /* go through cats and find if field exist */
205  for (n = 0; n < Cats->n_cats; n++) {
206  if (Cats->field[n] != field)
207  continue;
208  Vect_list_append(cats, Cats->cat[n]);
209  }
210 
211  return cats->n_values;
212 }
213 
223 int Vect_cat_del(struct line_cats *Cats, int field)
224 {
225  int n, m, found = 0;
226 
227  /* check input value */
228  /*
229  if (field < 1 || field > GV_FIELD_MAX)
230  return (0);
231  */
232 
233  /* go through cats and find if field exist */
234  for (n = 0; n < Cats->n_cats; n++) {
235  if (Cats->field[n] == field) {
236  for (m = n; m < Cats->n_cats - 1; m++) {
237  Cats->field[m] = Cats->field[m + 1];
238  Cats->cat[m] = Cats->cat[m + 1];
239  }
240  Cats->n_cats--;
241  found = 1;
242  n--; /* check again this position */
243  }
244  }
245 
246  return (found);
247 }
248 
259 int Vect_field_cat_del(struct line_cats *Cats, int field, int cat)
260 {
261  register int n, m, found = 0;
262 
263  /* check input value */
264  /*
265  if (field < 1 || field > GV_FIELD_MAX)
266  return (0);
267  */
268 
269  /* go through cats and find if field exist */
270  for (n = 0; n < Cats->n_cats; n++) {
271  if (Cats->field[n] == field && (Cats->cat[n] == cat || cat == -1)) {
272  for (m = n; m < Cats->n_cats - 1; m++) {
273  Cats->field[m] = Cats->field[m + 1];
274  Cats->cat[m] = Cats->cat[m + 1];
275  }
276  Cats->n_cats--;
277  found = 1;
278  n--; /* check again this position */
279  }
280  }
281 
282  return (found);
283 }
284 
295 int Vect_reset_cats(struct line_cats *Cats)
296 {
297  Cats->n_cats = 0;
298 
299  return 0;
300 }
301 
308 struct cat_list *Vect_new_cat_list()
309 {
310  struct cat_list *p;
311 
312  p = (struct cat_list *)G_malloc(sizeof(struct cat_list));
313 
314  /* n_ranges MUST be initialized to zero */
315  if (p) {
316  p->n_ranges = 0;
317  p->alloc_ranges = 0;
318  p->field = 0;
319  p->min = NULL;
320  p->max = NULL;
321  }
322 
323  return p;
324 }
325 
326 
334 int Vect_destroy_cat_list(struct cat_list *p)
335 {
336  if (p) { /* probably a moot test */
337  if (p->n_ranges) {
338  G_free((void *)p->min);
339  G_free((void *)p->max);
340  }
341  G_free((void *)p);
342  }
343 
344  return 0;
345 }
346 
347 
358 int Vect_str_to_cat_list(const char *str, struct cat_list *list)
359 {
360  int i, nr, l, err = 0;
361  const char *s, *e;
362  char buf[100];
363  int min, max;
364 
365  G_debug(3, "Vect_str_to_cat_list(): str = %s", str);
366 
367  list->n_ranges = 0;
368  l = strlen(str);
369 
370  /* find number of ranges */
371  nr = 1; /* one range */
372  for (i = 0; i < l; i++)
373  if (str[i] == ',')
374  nr++;
375 
376  /* allocate space */
377  if (list->alloc_ranges == 0) {
378  list->min = (int *)G_malloc(nr * sizeof(int));
379  list->max = (int *)G_malloc(nr * sizeof(int));
380  }
381  else if (nr > list->alloc_ranges) {
382  list->min = (int *)G_realloc((void *)list->min, nr * sizeof(int));
383  list->max = (int *)G_realloc((void *)list->max, nr * sizeof(int));
384  }
385 
386  /* go through string and read ranges */
387  i = 0;
388  s = str;
389 
390  while (s) {
391  e = (char *)strchr(s, ','); /* first comma */
392  if (e) {
393  l = e - s;
394  strncpy(buf, s, l);
395  buf[l] = '\0';
396  s = e + 1;
397  }
398  else {
399  strcpy(buf, s);
400  s = NULL;
401  }
402 
403  G_debug(3, " buf = %s", buf);
404  if (sscanf(buf, "%d-%d", &min, &max) == 2) {
405  }
406  else if (sscanf(buf, "%d", &min) == 1)
407  max = min;
408  else { /* error */
409 
410  G_warning(_("Unable to convert category string '%s' (from '%s') to category range"),
411  buf, str);
412  err++;
413  continue;
414  }
415 
416  list->min[i] = min;
417  list->max[i] = max;
418  i++;
419  }
420 
421  list->n_ranges = i;
422 
423  return (err);
424 }
425 
435 int Vect_array_to_cat_list(int *vals, int nvals, struct cat_list *list)
436 {
437  int i, range;
438 
439  G_debug(1, "Vect_array_to_cat_list()");
440  range = -1;
441  for (i = 0; i < nvals; i++) {
442  if (i == 0 || (vals[i] - list->max[range]) > 1) {
443  range++;
444  if (range == list->alloc_ranges) {
445  list->alloc_ranges += 1000;
446  list->min = (int *)G_realloc((void *)list->min,
447  list->alloc_ranges *
448  sizeof(int));
449  list->max =
450  (int *)G_realloc((void *)list->max,
451  list->alloc_ranges * sizeof(int));
452  }
453  list->min[range] = vals[i];
454  list->max[range] = vals[i];
455  }
456  else {
457  list->max[range] = vals[i];
458  }
459  }
460 
461  list->n_ranges = range + 1;
462 
463  return (list->n_ranges);
464 }
465 
475 int Vect_cat_in_cat_list(int cat, struct cat_list *list)
476 {
477  int i;
478 
479  for (i = 0; i < list->n_ranges; i++)
480  if (cat >= list->min[i] && cat <= list->max[i])
481  return (TRUE);
482 
483  return (FALSE);
484 }
485 
496 int Vect_cat_in_array(int cat, int *array, int ncats)
497 {
498  int *i;
499 
500  i = bsearch((void *)&cat, (void *)array, (size_t) ncats,
501  sizeof(int), cmp);
502 
503  if (i != NULL)
504  return (TRUE);
505 
506  return (FALSE);
507 }
508 
509 static int cmp(const void *pa, const void *pb)
510 {
511  int *p1 = (int *)pa;
512  int *p2 = (int *)pb;
513 
514  if (*p1 < *p2)
515  return -1;
516  if (*p1 > *p2)
517  return 1;
518  return 0;
519 }
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
int l
Definition: dataquad.c:292
int Vect_field_cat_del(struct line_cats *Cats, int field, int cat)
Delete field/cat from line_cats structure.
#define FALSE
Definition: dbfopen.c:117
int Vect_destroy_cat_list(struct cat_list *p)
Frees allocated cat_list memory.
#define min(x, y)
Definition: draw2.c:68
int Vect_cat_del(struct line_cats *Cats, int field)
Delete all categories of given layer.
const char * err
Definition: g3dcolor.c:50
int Vect_reset_cats(struct line_cats *Cats)
Reset category structure to make sure cats structure is clean to be re-used.
#define max(x, y)
Definition: draw2.c:69
int Vect_cat_in_cat_list(int cat, struct cat_list *list)
Check if category number is in list.
int Vect_field_cat_get(struct line_cats *Cats, int field, struct ilist *cats)
Get list of categories of given field.
int dig_alloc_cats(struct line_cats *cats, int num)
Definition: struct_alloc.c:272
int Vect_cat_set(struct line_cats *Cats, int field, int cat)
Add new field/cat to category structure if doesn&#39;t exist yet.
struct cat_list * Vect_new_cat_list()
Allocate memory for cat_list structure.
#define TRUE
Definition: dbfopen.c:118
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
int Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.
int
Definition: g3dcolor.c:48
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int Vect_array_to_cat_list(int *vals, int nvals, struct cat_list *list)
Convert ordered array of integers to cat_list structure.
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int Vect_cat_in_array(int cat, int *array, int ncats)
Check if category is in ordered array of integers.
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int Vect_str_to_cat_list(const char *str, struct cat_list *list)
Convert string of categories and cat ranges separated by commas to cat_list.
CELL cat
Definition: g3dcats.c:90
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
tuple range
Definition: tools.py:1406
int n
Definition: dataquad.c:291
struct line_cats * Vect__new_cats_struct(void)
Creates and initializes line_cats structure (lower level fn)
int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
Get first found category of given field.