/* Write spatial index */ int dig_write_cidx(GVFILE * fp, struct Plus_head *plus) { int i; dig_set_cur_port(&(plus->cidx_port)); dig_rewind(fp); dig_write_cidx_head(fp, plus); /* Write category-type-id for each field */ for (i = 0; i < plus->n_cidx; i++) { int j; struct Cat_index *ci; ci = &(plus->cidx[i]); ci->offset = dig_ftell(fp); /* convert type */ for (j = 0; j < ci->n_cats; j++) ci->cat[j][1] = dig_type_to_store(ci->cat[j][1]); if (0 >= dig__fwrite_port_I((int *)ci->cat, 3 * ci->n_cats, fp)) return (-1); /* Return back */ for (j = 0; j < ci->n_cats; j++) ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]); } dig_write_cidx_head(fp, plus); /* rewrite with offsets */ return 0; }
/*! \brief Read spatial index file \param fp pointer to gvfile structure \param[in,out] plus pointer to Plus_head structure \param head_only non-zero to read only head \return 0 OK \return 1 error */ int dig_read_cidx(struct gvfile * fp, struct Plus_head *plus, int head_only) { int i; G_debug(3, "dig_read_cidx()"); dig_cidx_free(plus); dig_cidx_init(plus); dig_rewind(fp); if (dig_read_cidx_head(fp, plus) == -1) { G_debug(3, "Cannot read cidx head"); return 1; } if (head_only) { plus->cidx_up_to_date = 1; /* OK ? */ return 0; } dig_set_cur_port(&(plus->cidx_port)); /* Read category-type-id for each field */ for (i = 0; i < plus->n_cidx; i++) { int j; struct Cat_index *ci; ci = &(plus->cidx[i]); ci->a_cats = ci->n_cats; ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int)); if (dig_fseek(fp, ci->offset, 0) == -1) return 1; if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp)) return 1; /* convert type */ for (j = 0; j < ci->n_cats; j++) ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]); } plus->cidx_up_to_date = 1; return 0; }
int dig_Rd_P_line(struct Plus_head *Plus, int n, struct gvfile * fp) { int n_edges; char tp; struct P_line *ptr; G_debug(4, "dig_Rd_P_line()"); if (0 >= dig__fread_port_C(&tp, 1, fp)) return (-1); if (tp == 0) { /* dead */ G_debug(4, " line is dead"); Plus->Line[n] = NULL; return 0; } ptr = dig_alloc_line(); /* type */ ptr->type = dig_type_from_store(tp); G_debug(5, " line type %d -> %d", tp, ptr->type); /* offset */ if (0 >= dig__fread_port_O(&(ptr->offset), 1, fp, Plus->off_t_size)) return (-1); if (ptr->type == GV_POINT) { ptr->topo = NULL; } else { ptr->topo = dig_alloc_topo(ptr->type); } /* centroids */ if (ptr->type & GV_CENTROID) { struct P_topo_c *topo = (struct P_topo_c *)ptr->topo; if (0 >= dig__fread_port_P(&(topo->area), 1, fp)) return -1; } /* lines */ else if (ptr->type & GV_LINE) { struct P_topo_l *topo = (struct P_topo_l *)ptr->topo; if (0 >= dig__fread_port_P(&(topo->N1), 1, fp)) return -1; if (0 >= dig__fread_port_P(&(topo->N2), 1, fp)) return -1; } /* boundaries */ else if (ptr->type & GV_BOUNDARY) { struct P_topo_b *topo = (struct P_topo_b *)ptr->topo; if (0 >= dig__fread_port_P(&(topo->N1), 1, fp)) return -1; if (0 >= dig__fread_port_P(&(topo->N2), 1, fp)) return -1; if (0 >= dig__fread_port_P(&(topo->left), 1, fp)) return -1; if (0 >= dig__fread_port_P(&(topo->right), 1, fp)) return -1; } /* faces */ else if ((ptr->type & GV_FACE) && Plus->with_z) { /* reserved for face edges */ struct P_topo_f *topo = (struct P_topo_f *)ptr->topo; if (0 >= dig__fread_port_I(&n_edges, 1, fp)) return -1; /* here will be list of edges */ /* left / right volume */ if (0 >= dig__fread_port_P(&(topo->left), 1, fp)) return -1; if (0 >= dig__fread_port_P(&(topo->left), 1, fp)) return -1; } /* kernels */ else if ((ptr->type & GV_KERNEL) && Plus->with_z) { /* reserved for kernel (volume number) */ struct P_topo_k *topo = (struct P_topo_k *)ptr->topo; if (0 >= dig__fread_port_P(&(topo->volume), 1, fp)) return -1; } Plus->Line[n] = ptr; return (0); }
/* return: 0 OK, -1 error */ int dig_read_cidx_head(GVFILE * fp, struct Plus_head *plus) { unsigned char buf[5]; int i, byte_order; dig_rewind(fp); /* bytes 1 - 5 */ if (0 >= dig__fread_port_C(buf, 5, fp)) return (-1); plus->cidx_Version_Major = buf[0]; plus->cidx_Version_Minor = buf[1]; plus->cidx_Back_Major = buf[2]; plus->cidx_Back_Minor = buf[3]; byte_order = buf[4]; G_debug(3, "Cidx header: file version %d.%d , supported from GRASS version %d.%d", plus->cidx_Version_Major, plus->cidx_Version_Minor, plus->cidx_Back_Major, plus->cidx_Back_Minor); G_debug(3, " byte order %d", byte_order); /* check version numbers */ if (plus->cidx_Version_Major > GV_CIDX_VER_MAJOR || plus->cidx_Version_Minor > GV_CIDX_VER_MINOR) { /* The file was created by GRASS library with higher version than this one */ if (plus->cidx_Back_Major > GV_CIDX_VER_MAJOR || plus->cidx_Back_Minor > GV_CIDX_VER_MINOR) { /* This version of GRASS lib is lower than the oldest which can read this format */ G_debug(1, "Category index format version %d.%d", plus->cidx_Version_Major, plus->cidx_Version_Minor); G_fatal_error ("This version of GRASS (%d.%d) is too old to read this category index format." " Try to rebuild topology or upgrade GRASS to at least version %d.", GRASS_VERSION_MAJOR, GRASS_VERSION_MINOR, GRASS_VERSION_MAJOR + 1); return (-1); } G_warning ("Your GRASS version does not fully support category index format %d.%d of the vector." " Consider to rebuild topology or upgrade GRASS.", plus->cidx_Version_Major, plus->cidx_Version_Minor); } dig_init_portable(&(plus->cidx_port), byte_order); dig_set_cur_port(&(plus->cidx_port)); /* bytes 6 - 9 : header size */ if (0 >= dig__fread_port_L(&(plus->cidx_head_size), 1, fp)) return (-1); G_debug(3, " header size %ld", plus->cidx_head_size); /* Body of header - info about all fields */ /* Number of fields */ if (0 >= dig__fread_port_I(&(plus->n_cidx), 1, fp)) return (-1); /* alloc space */ plus->a_cidx = plus->n_cidx; plus->cidx = (struct Cat_index *)G_malloc(plus->a_cidx * sizeof(struct Cat_index)); for (i = 0; i < plus->n_cidx; i++) { int t; struct Cat_index *ci; ci = &(plus->cidx[i]); ci->cat = NULL; ci->a_cats = 0; /* Field number */ if (0 >= dig__fread_port_I(&(ci->field), 1, fp)) return (-1); /* Number of categories */ if (0 >= dig__fread_port_I(&(ci->n_cats), 1, fp)) return (-1); /* Number of unique categories */ if (0 >= dig__fread_port_I(&(ci->n_ucats), 1, fp)) return (-1); /* Number of types */ if (0 >= dig__fread_port_I(&(ci->n_types), 1, fp)) return (-1); /* Types */ for (t = 0; t < ci->n_types; t++) { int rtype; /* type */ if (0 >= dig__fread_port_I(&rtype, 1, fp)) return (-1); ci->type[t][0] = dig_type_from_store(rtype); /* number of items */ if (0 >= dig__fread_port_I(&(ci->type[t][1]), 1, fp)) return (-1); } /* Offset */ if (0 >= dig__fread_port_L(&(ci->offset), 1, fp)) return (0); } if (dig_fseek(fp, plus->cidx_head_size, SEEK_SET) == -1) return (-1); return (0); }
/*! \brief Read line from coor file \param Map vector map layer \param[out] p container used to store line points within \param[out] c container used to store line categories within \param offset given offset \return line type ( > 0 ) \return 0 dead line \return -1 out of memory \return -2 end of file */ int read_line_nat(struct Map_info *Map, struct line_pnts *p, struct line_cats *c, off_t offset) { register int i, dead = 0; int n_points; off_t size; int n_cats, do_cats; int type; char rhead, nc; short field; G_debug(3, "Vect__Read_line_nat: offset = %lu", (unsigned long) offset); Map->head.last_offset = offset; /* reads must set in_head, but writes use default */ dig_set_cur_port(&(Map->head.port)); dig_fseek(&(Map->dig_fp), offset, 0); if (0 >= dig__fread_port_C(&rhead, 1, &(Map->dig_fp))) return (-2); if (!(rhead & 0x01)) /* dead line */ dead = 1; if (rhead & 0x02) /* categories exists */ do_cats = 1; /* do not return here let file offset moves forward to next */ else /* line */ do_cats = 0; rhead >>= 2; type = dig_type_from_store((int)rhead); G_debug(3, " type = %d, do_cats = %d dead = %d", type, do_cats, dead); if (c != NULL) c->n_cats = 0; if (do_cats) { if (Map->head.Version_Minor == 1) { /* coor format 5.1 */ if (0 >= dig__fread_port_I(&n_cats, 1, &(Map->dig_fp))) return (-2); } else { /* coor format 5.0 */ if (0 >= dig__fread_port_C(&nc, 1, &(Map->dig_fp))) return (-2); n_cats = (int)nc; } G_debug(3, " n_cats = %d", n_cats); if (c != NULL) { c->n_cats = n_cats; if (n_cats > 0) { if (0 > dig_alloc_cats(c, (int)n_cats + 1)) return (-1); if (Map->head.Version_Minor == 1) { /* coor format 5.1 */ if (0 >= dig__fread_port_I(c->field, n_cats, &(Map->dig_fp))) return (-2); } else { /* coor format 5.0 */ for (i = 0; i < n_cats; i++) { if (0 >= dig__fread_port_S(&field, 1, &(Map->dig_fp))) return (-2); c->field[i] = (int)field; } } if (0 >= dig__fread_port_I(c->cat, n_cats, &(Map->dig_fp))) return (-2); } } else { if (Map->head.Version_Minor == 1) { /* coor format 5.1 */ size = (off_t) (2 * PORT_INT) * n_cats; } else { /* coor format 5.0 */ size = (off_t) (PORT_SHORT + PORT_INT) * n_cats; } dig_fseek(&(Map->dig_fp), size, SEEK_CUR); } } if (type & GV_POINTS) { n_points = 1; } else { if (0 >= dig__fread_port_I(&n_points, 1, &(Map->dig_fp))) return (-2); } G_debug(3, " n_points = %d", n_points); if (p != NULL) { if (0 > dig_alloc_points(p, n_points + 1)) return (-1); p->n_points = n_points; if (0 >= dig__fread_port_D(p->x, n_points, &(Map->dig_fp))) return (-2); if (0 >= dig__fread_port_D(p->y, n_points, &(Map->dig_fp))) return (-2); if (Map->head.with_z) { if (0 >= dig__fread_port_D(p->z, n_points, &(Map->dig_fp))) return (-2); } else { for (i = 0; i < n_points; i++) p->z[i] = 0.0; } } else { if (Map->head.with_z) size = (off_t) n_points * 3 * PORT_DOUBLE; else size = (off_t) n_points * 2 * PORT_DOUBLE; dig_fseek(&(Map->dig_fp), size, SEEK_CUR); } G_debug(3, " off = %lu", (unsigned long) dig_ftell(&(Map->dig_fp))); if (dead) return 0; return type; }