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);
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][0] != cat) {
369 if (ci->cat[idx][1] & type_mask) {
373 }
while (idx < ci->n_cats);
378 #define SEP "------------------------------------------------------------------------------------------\n"
391 int i, field, nfields, ntypes;
393 G_debug(2,
"Vect_cidx_dump()");
398 fprintf(out,
"---------- CATEGORY INDEX DUMP: Number of layers: %d "
399 "--------------------------------------\n", nfields);
401 for (i = 0; i < nfields; i++) {
402 int j, nucats, ncats;
410 "Layer %6d number of unique cats: %7d number of cats: %7d number of types: %d\n",
411 field, nucats, ncats, ntypes);
414 fprintf(out,
" type | count\n");
415 for (j = 0; j < ntypes; j++) {
419 fprintf(out,
" %5d | %9d\n", type, count);
422 fprintf(out,
" category | type | line/area\n");
423 for (j = 0; j < ncats; j++) {
427 fprintf(out,
"%9d | %4d | %9d\n", cat, type,
id);
446 struct Plus_head *plus;
447 char fname[1024],
buf[1024];
450 G_debug(2,
"Vect_cidx_save()");
455 sprintf(buf,
"%s/%s", GRASS_VECT_DIRECTORY, Map->name);
457 G_debug(2,
"Open cidx: %s", fname);
459 fp.file = fopen(fname,
"w");
460 if (fp.file ==
NULL) {
461 G_warning(_(
"Unable to open cidx file <%s> for write"), fname);
469 G_warning(_(
"Error writing out category index file <%s>"), fname);
491 char buf[500], file_path[2000];
493 struct Plus_head *Plus;
496 G_debug(2,
"Vect_cidx_open(): name = %s mapset= %s", Map->name,
501 sprintf(buf,
"%s/%s", GRASS_VECT_DIRECTORY, Map->name);
502 G__file_name(file_path, buf, GV_CIDX_ELEMENT, Map->mapset);
504 if (
stat(file_path, &info) != 0)
509 fp.file =
G_fopen_old(buf, GV_CIDX_ELEMENT, Map->mapset);
511 if (fp.file ==
NULL) {
512 G_warning(_(
"Unable to open category index file for vector map <%s@%s>"),
513 Map->name, Map->mapset);
524 G_debug(3,
"Cannot read cidx");
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
int Vect_cidx_get_num_cats_by_index(struct Map_info *Map, int index)
Get number of categories for given layer index.
int Vect_cidx_get_field_index(struct Map_info *Map, int field)
Get layer index for given layer number.
int Vect_cidx_dump(struct Map_info *Map, FILE *out)
Write category index in text form to file.
void Vect_cidx_find_all(struct Map_info *Map, int layer, int type_mask, int cat, struct ilist *lines)
Gind all line/area id's for given category.
int Vect_cidx_get_field_number(struct Map_info *Map, int index)
Get layer number for given index.
void dig_init_portable(struct Port_info *port, int byte_order)
int Vect_cidx_get_num_unique_cats_by_index(struct Map_info *Map, int index)
Get number of unique categories for given layer index.
int Vect_cidx_get_cat_by_index(struct Map_info *Map, int field_index, int cat_index, int *cat, int *type, int *id)
Get number of categories for given field and category index.
char * G__file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
int Vect_cidx_get_type_count_by_index(struct Map_info *Map, int field_index, int type_index, int *type, int *count)
Get type count field index and type index.
int Vect_cidx_get_type_count(struct Map_info *Map, int field, int type)
Get count of features of certain type by layer and type.
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
int dig_cidx_init(struct Plus_head *Plus)
int dig_read_cidx(GVFILE *fp, struct Plus_head *plus, int head_only)
int Vect_cidx_get_num_fields(struct Map_info *Map)
Get number of layer in category index.
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
void dig_file_init(GVFILE *file)
Initialize GVFILE.
int Vect_cidx_find_next(struct Map_info *Map, int field_index, int cat, int type_mask, int start_index, int *type, int *id)
Find next line/area id for given category, start_index and type_mask.
int dig_write_cidx(GVFILE *fp, struct Plus_head *plus)
int Vect_cidx_save(struct Map_info *Map)
Save category index.
int Vect_cidx_open(struct Map_info *Map, int head_only)
Read category index from file if exists.
int dig__byte_order_out()
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int Vect_cidx_get_num_types_by_index(struct Map_info *Map, int field_index)
Get number of types for given layer index.