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