00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <grass/gis.h>
00021 #include <grass/Vect.h>
00022
00023
00024 static int cmp(const void *pa, const void *pb);
00025 struct line_cats *Vect__new_cats_struct (void);
00026
00027
00036 struct line_cats *
00037 Vect_new_cats_struct ()
00038 {
00039 struct line_cats *p;
00040
00041 if (NULL == (p = Vect__new_cats_struct ()))
00042 G_fatal_error ("New_line: Out of memory");
00043
00044 return p;
00045 }
00046
00047 struct line_cats *
00048 Vect__new_cats_struct ()
00049 {
00050 struct line_cats *p;
00051
00052 p = (struct line_cats *) malloc (sizeof (struct line_cats));
00053
00054
00055 if (p)
00056 p->n_cats = 0;
00057
00058 if (p)
00059 p->alloc_cats = 0;
00060
00061 return p;
00062 }
00063
00070 int
00071 Vect_destroy_cats_struct (struct line_cats *p)
00072 {
00073 if (p)
00074 {
00075 if (p->n_cats)
00076 {
00077 free ((char *) p->field);
00078 free ((char *) p->cat);
00079 }
00080 free ((char *) p);
00081 }
00082
00083 return 0;
00084 }
00085
00097 int
00098 Vect_cat_set (struct line_cats *Cats, int field, int cat)
00099 {
00100 register int n;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 for (n = 0; n < Cats->n_cats; n++) {
00114 if (Cats->field[n] == field && Cats->cat[n] == cat )
00115 return (1);
00116 }
00117
00118
00119
00120 if (n >= GV_NCATS_MAX) {
00121 G_fatal_error ( "Too many categories (%d), cannot set cat %d (field %d).", Cats->n_cats, cat, field);
00122 }
00123
00124 if ( Cats->n_cats == Cats->alloc_cats ) {
00125 if (0 > dig_alloc_cats (Cats, Cats->n_cats + 100))
00126 return (-1);
00127 }
00128
00129 n = Cats->n_cats;
00130 Cats->field[n] = field;
00131 Cats->cat[n] = cat;
00132 Cats->n_cats++;
00133 return (1);
00134 }
00135
00145 int
00146 Vect_cat_get (struct line_cats *Cats, int field, int *cat)
00147 {
00148 register int n;
00149
00150
00151
00152
00153
00154
00155
00156 *cat = -1;
00157
00158
00159 for (n = 0; n < Cats->n_cats; n++)
00160 {
00161 if (Cats->field[n] == field)
00162 {
00163 *cat = Cats->cat[n];
00164 return (1);
00165 }
00166 }
00167
00168
00169 return (0);
00170 }
00171
00179 int
00180 Vect_cat_del (struct line_cats *Cats, int field)
00181 {
00182 int n, m, found = 0;
00183
00184
00185
00186
00187
00188
00189
00190
00191 for (n = 0; n < Cats->n_cats; n++) {
00192 if (Cats->field[n] == field) {
00193 for (m = n; m < Cats->n_cats - 1; m++) {
00194 Cats->field[m] = Cats->field[m + 1];
00195 Cats->cat[m] = Cats->cat[m + 1];
00196 }
00197 Cats->n_cats--;
00198 found = 1;
00199 n--;
00200 }
00201 }
00202
00203 return (found);
00204 }
00205
00214 int
00215 Vect_field_cat_del (struct line_cats *Cats, int field, int cat)
00216 {
00217 register int n, m, found = 0;
00218
00219
00220
00221
00222
00223
00224
00225
00226 for (n = 0; n < Cats->n_cats; n++) {
00227 if (Cats->field[n] == field && ( Cats->cat[n] == cat || cat == -1) ) {
00228 for (m = n; m < Cats->n_cats - 1; m++) {
00229 Cats->field[m] = Cats->field[m + 1];
00230 Cats->cat[m] = Cats->cat[m + 1];
00231 }
00232 Cats->n_cats--;
00233 found = 1;
00234 }
00235 }
00236
00237 return (found);
00238 }
00239
00248 int
00249 Vect_reset_cats (struct line_cats *Cats)
00250 {
00251 Cats->n_cats = 0;
00252
00253 return 0;
00254 }
00255
00262 struct cat_list *
00263 Vect_new_cat_list ()
00264 {
00265 struct cat_list *p;
00266
00267 p = (struct cat_list *) malloc (sizeof (struct cat_list));
00268
00269
00270 if (p) {
00271 p->n_ranges = 0;
00272 p->alloc_ranges = 0;
00273 p->field = 0;
00274 p->min = NULL;
00275 p->max = NULL;
00276 }
00277
00278 return p;
00279 }
00280
00281
00288 int
00289 Vect_destroy_cat_list (struct cat_list *p)
00290 {
00291 if (p)
00292 {
00293 if (p->n_ranges)
00294 {
00295 free ((char *) p->min);
00296 free ((char *) p->max);
00297 }
00298 free ((char *) p);
00299 }
00300
00301 return 0;
00302 }
00303
00304
00313 int
00314 Vect_str_to_cat_list (char *str, struct cat_list *list)
00315 {
00316 int i, nr, l, err = 0;
00317 char *s, *e, buf[100];
00318 int min, max;
00319
00320 G_debug (3, "Vect_str_to_cat_list(): str = %s", str);
00321
00322 list->n_ranges = 0;
00323 l = strlen (str);
00324
00325
00326 nr = 1;
00327 for ( i=0; i < l; i++)
00328 if (str[i] == ',')
00329 nr++;
00330
00331
00332 if ( list->alloc_ranges == 0 )
00333 {
00334 list->min = (int *) G_malloc (nr * sizeof(int));
00335 list->max = (int *) G_malloc (nr * sizeof(int));
00336 }
00337 else if (nr > list->alloc_ranges)
00338 {
00339 list->min = (int *) G_realloc ((void *)list->min,
00340 nr * sizeof(int));
00341 list->max = (int *) G_realloc ((void *)list->max,
00342 nr * sizeof(int));
00343 }
00344
00345
00346 i = 0;
00347 s = str;
00348
00349 while (s)
00350 {
00351 e = (char *) strchr (s, ',');
00352 if( e )
00353 {
00354 l = e - s;
00355 strncpy (buf, s, l);
00356 buf[l] = '\0';
00357 s = e + 1;
00358 }
00359 else
00360 {
00361 strcpy (buf, s);
00362 s = NULL;
00363 }
00364
00365 G_debug (3, " buf = %s", buf);
00366 if ( sscanf (buf, "%d-%d", &min, &max) == 2 ) {}
00367 else if ( sscanf (buf, "%d", &min) == 1 )
00368 max = min;
00369 else
00370 {
00371 G_warning ("Cannot convert category string '%s' (from '%s') to category range", buf, str);
00372 err++;
00373 continue;
00374 }
00375
00376 list->min[i] = min;
00377 list->max[i] = max;
00378 i++;
00379 }
00380
00381 list->n_ranges = i;
00382
00383 return (err);
00384 }
00385
00392 int
00393 Vect_array_to_cat_list (int *vals, int nvals, struct cat_list *list)
00394 {
00395 int i, range;
00396
00397 G_debug (1, "Vect_array_to_cat_list()");
00398 range = -1;
00399 for (i = 0; i < nvals; i++)
00400 {
00401 if ( i == 0 || (vals[i] - list->max[range]) > 1 )
00402 {
00403 range++;
00404 if ( range == list->alloc_ranges)
00405 {
00406 list->alloc_ranges += 1000;
00407 list->min = (int *) G_realloc ((void *)list->min,
00408 list->alloc_ranges * sizeof(int));
00409 list->max = (int *) G_realloc ((void *)list->max,
00410 list->alloc_ranges * sizeof(int));
00411 }
00412 list->min[range] = vals[i];
00413 list->max[range] = vals[i];
00414 }
00415 else
00416 {
00417 list->max[range] = vals[i];
00418 }
00419 }
00420
00421 list->n_ranges = range+1;
00422
00423 return (list->n_ranges);
00424 }
00425
00432 int
00433 Vect_cat_in_cat_list (int cat, struct cat_list *list)
00434 {
00435 int i;
00436
00437 for ( i=0; i < list->n_ranges; i++)
00438 if ( cat >= list->min[i] && cat <= list->max[i] )
00439 return (TRUE);
00440
00441 return (FALSE);
00442 }
00443
00450 int
00451 Vect_cat_in_array (int cat, int *array, int ncats)
00452 {
00453 int *i;
00454
00455 i = bsearch ( (void *) &cat, (void *) array, (size_t)ncats,
00456 sizeof (int), cmp);
00457
00458 if ( i != NULL ) return (TRUE);
00459
00460 return (FALSE);
00461 }
00462
00463
00464 static int cmp ( const void *pa, const void *pb)
00465 {
00466 int *p1 = (int *) pa;
00467 int *p2 = (int *) pb;
00468
00469 if( *p1 < *p2 )
00470 return -1;
00471 if( *p1 > *p2 )
00472 return 1;
00473 return 0;
00474 }