19 #include <sys/types.h>
22 #include <grass/gis.h>
23 #include <grass/Vect.h>
24 #include <grass/glocale.h>
26 static int cmp_cat(
const void *pa,
const void *pb);
28 static void check_status(
struct Map_info *Map)
30 if (!Map->plus.cidx_up_to_date)
45 return (Map->plus.n_cidx);
60 if (index >= Map->plus.n_cidx)
61 G_fatal_error(_(
"Invalid layer index (index >= number of layers)"));
63 return (Map->plus.cidx[index].field);
78 struct Plus_head *Plus;
80 G_debug(2,
"Vect_cidx_get_field_index() field = %d", field);
85 for (i = 0; i < Plus->n_cidx; i++) {
86 if (Plus->cidx[i].field == field)
106 if (index < 0 || index >= Map->plus.n_cidx)
107 G_fatal_error(_(
"Invalid layer index (index < 0 or index >= number of layers)"));
109 return (Map->plus.cidx[index].n_ucats);
124 if (index >= Map->plus.n_cidx)
125 G_fatal_error(_(
"Invalid layer index (index >= number of layers)"));
127 return (Map->plus.cidx[index].n_cats);
142 if (field_index >= Map->plus.n_cidx)
143 G_fatal_error(_(
"Invalid layer index (index >= number of layers)"));
145 return (Map->plus.cidx[field_index].n_types);
162 int type_index,
int *
type,
int *count)
165 if (field_index >= Map->plus.n_cidx)
166 G_fatal_error(_(
"Invalid layer index (index >= number of layers)"));
168 *type = Map->plus.cidx[field_index].type[type_index][0];
169 *count = Map->plus.cidx[field_index].type[type_index][1];
186 int i, fi,
count = 0;
188 G_debug(3,
"Vect_cidx_get_type_count() field = %d, type = %d", field,
195 G_debug(3,
"field_index = %d", fi);
197 G_debug(3,
"ntypes = %d", Map->plus.cidx[fi].n_types);
198 for (i = 0; i < Map->plus.cidx[fi].n_types; i++) {
201 tp = Map->plus.cidx[fi].type[i][0];
202 cnt = Map->plus.cidx[fi].type[i][1];
205 G_debug(3,
"%d tp = %d, cnt= %d count = %d", i, tp, cnt, count);
226 int cat_index,
int *cat,
int *
type,
int *
id)
230 if (field_index >= Map->plus.n_cidx || field_index < 0 ||
231 cat_index >= Map->plus.cidx[field_index].n_cats)
234 *cat = Map->plus.cidx[field_index].cat[cat_index][0];
235 *type = Map->plus.cidx[field_index].cat[cat_index][1];
236 *
id = Map->plus.cidx[field_index].cat[cat_index][2];
242 static int cmp_cat(
const void *pa,
const void *pb)
270 int type_mask,
int start_index,
int *
type,
int *
id)
272 int *catp, cat_index;
273 struct Cat_index *ci;
276 "Vect_cidx_find_next() cat = %d, type_mask = %d, start_index = %d",
277 cat, type_mask, start_index);
282 if (field_index >= Map->plus.n_cidx)
287 if (start_index >= Map->plus.cidx[field_index].n_cats)
291 ci = &(Map->plus.cidx[field_index]);
294 catp = bsearch(&cat, (
int *)ci->cat + start_index * 3,
295 (
size_t) ci->n_cats - start_index,
296 3 *
sizeof(
int), cmp_cat);
303 cat_index = (catp - (
int *)ci->cat) / 3;
305 G_debug(4,
"cat_index = %d", cat_index);
308 while (cat_index > start_index) {
309 if (ci->cat[cat_index - 1][0] != cat) {
314 G_debug(4,
"cat_index = %d", cat_index);
317 G_debug(3,
" cat_index = %d", cat_index);
318 if (ci->cat[cat_index][0] == cat && ci->cat[cat_index][1] & type_mask) {
319 *type = ci->cat[cat_index][1];
320 *
id = ci->cat[cat_index][2];
321 G_debug(3,
" type match -> record found");
325 }
while (cat_index < ci->n_cats);
343 int cat,
struct ilist *lines)
346 struct Cat_index *ci;
347 int field_index, idx;
352 if (field_index == -1) {
356 ci = &(Map->plus.cidx[field_index]);
359 type_mask, 0, &type, &line);
366 if (!(ci->cat[idx][1] & type_mask)
367 || ci->cat[idx][0] != cat) {
372 }
while (idx < ci->n_cats);
377 #define SEP "------------------------------------------------------------------------------------------\n"
390 int i, field, nfields, ntypes;
392 G_debug(2,
"Vect_cidx_dump()");
397 fprintf(out,
"---------- CATEGORY INDEX DUMP: Number of layers: %d "
398 "--------------------------------------\n", nfields);
400 for (i = 0; i < nfields; i++) {
401 int j, nucats, ncats;
409 "Layer %6d number of unique cats: %7d number of cats: %7d number of types: %d\n",
410 field, nucats, ncats, ntypes);
413 fprintf(out,
" type | count\n");
414 for (j = 0; j < ntypes; j++) {
418 fprintf(out,
" %5d | %9d\n", type, count);
421 fprintf(out,
" category | type | line/area\n");
422 for (j = 0; j < ncats; j++) {
426 fprintf(out,
"%9d | %4d | %9d\n", cat, type,
id);
445 struct Plus_head *plus;
446 char fname[1024], buf[1024];
449 G_debug(2,
"Vect_cidx_save()");
454 sprintf(buf,
"%s/%s", GRASS_VECT_DIRECTORY, Map->name);
456 G_debug(2,
"Open cidx: %s", fname);
458 fp.file = fopen(fname,
"w");
459 if (fp.file ==
NULL) {
460 G_warning(_(
"Unable to open cidx file <%s> for write"), fname);
468 G_warning(_(
"Error writing out category index file <%s>"), fname);
490 char buf[500], file_path[2000];
492 struct Plus_head *Plus;
495 G_debug(2,
"Vect_cidx_open(): name = %s mapset= %s", Map->name,
500 sprintf(buf,
"%s/%s", GRASS_VECT_DIRECTORY, Map->name);
501 G__file_name(file_path, buf, GV_CIDX_ELEMENT, Map->mapset);
503 if (stat(file_path, &info) != 0)
508 fp.file =
G_fopen_old(buf, GV_CIDX_ELEMENT, Map->mapset);
510 if (fp.file ==
NULL) {
511 G_warning(_(
"Unable to open category index file for vector map <%s@%s>"),
512 Map->name, Map->mapset);
523 G_debug(3,
"Cannot read cidx");