00001
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <grass/gis.h>
00024 #include <grass/Vect.h>
00025 #include <grass/glocale.h>
00026
00027 static int cmp(const void *pa, const void *pb);
00028 struct line_cats *Vect__new_cats_struct(void);
00029
00030
00040 struct line_cats *Vect_new_cats_struct()
00041 {
00042 struct line_cats *p;
00043
00044 if (NULL == (p = Vect__new_cats_struct()))
00045 G_fatal_error(_("Vect_new_cats_struct(): Out of memory"));
00046
00047 return p;
00048 }
00049
00058 struct line_cats *Vect__new_cats_struct()
00059 {
00060 struct line_cats *p;
00061
00062 p = (struct line_cats *)G_malloc(sizeof(struct line_cats));
00063
00064
00065 if (p)
00066 p->n_cats = 0;
00067
00068 if (p)
00069 p->alloc_cats = 0;
00070
00071 return p;
00072 }
00073
00081 int Vect_destroy_cats_struct(struct line_cats *p)
00082 {
00083 if (p) {
00084 if (p->n_cats) {
00085 G_free((void *)p->field);
00086 G_free((void *)p->cat);
00087 }
00088 G_free((void *)p);
00089 }
00090
00091 return 0;
00092 }
00093
00106 int Vect_cat_set(struct line_cats *Cats, int field, int cat)
00107 {
00108 register int n;
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 for (n = 0; n < Cats->n_cats; n++) {
00122 if (Cats->field[n] == field && Cats->cat[n] == cat)
00123 return (1);
00124 }
00125
00126
00127
00128 if (n >= GV_NCATS_MAX) {
00129 G_fatal_error(_("Too many categories (%d), unable to set cat %d (layer %d)"),
00130 Cats->n_cats, cat, field);
00131 }
00132
00133 if (Cats->n_cats == Cats->alloc_cats) {
00134 if (0 > dig_alloc_cats(Cats, Cats->n_cats + 100))
00135 return (-1);
00136 }
00137
00138 n = Cats->n_cats;
00139 Cats->field[n] = field;
00140 Cats->cat[n] = cat;
00141 Cats->n_cats++;
00142 return (1);
00143 }
00144
00157 int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
00158 {
00159 register int n;
00160
00161
00162
00163
00164
00165
00166
00167 *cat = -1;
00168
00169
00170 for (n = 0; n < Cats->n_cats; n++) {
00171 if (Cats->field[n] == field) {
00172 *cat = Cats->cat[n];
00173 return (1);
00174 }
00175 }
00176
00177
00178 return (0);
00179 }
00180
00191 int Vect_field_cat_get(struct line_cats *Cats, int field, struct ilist *cats)
00192 {
00193 int n;
00194
00195
00196 Vect_reset_list(cats);
00197
00198
00199 if (field < 1 || field > GV_FIELD_MAX)
00200 return -1;
00201
00202
00203 for (n = 0; n < Cats->n_cats; n++) {
00204 if (Cats->field[n] != field)
00205 continue;
00206 Vect_list_append(cats, Cats->cat[n]);
00207 }
00208
00209 return cats->n_values;
00210 }
00211
00221 int Vect_cat_del(struct line_cats *Cats, int field)
00222 {
00223 int n, m, found = 0;
00224
00225
00226
00227
00228
00229
00230
00231
00232 for (n = 0; n < Cats->n_cats; n++) {
00233 if (Cats->field[n] == field) {
00234 for (m = n; m < Cats->n_cats - 1; m++) {
00235 Cats->field[m] = Cats->field[m + 1];
00236 Cats->cat[m] = Cats->cat[m + 1];
00237 }
00238 Cats->n_cats--;
00239 found = 1;
00240 n--;
00241 }
00242 }
00243
00244 return (found);
00245 }
00246
00257 int Vect_field_cat_del(struct line_cats *Cats, int field, int cat)
00258 {
00259 register int n, m, found = 0;
00260
00261
00262
00263
00264
00265
00266
00267
00268 for (n = 0; n < Cats->n_cats; n++) {
00269 if (Cats->field[n] == field && (Cats->cat[n] == cat || cat == -1)) {
00270 for (m = n; m < Cats->n_cats - 1; m++) {
00271 Cats->field[m] = Cats->field[m + 1];
00272 Cats->cat[m] = Cats->cat[m + 1];
00273 }
00274 Cats->n_cats--;
00275 found = 1;
00276 }
00277 }
00278
00279 return (found);
00280 }
00281
00292 int Vect_reset_cats(struct line_cats *Cats)
00293 {
00294 Cats->n_cats = 0;
00295
00296 return 0;
00297 }
00298
00305 struct cat_list *Vect_new_cat_list()
00306 {
00307 struct cat_list *p;
00308
00309 p = (struct cat_list *)G_malloc(sizeof(struct cat_list));
00310
00311
00312 if (p) {
00313 p->n_ranges = 0;
00314 p->alloc_ranges = 0;
00315 p->field = 0;
00316 p->min = NULL;
00317 p->max = NULL;
00318 }
00319
00320 return p;
00321 }
00322
00323
00331 int Vect_destroy_cat_list(struct cat_list *p)
00332 {
00333 if (p) {
00334 if (p->n_ranges) {
00335 G_free((void *)p->min);
00336 G_free((void *)p->max);
00337 }
00338 G_free((void *)p);
00339 }
00340
00341 return 0;
00342 }
00343
00344
00355 int Vect_str_to_cat_list(const char *str, struct cat_list *list)
00356 {
00357 int i, nr, l, err = 0;
00358 const char *s, *e;
00359 char buf[100];
00360 int min, max;
00361
00362 G_debug(3, "Vect_str_to_cat_list(): str = %s", str);
00363
00364 list->n_ranges = 0;
00365 l = strlen(str);
00366
00367
00368 nr = 1;
00369 for (i = 0; i < l; i++)
00370 if (str[i] == ',')
00371 nr++;
00372
00373
00374 if (list->alloc_ranges == 0) {
00375 list->min = (int *)G_malloc(nr * sizeof(int));
00376 list->max = (int *)G_malloc(nr * sizeof(int));
00377 }
00378 else if (nr > list->alloc_ranges) {
00379 list->min = (int *)G_realloc((void *)list->min, nr * sizeof(int));
00380 list->max = (int *)G_realloc((void *)list->max, nr * sizeof(int));
00381 }
00382
00383
00384 i = 0;
00385 s = str;
00386
00387 while (s) {
00388 e = (char *)strchr(s, ',');
00389 if (e) {
00390 l = e - s;
00391 strncpy(buf, s, l);
00392 buf[l] = '\0';
00393 s = e + 1;
00394 }
00395 else {
00396 strcpy(buf, s);
00397 s = NULL;
00398 }
00399
00400 G_debug(3, " buf = %s", buf);
00401 if (sscanf(buf, "%d-%d", &min, &max) == 2) {
00402 }
00403 else if (sscanf(buf, "%d", &min) == 1)
00404 max = min;
00405 else {
00406
00407 G_warning(_("Unable to convert category string '%s' (from '%s') to category range"),
00408 buf, str);
00409 err++;
00410 continue;
00411 }
00412
00413 list->min[i] = min;
00414 list->max[i] = max;
00415 i++;
00416 }
00417
00418 list->n_ranges = i;
00419
00420 return (err);
00421 }
00422
00432 int Vect_array_to_cat_list(int *vals, int nvals, struct cat_list *list)
00433 {
00434 int i, range;
00435
00436 G_debug(1, "Vect_array_to_cat_list()");
00437 range = -1;
00438 for (i = 0; i < nvals; i++) {
00439 if (i == 0 || (vals[i] - list->max[range]) > 1) {
00440 range++;
00441 if (range == list->alloc_ranges) {
00442 list->alloc_ranges += 1000;
00443 list->min = (int *)G_realloc((void *)list->min,
00444 list->alloc_ranges *
00445 sizeof(int));
00446 list->max =
00447 (int *)G_realloc((void *)list->max,
00448 list->alloc_ranges * sizeof(int));
00449 }
00450 list->min[range] = vals[i];
00451 list->max[range] = vals[i];
00452 }
00453 else {
00454 list->max[range] = vals[i];
00455 }
00456 }
00457
00458 list->n_ranges = range + 1;
00459
00460 return (list->n_ranges);
00461 }
00462
00472 int Vect_cat_in_cat_list(int cat, struct cat_list *list)
00473 {
00474 int i;
00475
00476 for (i = 0; i < list->n_ranges; i++)
00477 if (cat >= list->min[i] && cat <= list->max[i])
00478 return (TRUE);
00479
00480 return (FALSE);
00481 }
00482
00493 int Vect_cat_in_array(int cat, int *array, int ncats)
00494 {
00495 int *i;
00496
00497 i = bsearch((void *)&cat, (void *)array, (size_t) ncats,
00498 sizeof(int), cmp);
00499
00500 if (i != NULL)
00501 return (TRUE);
00502
00503 return (FALSE);
00504 }
00505
00506 static int cmp(const void *pa, const void *pb)
00507 {
00508 int *p1 = (int *)pa;
00509 int *p2 = (int *)pb;
00510
00511 if (*p1 < *p2)
00512 return -1;
00513 if (*p1 > *p2)
00514 return 1;
00515 return 0;
00516 }