Exemplo n.º 1
0
/*!
   \brief Read spatial index from sidx file
   Only needed when old vector is opened in update mode

   \param fp pointer to struct gvfile
   \param[in,out] Plus pointer to Plus_head structure

   \return 0
 */
int dig_Rd_spidx(struct gvfile * fp, struct Plus_head *Plus)
{
    G_debug(1, "dig_read_spindx()");

    /* free old trees, init new trees */
    dig_spidx_free(Plus);
    dig_spidx_init(Plus);

    dig_rewind(fp);
    dig_Rd_spidx_head(fp, Plus);
    dig_set_cur_port(&(Plus->spidx_port));

    /* Nodes */
    rtree_load_from_sidx(fp, Plus->Node_spidx_offset,
			 Plus->Node_spidx, Plus->spidx_port.off_t_size);

    /* Lines */
    rtree_load_from_sidx(fp, Plus->Line_spidx_offset,
			 Plus->Line_spidx, Plus->spidx_port.off_t_size);

    /* Areas */
    rtree_load_from_sidx(fp, Plus->Area_spidx_offset,
			 Plus->Area_spidx, Plus->spidx_port.off_t_size);

    /* Isles */
    rtree_load_from_sidx(fp, Plus->Isle_spidx_offset,
			 Plus->Isle_spidx, Plus->spidx_port.off_t_size);

    /* 3D future : */
    /* Faces */
    /* Volumes */
    /* Holes */

    return 0;
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/*!
   \brief Write spatial index to file

   \param[out] fp pointer to struct gvfile
   \param Plus pointer to Plus_head structure

   \return 0
 */
int dig_Wr_spidx(struct gvfile *fp, struct Plus_head *Plus)
{
    G_debug(1, "dig_Wr_spidx()");

    dig_set_cur_port(&(Plus->spidx_port));
    dig_rewind(fp);

    dig_Wr_spidx_head(fp, Plus);

    /* Nodes */
    Plus->Node_spidx_offset =
	rtree_write_to_sidx(fp, dig_ftell(fp), Plus->Node_spidx,
			    Plus->spidx_port.off_t_size);

    /* Lines */
    Plus->Line_spidx_offset =
	rtree_write_to_sidx(fp, dig_ftell(fp), Plus->Line_spidx,
			    Plus->spidx_port.off_t_size);

    /* Areas */
    Plus->Area_spidx_offset =
	rtree_write_to_sidx(fp, dig_ftell(fp), Plus->Area_spidx,
			    Plus->spidx_port.off_t_size);

    /* Isles */
    Plus->Isle_spidx_offset =
	rtree_write_to_sidx(fp, dig_ftell(fp), Plus->Isle_spidx,
			    Plus->spidx_port.off_t_size);

    /* 3D future : */
    /* Faces */
    /* Volumes */
    /* Holes */

    dig_rewind(fp);
    dig_Wr_spidx_head(fp, Plus);	/* rewrite with offsets */

    dig_fflush(fp);
    return 0;
}
Exemplo n.º 5
0
int dig_Wr_Plus_head(struct gvfile * fp, struct Plus_head *ptr)
{
    unsigned char buf[10];
    long length = 142;

    dig_rewind(fp);
    dig_set_cur_port(&(ptr->port));

    /* bytes 1 - 5 */
    buf[0] = GV_TOPO_VER_MAJOR;
    buf[1] = GV_TOPO_VER_MINOR;
    buf[2] = GV_TOPO_EARLIEST_MAJOR;
    buf[3] = GV_TOPO_EARLIEST_MINOR;
    buf[4] = ptr->port.byte_order;
    if (0 >= dig__fwrite_port_C((char *)buf, 5, fp))
	return (-1);

    /* determine required offset size from coor file size */
    if (ptr->coor_size > (off_t)PORT_LONG_MAX) {
	/* can only happen when sizeof(off_t) == 8 */
	ptr->off_t_size = 8;
    }
    else
	ptr->off_t_size = 4;

    /* add a new field with off_t_size after byte_order? */

    /* adjust header size for large files */
    if (ptr->off_t_size == 8) {
	/* 7 offset values and coor file size: add 8 * 4 */
	length += 32;
    }

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fwrite_port_L(&length, 1, fp))
	return (0);

    /* byte 10 : dimension 2D or 3D */
    buf[0] = ptr->with_z;
    if (0 >= dig__fwrite_port_C((char *)buf, 1, fp))
	return (0);

    /* bytes 11 - 58 : bound box */
    if (0 >= dig__fwrite_port_D(&(ptr->box.N), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.S), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.E), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.W), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.T), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.B), 1, fp))
	return (-1);

    /* bytes 59 - 86 : number of structures */
    if (0 >= dig__fwrite_port_P(&(ptr->n_nodes), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_edges), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_areas), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_isles), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_volumes), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_holes), 1, fp))
	return (-1);

    /* bytes 87 - 110 : number of line types */
    if (0 >= dig__fwrite_port_P(&(ptr->n_plines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_llines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_blines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_clines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_flines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_klines), 1, fp))
	return (-1);

    /* bytes 111 - 138 : Offset */
    if (0 >= dig__fwrite_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size))
	return (-1);

    /* bytes 139 - 142 : Coor size and time */
    if (0 >= dig__fwrite_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
	return (-1);

    G_debug(2, "topo body offset %"PRI_OFF_T, dig_ftell(fp));

    return (0);
}
Exemplo n.º 6
0
/*!
  \brief Read Plus_head from file

  \param fp pointer to gvfile structure
  \param[in,out] ptr pointer to Plus_head structure

  \return -1 error
  \return  0 OK 
*/
int dig_Rd_Plus_head(struct gvfile * fp, struct Plus_head *ptr)
{
    unsigned char buf[5];
    int byte_order;

    dig_rewind(fp);

    /* bytes 1 - 5 */
    if (0 >= dig__fread_port_C((char *)buf, 5, fp))
	return (-1);
    ptr->version.topo.major = buf[0];
    ptr->version.topo.minor = buf[1];
    ptr->version.topo.back_major = buf[2];
    ptr->version.topo.back_minor = buf[3];
    byte_order = buf[4];

    G_debug(2,
	    "Topo header: file version %d.%d , supported from GRASS version %d.%d",
	    ptr->version.topo.major, ptr->version.topo.minor, ptr->version.topo.back_major,
	    ptr->version.topo.back_minor);

    G_debug(2, "  byte order %d", byte_order);

    /* check version numbers */
    if (ptr->version.topo.major > GV_TOPO_VER_MAJOR ||
	ptr->version.topo.minor > GV_TOPO_VER_MINOR) {
	/* The file was created by GRASS library with higher version than this one */

	if (ptr->version.topo.back_major > GV_TOPO_VER_MAJOR ||
	    ptr->version.topo.back_minor > GV_TOPO_VER_MINOR) {
	    /* This version of GRASS lib is lower than the oldest which can read this format */
	    G_debug(1, "Topology format version %d.%d",
		    ptr->version.topo.major, ptr->version.topo.minor);
	    G_fatal_error
		(_("This version of GRASS (%d.%d) is too old to read this topology 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 topology format %d.%d of the vector."
		    " Consider to rebuild topology or upgrade GRASS."),
		  ptr->version.topo.major, ptr->version.topo.minor);
    }
    if (ptr->version.topo.major < GV_TOPO_VER_MAJOR ||
	(ptr->version.topo.major == GV_TOPO_VER_MAJOR &&
	 ptr->version.topo.minor < GV_TOPO_VER_MINOR)) {
	/* The file was created by GRASS library with lower version than this one */

	/* This version of GRASS lib can not read this old format */
	G_warning(_("Old topology format version %d.%d is not supported by this release."
		    " Try to rebuild topology using v.build or v.build.all module."),
		  ptr->version.topo.major, ptr->version.topo.minor);
	return (-1);
    }

    /* init Port_info structure and set as default */
    dig_init_portable(&(ptr->port), byte_order);
    dig_set_cur_port(&(ptr->port));

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fread_port_L(&(ptr->head_size), 1, fp))
	return (-1);
    G_debug(2, "  header size %ld", ptr->head_size);

    /* determine required offset size from header size */
    /* this is not safe in case new fields get added in later versions */
    /* better: add a new field with off_t_size after byte_order? */
    if (ptr->head_size >= 142 + 32) /* keep in sync with dig_Wr_Plus_head() */
	ptr->off_t_size = 8;
    else
	ptr->off_t_size = 4;

    if (sizeof(off_t) < ptr->off_t_size) {
	G_warning(_("Vector exceeds supported file size limit"));
	return (-1);
    }

    G_debug(2, "topo off_t size = %d", ptr->off_t_size);

    /* byte 10 : dimension 2D or 3D */
    if (0 >= dig__fread_port_C((char *)buf, 1, fp))
	return (-1);
    ptr->with_z = buf[0];
    G_debug(2, "  with_z %d", ptr->with_z);

    /* bytes 11 - 58 : bound box */
    if (0 >= dig__fread_port_D(&(ptr->box.N), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.S), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.E), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.W), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.T), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.B), 1, fp))
	return (-1);

    /* bytes 59 - 86 : number of structures */
    if (0 >= dig__fread_port_P(&(ptr->n_nodes), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_edges), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_lines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_areas), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_volumes), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_holes), 1, fp))
	return (-1);

    /* bytes 87 - 110 : number of line types */
    if (0 >= dig__fread_port_P(&(ptr->n_plines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_llines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_blines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_clines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_flines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_klines), 1, fp))
	return (-1);

    /* bytes 111 - 138 : Offset */
    if (0 >= dig__fread_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size))
	return (-1);

    /* bytes 139 - 142 : Coor size and time */
    if (0 >= dig__fread_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
	return (-1);

    G_debug(2, "  coor size %"PRI_OFF_T, ptr->coor_size);

    dig_fseek(fp, ptr->head_size, SEEK_SET);

    return (0);
}
Exemplo n.º 7
0
int dig_write_cidx_head(GVFILE * fp, struct Plus_head *plus)
{
    int i;
    unsigned char buf[5];
    long length = 9;

    G_debug(3, "dig_write_cidx_head()");

    dig_rewind(fp);
    dig_set_cur_port(&(plus->cidx_port));

    /* Head of header */
    /* bytes 1 - 5 */
    buf[0] = GV_CIDX_VER_MAJOR;
    buf[1] = GV_CIDX_VER_MINOR;
    buf[2] = GV_CIDX_EARLIEST_MAJOR;
    buf[3] = GV_CIDX_EARLIEST_MINOR;
    buf[4] = plus->cidx_port.byte_order;
    if (0 >= dig__fwrite_port_C(buf, 5, fp))
	return (-1);

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fwrite_port_L(&length, 1, fp))
	return (0);

    /* Body of header - info about all fields */
    /* Number of fields */
    if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
	return (-1);

    for (i = 0; i < plus->n_cidx; i++) {
	int t;
	struct Cat_index *ci;

	ci = &(plus->cidx[i]);

	G_debug(3, "cidx %d head offset: %ld", i, dig_ftell(fp));

	/* Field number */
	if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
	    return (-1);

	/* Number of categories */
	if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
	    return (-1);

	/* Number of unique categories */
	if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
	    return (-1);

	/* Number of types */
	if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
	    return (-1);

	/* Types */
	for (t = 0; t < ci->n_types; t++) {
	    int wtype;

	    /* type */
	    wtype = dig_type_to_store(ci->type[t][0]);
	    if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
		return (-1);

	    /* number of items */
	    if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
		return (-1);

	}

	/* Offset */
	if (0 >= dig__fwrite_port_L(&(ci->offset), 1, fp))
	    return (0);
	G_debug(3, "cidx %d offset: %ld", i, ci->offset);
    }

    G_debug(3, "cidx body offset %ld", dig_ftell(fp));

    return (0);
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
0
/*!
   \brief Write spatial index header to file

   \param[in,out] fp pointer to struct gvfile
   \param ptr pointer to Plus_head structure

   \return 0 on success
   \return -1 on error
 */
int dig_Wr_spidx_head(struct gvfile * fp, struct Plus_head *ptr)
{
    unsigned char buf[6];
    long length = 81;		/* header length in bytes */
    struct RTree *t;
    size_t size;

    dig_rewind(fp);
    dig_set_cur_port(&(ptr->spidx_port));

    /* use ptr->off_t_size = 4 if possible */
    if (sizeof(off_t) > 4) {
	size = ptr->Node_spidx->n_nodes * ptr->Node_spidx->nodesize;
	size += ptr->Line_spidx->n_nodes * ptr->Line_spidx->nodesize;
	size += ptr->Area_spidx->n_nodes * ptr->Area_spidx->nodesize;
	size += ptr->Isle_spidx->n_nodes * ptr->Isle_spidx->nodesize;

	if (size < PORT_INT_MAX)
	    ptr->spidx_port.off_t_size = 4;
	else
	    ptr->spidx_port.off_t_size = 8;
    }
    else
	ptr->spidx_port.off_t_size = 4;

    /* bytes 1 - 6 */
    buf[0] = GV_SIDX_VER_MAJOR;
    buf[1] = GV_SIDX_VER_MINOR;
    buf[2] = GV_SIDX_EARLIEST_MAJOR;
    buf[3] = GV_SIDX_EARLIEST_MINOR;
    buf[4] = ptr->spidx_port.byte_order;
    buf[5] = (unsigned char)ptr->spidx_port.off_t_size;
    if (0 >= dig__fwrite_port_C((const char *)buf, 6, fp))
	return (-1);

    /* adjust header size for large files */
    if (ptr->spidx_port.off_t_size == 4) {
	if (ptr->off_t_size == 4)
	    length = 113;
	else if (ptr->off_t_size == 8)
	    length = 117;
	else
            G_fatal_error(_("Topology file must be written before spatial index file"));
    }
    else if (ptr->spidx_port.off_t_size == 8) {
	if (ptr->off_t_size == 4)
	    length = 141;
	else if (ptr->off_t_size == 8)
	    length = 145;
	else
            G_fatal_error(_("Topology file must be written before spatial index file"));
    }

    /* bytes 7 - 10 : header size */
    if (0 >= dig__fwrite_port_L(&length, 1, fp))
	return (0);

    ptr->spidx_head_size = length;

    /* byte 11 : dimension 2D or 3D */
    buf[0] = ptr->spidx_with_z;
    if (0 >= dig__fwrite_port_C((const char *)buf, 1, fp))
	return (-1);

    /* identical for all spatial indices: */
    t = ptr->Node_spidx;
    /* byte 12 : n dimensions */
    if (0 >= dig__fwrite_port_C((const char *)&(t->ndims), 1, fp))
	return (-1);
    /* byte 13 : n sides */
    if (0 >= dig__fwrite_port_C((const char *)&(t->nsides), 1, fp))
	return (-1);
    /* bytes 14 - 17 : nodesize */
    if (0 >= dig__fwrite_port_I(&(t->nodesize), 1, fp))
	return (-1);
    /* bytes 18 - 21 : nodecard */
    if (0 >= dig__fwrite_port_I(&(t->nodecard), 1, fp))
	return (-1);
    /* bytes 22 - 25 : leafcard */
    if (0 >= dig__fwrite_port_I(&(t->leafcard), 1, fp))
	return (-1);
    /* bytes 26 - 29 : min node fill */
    if (0 >= dig__fwrite_port_I(&(t->min_node_fill), 1, fp))
	return (-1);
    /* bytes 30 - 33 : min leaf fill */
    if (0 >= dig__fwrite_port_I(&(t->min_leaf_fill), 1, fp))
	return (-1);

    /* for each spatial index : */

    /* Node spatial index */
    /* bytes 34 - 37 : n nodes */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 38 - 41 : n leafs */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 42 - 45 : n levels */
    if (0 >= dig__fwrite_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 46 - 49 (LFS 53) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Node_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);

    /* Line spatial index */
    t = ptr->Line_spidx;
    /* bytes 50 - 53 (LFS 54 - 57) : n nodes */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 54 - 57 (LFS 58 - 61) : n leafs */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 58 - 61 (LFS 62 - 65) : n levels */
    if (0 >= dig__fwrite_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 62 - 65 (LFS 66 - 73) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Line_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);

    /* Area spatial index */
    t = ptr->Area_spidx;
    /* bytes 66 - 69 (LFS 74 - 77) : n nodes */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 70 - 73 (LFS 78 - 81) : n leafs */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 74 - 77 (LFS 82 - 85) : n levels */
    if (0 >= dig__fwrite_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 78 - 81 (LFS 86 - 93) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Area_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);

    /* Isle spatial index */
    t = ptr->Isle_spidx;
    /* bytes 82 - 85 (LFS 94 - 97) : n nodes */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 86 - 89 (LFS 98 - 101) : n leafs */
    if (0 >= dig__fwrite_port_I((const int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 90 - 93 (LFS 102 - 105) : n levels */
    if (0 >= dig__fwrite_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 94 - 97 (LFS 106 - 113) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Isle_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);

    /* 3D future : */
    /* Face spatial index */
    /* bytes 98 - 101 (LFS 114 - 121) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Face_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);
    /* ptr->Face_spidx->rootpos = ptr->Face_spidx_offset; */

    /* Volume spatial index */
    /* bytes 102 - 105 (LFS 122 - 129) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Volume_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);
    /* ptr->Volume_spidx->rootpos = ptr->Volume_spidx_offset; */

    /* Hole spatial index */
    /* bytes 106 - 109 (LFS 130 - 137) : root node offset */
    if (0 >=
	dig__fwrite_port_O(&(ptr->Hole_spidx_offset), 1, fp,
			   ptr->spidx_port.off_t_size))
	return (-1);
    /* ptr->Hole_spidx->rootpos = ptr->Hole_spidx_offset; */

    G_debug(3, "spidx offset node = %lu line = %lu, area = %lu isle = %lu",
	    (long unsigned)ptr->Node_spidx_offset,
	    (long unsigned)ptr->Line_spidx_offset,
	    (long unsigned)ptr->Area_spidx_offset,
	    (long unsigned)ptr->Isle_spidx_offset);

    /* coor file size : bytes 110 - 113 (117) (LFS: 138 - 141 (145)) */
    if (0 >= dig__fwrite_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
	return (-1);

    length = (long unsigned)dig_ftell(fp);
    G_debug(1, "spidx body offset %lu", length);

    if (ptr->spidx_head_size != length)
	G_fatal_error("wrong sidx head length %ld", ptr->spidx_head_size);

    return (0);
}
Exemplo n.º 10
0
/*!
   \brief Read spatial index header from sidx file

   \param fp pointer to struct gvfile
   \param[in,out] ptr pointer to Plus_head structure

   \return 0 on success
   \return -1 on error
 */
int dig_Rd_spidx_head(struct gvfile * fp, struct Plus_head *ptr)
{
    unsigned char buf[6];
    int byte_order;
    struct RTree *t;

    dig_rewind(fp);

    /* bytes 1 - 6 */
    if (0 >= dig__fread_port_C((char *)buf, 6, fp))
	return (-1);
    ptr->version.spidx.major = buf[0];
    ptr->version.spidx.minor = buf[1];
    ptr->version.spidx.back_major = buf[2];
    ptr->version.spidx.back_minor = buf[3];
    byte_order = buf[4];
    ptr->spidx_port.off_t_size = buf[5];

    G_debug(2,
	    "Spidx header: file version %d.%d , supported from GRASS version %d.%d",
	    ptr->version.spidx.major, ptr->version.spidx.minor,
	    ptr->version.spidx.back_major, ptr->version.spidx.back_minor);

    G_debug(2, "  byte order %d", byte_order);

    /* check version numbers */
    if (ptr->version.spidx.major > GV_SIDX_VER_MAJOR ||
	ptr->version.spidx.minor > GV_SIDX_VER_MINOR) {
	/* The file was created by GRASS library with higher version than this one */

	if (ptr->version.spidx.back_major > GV_SIDX_VER_MAJOR ||
	    ptr->version.spidx.back_minor > GV_SIDX_VER_MINOR) {
	    /* This version of GRASS lib is lower than the oldest which can read this format */
	    G_debug(1, "Spatial index format version %d.%d",
		    ptr->version.spidx.major, ptr->version.spidx.minor);
	    G_fatal_error
		(_("This version of GRASS (%d.%d) is too old to read this spatial 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 "
		    "spatial index format %d.%d of the vector."
		    " Consider to rebuild topology or upgrade GRASS."),
		  ptr->version.spidx.major, ptr->version.spidx.minor);
    }
    if (ptr->version.spidx.major < GV_SIDX_VER_MAJOR ||
	(ptr->version.spidx.major == GV_SIDX_VER_MAJOR &&
	ptr->version.spidx.minor < GV_SIDX_VER_MINOR)) {
	/* The file was created by GRASS library with lower version than this one */
	    G_fatal_error(_("Spatial index format version %d.%d is not "
			    "supported by this release."
			    " Please rebuild topology."),
			  ptr->version.spidx.major, ptr->version.spidx.minor);
	    return (-1);
    }

    /* can this library read the sidx file ? */
    if (ptr->spidx_port.off_t_size > (int)sizeof(off_t)) {
	G_fatal_error("Spatial index was written with LFS but this "
		      "GRASS version does not support LFS. "
		      "Please get a GRASS version with LFS support.");
    }

    dig_init_portable(&(ptr->spidx_port), byte_order);
    dig_set_cur_port(&(ptr->spidx_port));

    /* bytes 7 - 10 : header size */
    if (0 >= dig__fread_port_L(&(ptr->spidx_head_size), 1, fp))
	return (-1);
    G_debug(2, "  header size %ld", ptr->spidx_head_size);

    /* byte 11 : dimension 2D or 3D */
    if (0 >= dig__fread_port_C((char *)buf, 1, fp))
	return (-1);
    ptr->spidx_with_z = buf[0];
    G_debug(2, "  with_z %d", ptr->spidx_with_z);

    /* identical for all spatial indices: */
    t = ptr->Node_spidx;
    /* byte 12 : n dimensions */
    if (0 >= dig__fread_port_C((char *)&(t->ndims), 1, fp))
	return (-1);
    ptr->Node_spidx->ndims = t->ndims;
    ptr->Line_spidx->ndims = t->ndims;
    ptr->Area_spidx->ndims = t->ndims;
    ptr->Isle_spidx->ndims = t->ndims;

    /* byte 13 : n sides */
    if (0 >= dig__fread_port_C((char *)&(t->nsides), 1, fp))
	return (-1);
    ptr->Node_spidx->nsides = t->nsides;
    ptr->Line_spidx->nsides = t->nsides;
    ptr->Area_spidx->nsides = t->nsides;
    ptr->Isle_spidx->nsides = t->nsides;

    /* bytes 14 - 17 : nodesize */
    if (0 >= dig__fread_port_I(&(t->nodesize), 1, fp))
	return (-1);
    ptr->Node_spidx->nodesize = t->nodesize;
    ptr->Line_spidx->nodesize = t->nodesize;
    ptr->Area_spidx->nodesize = t->nodesize;
    ptr->Isle_spidx->nodesize = t->nodesize;

    /* bytes 18 - 21 : nodecard */
    if (0 >= dig__fread_port_I(&(t->nodecard), 1, fp))
	return (-1);
    ptr->Node_spidx->nodecard = t->nodecard;
    ptr->Line_spidx->nodecard = t->nodecard;
    ptr->Area_spidx->nodecard = t->nodecard;
    ptr->Isle_spidx->nodecard = t->nodecard;

    /* bytes 22 - 25 : leafcard */
    if (0 >= dig__fread_port_I(&(t->leafcard), 1, fp))
	return (-1);
    ptr->Node_spidx->leafcard = t->leafcard;
    ptr->Line_spidx->leafcard = t->leafcard;
    ptr->Area_spidx->leafcard = t->leafcard;
    ptr->Isle_spidx->leafcard = t->leafcard;

    /* bytes 26 - 29 : min node fill */
    if (0 >= dig__fread_port_I(&(t->min_node_fill), 1, fp))
	return (-1);
    ptr->Node_spidx->min_node_fill = t->min_node_fill;
    ptr->Line_spidx->min_node_fill = t->min_node_fill;
    ptr->Area_spidx->min_node_fill = t->min_node_fill;
    ptr->Isle_spidx->min_node_fill = t->min_node_fill;

    /* bytes 30 - 33 : min leaf fill */
    if (0 >= dig__fread_port_I(&(t->min_leaf_fill), 1, fp))
	return (-1);
    ptr->Node_spidx->min_leaf_fill = t->min_leaf_fill;
    ptr->Line_spidx->min_leaf_fill = t->min_leaf_fill;
    ptr->Area_spidx->min_leaf_fill = t->min_leaf_fill;
    ptr->Isle_spidx->min_leaf_fill = t->min_leaf_fill;

    /* for each spatial index : */

    /* Node spatial index */
    /* bytes 34 - 37 : n nodes */
    if (0 >= dig__fread_port_I((int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 38 - 41 : n leafs */
    if (0 >= dig__fread_port_I((int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 42 - 45 : n levels */
    if (0 >= dig__fread_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 46 - 49 (LFS 53) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Node_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    t->rootpos = ptr->Node_spidx_offset;

    /* Line spatial index */
    t = ptr->Line_spidx;
    /* bytes 50 - 53 (LFS 54 - 57) : n nodes */
    if (0 >= dig__fread_port_I((int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 54 - 57 (LFS 58 - 61) : n leafs */
    if (0 >= dig__fread_port_I((int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 58 - 61 (LFS 62 - 65) : n levels */
    if (0 >= dig__fread_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 62 - 65 (LFS 66 - 73) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Line_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    ptr->Line_spidx->rootpos = ptr->Line_spidx_offset;

    /* Area spatial index */
    t = ptr->Area_spidx;
    /* bytes 66 - 69 (LFS 74 - 77) : n nodes */
    if (0 >= dig__fread_port_I((int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 70 - 73 (LFS 78 - 81) : n leafs */
    if (0 >= dig__fread_port_I((int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 74 - 77 (LFS 82 - 85) : n levels */
    if (0 >= dig__fread_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 78 - 81 (LFS 86 - 93) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Area_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    ptr->Area_spidx->rootpos = ptr->Area_spidx_offset;

    /* Isle spatial index */
    t = ptr->Isle_spidx;
    /* bytes 82 - 85 (LFS 94 - 97) : n nodes */
    if (0 >= dig__fread_port_I((int *)&(t->n_nodes), 1, fp))
	return (-1);
    /* bytes 86 - 89 (LFS 98 - 101) : n leafs */
    if (0 >= dig__fread_port_I((int *)&(t->n_leafs), 1, fp))
	return (-1);
    /* bytes 90 - 93 (LFS 102 - 105) : n levels */
    if (0 >= dig__fread_port_I(&(t->rootlevel), 1, fp))
	return (-1);
    /* bytes 94 - 97 (LFS 106 - 113) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Isle_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    ptr->Isle_spidx->rootpos = ptr->Isle_spidx_offset;

    /* 3D future : */
    /* Face spatial index */
    /* bytes 98 - 101 (LFS 114 - 121) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Face_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    /* ptr->Face_spidx->rootpos = ptr->Face_spidx_offset; */

    /* Volume spatial index */
    /* bytes 102 - 105 (LFS 122 - 129) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Volume_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    /* ptr->Volume_spidx->rootpos = ptr->Volume_spidx_offset; */

    /* Hole spatial index */
    /* bytes 106 - 109 (LFS 130 - 137) : root node offset */
    if (0 >=
	dig__fread_port_O(&(ptr->Hole_spidx_offset), 1, fp,
			  ptr->spidx_port.off_t_size))
	return (-1);
    /* ptr->Hole_spidx->rootpos = ptr->Hole_spidx_offset; */

    /* coor file size : bytes 110 - 113 (117) (LFS: 138 - 145) */
    if (ptr->off_t_size == -1)
        ptr->off_t_size = ptr->spidx_port.off_t_size;
    if (0 >= dig__fread_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
	return (-1);
    G_debug(2, "  coor size %lu", (long unsigned)ptr->coor_size);

    dig_fseek(fp, ptr->spidx_head_size, SEEK_SET);

    return (0);
}
Exemplo n.º 11
0
/*!
   \brief Search spatial index file
   Can't use regular RTreeSearch() here because sidx must be read
   with dig__fread_port_*() functions

   \param t pointer to RTree
   \param r search rectangle
   \param shcb user-provided callback
   \param cbarg argument for shcb
   \param Plus pointer to Plus_head structure

   \return number of qualifying rectangles
 */
int rtree_search(struct RTree *t, struct RTree_Rect *r,
                 SearchHitCallback shcb, void *cbarg, struct Plus_head *Plus)
{
    int hitCount = 0, found;
    /* int j, maxcard; */
    int i;
    struct spidxpstack s[MAXLEVEL];
    int top = 0, level;
    off_t lastpos;

    assert(r);
    assert(t);

    /* stack size of t->rootlevel + 1 is enough because of depth first search */
    /* only one node per level on stack at any given time */

    dig_set_cur_port(&(Plus->spidx_port));

    /* add root node position to stack */
    s[top].sn = rtree_get_node(t->rootpos, t->rootlevel, t, Plus);
#if 0
    dig_fseek(&(Plus->spidx_fp), t->rootpos, SEEK_SET);
    /* read with dig__fread_port_* fns */
    dig__fread_port_I(&(s[top].sn.count), 1, &(Plus->spidx_fp));
    dig__fread_port_I(&(s[top].sn.level), 1, &(Plus->spidx_fp));
    maxcard = t->rootlevel ? t->nodecard : t->leafcard;
    for (j = 0; j < maxcard; j++) {
	dig__fread_port_D(s[top].sn.branch[j].rect.boundary, NUMSIDES,
			  &(Plus->spidx_fp));
	dig__fread_port_O(&(s[top].pos[j]), 1, &(Plus->spidx_fp),
			  Plus->spidx_port.off_t_size);
	/* leaf node: vector object IDs are stored in child.id */
	if (s[top].sn.level == 0) {
	    s[top].sn.branch[j].child.id = (int)s[top].pos[j];
	}
	else {
	    s[top].sn.branch[j].child.pos = s[top].pos[j];
	}
    }
#endif

    s[top].branch_id = i = 0;

    while (top >= 0) {
	level = s[top].sn->level;
	if (level > 0) {	/* this is an internal node in the tree */
	    found = 1;
	    for (i = s[top].branch_id; i < t->nodecard; i++) {
		lastpos = s[top].sn->branch[i].child.pos;
		if (lastpos > 0 &&
		    RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) {
		    s[top++].branch_id = i + 1;
		    s[top].sn = rtree_get_node(lastpos, level - 1, t, Plus);
		    
#if 0
		    dig_fseek(&(Plus->spidx_fp), lastpos, SEEK_SET);
		    /* read with dig__fread_port_* fns */
		    dig__fread_port_I(&(s[top].sn.count), 1,
				      &(Plus->spidx_fp));
		    dig__fread_port_I(&(s[top].sn.level), 1,
				      &(Plus->spidx_fp));
		    maxcard = s[top].sn.level ? t->nodecard : t->leafcard;
		    for (j = 0; j < maxcard; j++) {
			dig__fread_port_D(s[top].sn.branch[j].rect.boundary,
					  NUMSIDES, &(Plus->spidx_fp));
			dig__fread_port_O(&(s[top].pos[j]), 1,
					  &(Plus->spidx_fp),
					  Plus->spidx_port.off_t_size);
			if (s[top].sn.level == 0) {
			    s[top].sn.branch[j].child.id = (int)s[top].pos[j];
			}
			else {
			    s[top].sn.branch[j].child.pos = s[top].pos[j];
			}
		    }
#endif
		    s[top].branch_id = 0;
		    found = 0;
		    break;
		}
	    }
	    if (found) {
		/* nothing else found, go back up */
		s[top].branch_id = t->nodecard;
		top--;
	    }
	}
	else {			/* this is a leaf node */
	    for (i = 0; i < t->leafcard; i++) {
		if (s[top].sn->branch[i].child.id &&
		    RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) {
		    hitCount++;
		    if (shcb) {	/* call the user-provided callback */
			if (!shcb((int)s[top].sn->branch[i].child.id,
				  &s[top].sn->branch[i].rect, cbarg)) {
			    /* callback wants to terminate search early */
			    return hitCount;
			}
		    }
		}
	    }
	    top--;
	}
    }

    return hitCount;
}
Exemplo n.º 12
0
int dig_write_cidx_head(struct gvfile * fp, struct Plus_head *plus)
{
    int i;
    unsigned char buf[5];
    long length = 9;

    G_debug(3, "dig_write_cidx_head()");

    dig_rewind(fp);
    dig_set_cur_port(&(plus->cidx_port));

    /* Head of header */
    /* bytes 1 - 5 */
    buf[0] = GV_CIDX_VER_MAJOR;
    buf[1] = GV_CIDX_VER_MINOR;
    buf[2] = GV_CIDX_EARLIEST_MAJOR;
    buf[3] = GV_CIDX_EARLIEST_MINOR;
    buf[4] = plus->cidx_port.byte_order;
    if (0 >= dig__fwrite_port_C((const char *)buf, 5, fp))
	return (-1);

    /* get required offset size */
    if (plus->off_t_size == 0) {
	/* should not happen, topo is written first */
	if (plus->coor_size > (off_t)PORT_LONG_MAX)
	    plus->off_t_size = 8;
	else
	    plus->off_t_size = 4;
    }

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fwrite_port_L(&length, 1, fp))
	return (0);

    /* Body of header - info about all fields */
    /* Number of fields */
    if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
	return (-1);

    for (i = 0; i < plus->n_cidx; i++) {
	int t;
	struct Cat_index *ci;

	ci = &(plus->cidx[i]);

	G_debug(3, "cidx %d head offset: %"PRI_OFF_T, i, dig_ftell(fp));

	/* Field number */
	if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
	    return (-1);

	/* Number of categories */
	if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
	    return (-1);

	/* Number of unique categories */
	if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
	    return (-1);

	/* Number of types */
	if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
	    return (-1);

	/* Types */
	for (t = 0; t < ci->n_types; t++) {
	    int wtype;

	    /* type */
	    wtype = dig_type_to_store(ci->type[t][0]);
	    if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
		return (-1);

	    /* number of items */
	    if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
		return (-1);

	}

	/* Offset */
	if (0 >= dig__fwrite_port_O(&(ci->offset), 1, fp, plus->off_t_size))
	    return (0);
	G_debug(3, "cidx %d offset: %"PRI_OFF_T, i, ci->offset);
    }

    G_debug(3, "cidx body offset %"PRI_OFF_T, dig_ftell(fp));

    return (0);
}
Exemplo n.º 13
0
/*!
   \brief Save feature index file for vector map

   \param Map pointer to Map_info structure
   \param offset pointer to Format_info_offset struct
   (see Format_info_ogr and Format_info_pg struct for implementation issues)

   \return 1 on success
   \return 0 on error
 */
int Vect_save_fidx(struct Map_info *Map,
                   struct Format_info_offset *offset)
{
#ifdef HAVE_OGR
    char fname[GPATH_MAX], elem[GPATH_MAX];
    char buf[5];
    long length;
    struct gvfile fp;
    struct Port_info port;

    if (strcmp(Map->mapset, G_mapset()) != 0 ||
            Map->support_updated == FALSE ||
            Map->plus.built != GV_BUILD_ALL)
        return 1;

    length = 9;

    sprintf(elem, "%s/%s", GV_DIRECTORY, Map->name);
    G_file_name(fname, elem, GV_FIDX_ELEMENT, Map->mapset);
    G_debug(4, "Open fidx: %s", fname);
    dig_file_init(&fp);
    fp.file = fopen(fname, "w");
    if (fp.file == NULL) {
        G_warning(_("Unable to open fidx file for write <%s>"), fname);
        return 0;
    }

    dig_init_portable(&port, dig__byte_order_out());
    dig_set_cur_port(&port);

    /* Header */
    /* bytes 1 - 5 */
    buf[0] = 5;
    buf[1] = 0;
    buf[2] = 5;
    buf[3] = 0;
    buf[4] = (char)dig__byte_order_out();
    if (0 >= dig__fwrite_port_C(buf, 5, &fp))
        return 0;

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fwrite_port_L(&length, 1, &fp))
        return 0;

    /* Body */
    /* number of records  */
    if (0 >= dig__fwrite_port_I(&(offset->array_num), 1, &fp))
        return 0;

    /* offsets */
    if (0 >= dig__fwrite_port_I(offset->array,
                                offset->array_num, &fp))
        return 0;

    G_debug(3, "Vect_save_fidx(): offset_num = %d", offset->array_num);

    fclose(fp.file);

    return 1;
#else
    G_fatal_error(_("GRASS is not compiled with OGR support"));
    return 0;
#endif
}
Exemplo n.º 14
0
/* read old 3.0 or 4.0 dig file into array 
   returns number of elements read into array
   or -1 on error */
int read_dig(FILE * Digin, struct Map_info *Mapout,
	     struct Line **plines, int endian, int att)
{
    char buf[100];
    struct dig_head In_head;
    int lalloc, line = 0, type, portable = 1;
    int npoints = 0, nlines = 0, nbounds = 0;
    int ndpoints = 0, ndlines = 0, ndbounds = 0, nunknown = 0;
    struct Line *lines;
    struct line_pnts *nline;
    struct line_cats *cat_out;
    double dbuf;
    int ibuf;
    long lbuf;
    struct gvfile gvf;

    dig_file_init(&gvf);
    gvf.file = Digin;

    Vect__init_head(Mapout);
    /* set conversion matrices */
    dig_init_portable(&(In_head.port), endian);

    /* Version 3 dig files were not portable and some version 4 
     * files may be also non portable */

    G_message(_("Reading dig file..."));

    /* read and copy head */
    dig_fseek(&gvf, 0L, SEEK_SET);	/* set to beginning */

    if (0 >= dig__fread_port_C(buf, DIG4_ORGAN_LEN, &gvf))
	return -1;
    buf[DIG4_ORGAN_LEN - 1] = '\0';
    Vect_set_organization(Mapout, buf);

    if (0 >= dig__fread_port_C(buf, DIG4_DATE_LEN, &gvf))
	return -1;
    buf[DIG4_DATE_LEN - 1] = '\0';
    Vect_set_date(Mapout, buf);

    if (0 >= dig__fread_port_C(buf, DIG4_YOUR_NAME_LEN, &gvf))
	return -1;
    buf[DIG4_YOUR_NAME_LEN - 1] = '\0';
    Vect_set_person(Mapout, buf);

    if (0 >= dig__fread_port_C(buf, DIG4_MAP_NAME_LEN, &gvf))
	return -1;
    buf[DIG4_MAP_NAME_LEN - 1] = '\0';
    Vect_set_map_name(Mapout, buf);

    if (0 >= dig__fread_port_C(buf, DIG4_SOURCE_DATE_LEN, &gvf))
	return -1;
    buf[DIG4_SOURCE_DATE_LEN - 1] = '\0';
    Vect_set_map_date(Mapout, buf);

    if (0 >= dig__fread_port_C(buf, DIG4_LINE_3_LEN, &gvf))
	return -1;
    buf[DIG4_LINE_3_LEN - 1] = '\0';
    Vect_set_comment(Mapout, buf);

    if (0 >= dig__fread_port_C(buf, VERS_4_DATA_SIZE, &gvf))
	return -1;

    if (buf[0] != '%' || buf[1] != '%') {	/* Version3.0 */
	In_head.Version_Major = 3;
	portable = 0;		/* input vector is not portable format */
	G_message(_("Input file is version 3."));
    }
    else {
	In_head.Version_Major = 4;
	G_message(_("Input file is version 4."));
	/* determine if in portable format or not */
	if (buf[6] == 1 && (~buf[6] & 0xff) == (buf[7] & 0xff)) {	/* portable ? */
	    portable = 1;	/* input vector is portable format */
	}
	else {
	    portable = 0;	/* input vector is not portable format */
	}
    }
    if (portable == 1) {
	G_message(_("Input file is portable."));
    }
    else {
	G_warning(_("Input file is not portable. "
		    "We will attempt to convert anyway but conversion may fail. "
		    "Please read manual for detail information."));
    }

    /* set Cur_Head because it is used by dig__*_convert()
       called by dig__fread_port_*() */
    dig_set_cur_port(&(In_head.port));

    if (0 >= dig__fread_port_L(&lbuf, 1, &gvf))
	return -1;
    Vect_set_scale(Mapout, (int)lbuf);
    if (0 >= dig__fread_port_I(&ibuf, 1, &gvf))
	return -1;
    Vect_set_zone(Mapout, ibuf);
    if (0 >= dig__fread_port_D(&dbuf, 1, &gvf))
	return -1;		/* W */
    if (0 >= dig__fread_port_D(&dbuf, 1, &gvf))
	return -1;		/* E */
    if (0 >= dig__fread_port_D(&dbuf, 1, &gvf))
	return -1;		/* S */
    if (0 >= dig__fread_port_D(&dbuf, 1, &gvf))
	return -1;		/* N */
    if (0 >= dig__fread_port_D(&dbuf, 1, &gvf))
	return -1;
    Vect_set_thresh(Mapout, dbuf);

    /* reading dig file body (elements) */
    nline = Vect_new_line_struct();
    cat_out = Vect_new_cats_struct();

    lalloc = 0;
    lines = NULL;

    line = 0;
    while (1) {
	type = read_line(&gvf, nline);
	G_debug(3, "read line = %d, type = %d", line, type);
	if (type == -2)
	    break;		/* EOF */
	switch (type) {
	case GV_POINT:
	    npoints++;
	    break;
	case GV_LINE:
	    nlines++;
	    break;
	case GV_BOUNDARY:
	    nbounds++;
	    break;
	case 0:		/* dead */
	    break;
	default:
	    nunknown++;
	    break;
	}
	if (!(type & (GV_POINT | GV_LINE | GV_BOUNDARY)))
	    continue;

	if ((type & GV_BOUNDARY) || !att) {
	    Vect_write_line(Mapout, type, nline, cat_out);
	    /* reset In_head */
	    dig_set_cur_port(&(In_head.port));
	}
	else {			/* GV_POINT or GV_LINE */
	    if (line >= lalloc) {
		lalloc += 10000;
		lines =
		    (struct Line *)G_realloc(lines,
					     lalloc * sizeof(struct Line));
	    }
	    lines[line].type = type;
	    lines[line].n_points = nline->n_points;
	    lines[line].cat = -1;
	    lines[line].x =
		(double *)G_malloc(nline->n_points * sizeof(double));
	    lines[line].y =
		(double *)G_malloc(nline->n_points * sizeof(double));
	    memcpy((void *)lines[line].x, (void *)nline->x,
		   nline->n_points * sizeof(double));
	    memcpy((void *)lines[line].y, (void *)nline->y,
		   nline->n_points * sizeof(double));
	    line++;
	}
    }
    if (att) {
	G_message(_("[%d] points read to memory"), npoints);
	G_message(_("[%d] lines read to memory"), nlines);
    }
    else {
	G_message(_("[%d] points read and written to output"), npoints);
	G_message(_("[%d] lines read and written to output"), nlines);
    }
    G_message(_("[%d] area boundaries read and written to output"), nbounds);
    G_message(_("[%d] dead points skipped"), ndpoints);
    G_message(_("[%d] dead lines skipped"), ndlines);
    G_message(_("[%d] dead area boundaries skipped"), ndbounds);
    G_message(_("[%d] elements of unknown type skipped"), nunknown);

    G_message(_("[%d] elements read to memory"), line);

    *plines = lines;
    return (line);
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
/*!
  \brief Open feature index file
  
  \param[in,out] Map pointer to Map_info struct
  \param[out] offset pointer to Format_info_offset (OGR or PG)
  
  \return 0 on success
  \return -1 on error
*/
int Vect_open_fidx(struct Map_info *Map, struct Format_info_offset *offset)
{
    char elem[GPATH_MAX];
    char buf[5];		/* used for format version */
    long length;
    int Version_Major, Version_Minor, Back_Major, Back_Minor, byte_order;
    
    struct gvfile fp;
    struct Port_info port;
    
    G_debug(1, "Vect_open_fidx(): name = %s mapset = %s format = %d",
	    Map->name, Map->mapset, Map->format);
    
    sprintf(elem, "%s/%s", GV_DIRECTORY, Map->name);
    dig_file_init(&fp);
    fp.file = G_fopen_old(elem, GV_FIDX_ELEMENT, Map->mapset);
    if (fp.file == NULL) {
        G_debug(1, "unable to open fidx file for vector map <%s>",
                Vect_get_full_name(Map));
	return -1;
    }

    /* Header */
    if (0 >= dig__fread_port_C(buf, 5, &fp))
	return -1;
    Version_Major = buf[0];
    Version_Minor = buf[1];
    Back_Major    = buf[2];
    Back_Minor    = buf[3];
    byte_order    = buf[4];
    
    /* check version numbers */
    if (Version_Major > 5 || Version_Minor > 0) {
	if (Back_Major > 5 || Back_Minor > 0) {
	    G_fatal_error(_("Feature index format version %d.%d is not supported by this release."
			   " Try to rebuild topology or upgrade GRASS."),
			  Version_Major, Version_Minor);
	    return -1;
	}
	G_warning(_("Your GRASS version does not fully support feature index format %d.%d of the vector."
		   " Consider to rebuild topology or upgrade GRASS."),
		  Version_Major, Version_Minor);
    }

    dig_init_portable(&port, byte_order);
    dig_set_cur_port(&port);

    /* Body */
    /* bytes 6 - 9 : header size */
    if (0 >= dig__fread_port_L(&length, 1, &fp))
	return -1;
    G_debug(4, "  header size %ld", length);

    G_fseek(fp.file, length, SEEK_SET);

    /* number of records  */
    if (0 >= dig__fread_port_I(&(offset->array_num), 1, &fp))
	return -1;
    
    /* alloc space */
    offset->array = (int *) G_malloc(offset->array_num * sizeof(int));
    offset->array_alloc = offset->array_num;
    
    /* offsets */
    if (0 >= dig__fread_port_I(offset->array,
			       offset->array_num, &fp))
	return -1;

    fclose(fp.file);

    G_debug(3, "%d records read from fidx", offset->array_num);

    return 0;
}