예제 #1
0
int dig_Wr_P_node(struct Plus_head *Plus, int n, struct gvfile * fp)
{
    int i, n_edges = 0;
    struct P_node *ptr;

    G_debug(4, "dig_Wr_P_node()");
    ptr = Plus->Node[n];

    /* If NULL i.e. dead write just 0 instead of number of lines */
    if (ptr == NULL) {
	G_debug(4, "    node is dead -> write 0 only");
	i = 0;
	if (0 >= dig__fwrite_port_P(&i, 1, fp))
	    return (-1);
	return 0;
    }

    if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
	return (-1);

    if (ptr->n_lines) {
	if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
	    return (-1);
	if (0 >= dig__fwrite_port_F(ptr->angles, ptr->n_lines, fp))
	    return (-1);
    }

    if (Plus->with_z)
	if (0 >= dig__fwrite_port_P(&n_edges, 1, fp))	/* reserved for edges */
	    return (-1);

    /* here will be edges */

    if (0 >= dig__fwrite_port_D(&(ptr->x), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->y), 1, fp))
	return (-1);

    if (Plus->with_z)
	if (0 >= dig__fwrite_port_D(&(ptr->z), 1, fp))
	    return (-1);

    return (0);
}
예제 #2
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);
}
예제 #3
0
static off_t rtree_write_from_file(struct gvfile *fp, off_t startpos,
				 struct RTree *t, int off_t_size)
{
    off_t nextfreepos = startpos;
    int sidx_nodesize, sidx_leafsize;
    struct RTree_Node *n;
    int i, j, writeout, maxcard;
    static struct spidxstack *s = NULL;
    int top = 0;
    
    if (!s) {
	s = G_malloc(MAXLEVEL * sizeof(struct spidxstack));
	for (i = 0; i < MAXLEVEL; i++) {
	    s[i].sn.branch = G_malloc(MAXCARD * sizeof(struct RTree_Branch));
	    for (j = 0; j < MAXCARD; j++) {
		s[i].sn.branch[j].rect.boundary = G_malloc(6 * sizeof(RectReal));
	    }
	}
    }

    /* write pending changes to file */
    RTreeFlushBuffer(t);

    /* should be foolproof */
    sidx_nodesize =
	(int)(2 * PORT_INT + t->nodecard * (off_t_size + NUMSIDES * PORT_DOUBLE));
    sidx_leafsize =
	(int)(2 * PORT_INT + t->leafcard * (off_t_size + NUMSIDES * PORT_DOUBLE));

    /* stack size of t->rootlevel + 1 would be enough because of
     * depth-first post-order traversal:
     * only one node per level on stack at any given time */

    /* add root node position to stack */
    s[top].branch_id = i = 0;
    RTreeReadNode(&s[top].sn, t->rootpos, t);

    /* depth-first postorder traversal 
     * all children of a node are visitied and written out first
     * when a child is written out, its position in file is stored in pos[] for
     * the parent node and written out with the parent node */
    /* root node is written out last and its position returned */

    while (top >= 0) {
	n = &(s[top].sn);
	writeout = 1;
	/* this is an internal node in the RTree
	 * all its children are processed first,
	 * before it is written out to the sidx file */
	if (s[top].sn.level > 0) {
	    for (i = s[top].branch_id; i < t->nodecard; i++) {
		s[top].pos[i] = 0;
		if (n->branch[i].child.pos >= 0) {
		    s[top++].branch_id = i + 1;
		    RTreeReadNode(&s[top].sn, n->branch[i].child.pos, t);
		    s[top].branch_id = 0;
		    writeout = 0;
		    break;
		}
	    }
	    if (writeout) {
		/* nothing else found, ready to write out */
		s[top].branch_id = t->nodecard;
	    }
	}
	if (writeout) {
	    /* write node to sidx file */
	    if (G_ftell(fp->file) != nextfreepos)
		G_fatal_error("Unable to write spatial index. "
                              "Wrong node position (%"PRI_OFF_T") in file (should be %"PRI_OFF_T").",
                              G_ftell(fp->file), nextfreepos);
            
	    /* write with dig__fwrite_port_* fns */
	    dig__fwrite_port_I(&(s[top].sn.count), 1, fp);
	    dig__fwrite_port_I(&(s[top].sn.level), 1, fp);
	    maxcard = s[top].sn.level ? t->nodecard : t->leafcard;
	    for (j = 0; j < maxcard; j++) {
		dig__fwrite_port_D(s[top].sn.branch[j].rect.boundary,
				   NUMSIDES, fp);
		/* leaf node: vector object IDs are stored in child.id */
		if (s[top].sn.level == 0)
		    s[top].pos[j] = (off_t) s[top].sn.branch[j].child.id;
		dig__fwrite_port_O(&(s[top].pos[j]), 1, fp, off_t_size);
	    }

	    top--;
	    /* update corresponding child position of parent node
	     * this node is only updated if its level is > 0, i.e.
	     * this is an internal node
	     * children of internal nodes do not have an ID, instead
	     * they hold the position in file of the next nodes down the tree */
	    if (top >= 0) {
		s[top].pos[s[top].branch_id - 1] = nextfreepos;
		nextfreepos += (s[top + 1].sn.level ? sidx_nodesize : sidx_leafsize);
	    }
	}
    }
    
    close(t->fd);
    
    return nextfreepos;
}