[GRASS-SVN] r46900 - grass/trunk/lib/vector/diglib

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jul 1 04:53:19 EDT 2011


Author: mmetz
Date: 2011-07-01 01:53:19 -0700 (Fri, 01 Jul 2011)
New Revision: 46900

Modified:
   grass/trunk/lib/vector/diglib/inside.c
   grass/trunk/lib/vector/diglib/list.c
   grass/trunk/lib/vector/diglib/plus_area.c
   grass/trunk/lib/vector/diglib/plus_line.c
   grass/trunk/lib/vector/diglib/plus_struct.c
   grass/trunk/lib/vector/diglib/spindex.c
   grass/trunk/lib/vector/diglib/spindex_rw.c
   grass/trunk/lib/vector/diglib/struct_alloc.c
Log:
remove bounding boxes from vector topology (Radim's TODO): update diglib

Modified: grass/trunk/lib/vector/diglib/inside.c
===================================================================
--- grass/trunk/lib/vector/diglib/inside.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/inside.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -27,22 +27,3 @@
     a = beg_x - b * beg_y;
     return (a + b * Y);
 }
-
-int dig_in_area_bbox(struct P_area * Area, double x, double y)
-{
-#ifdef GDEBUG
-    G_debug(3, "BBOX: (x,y) (%lf, %lf)\n", x, y);
-    G_debug(3, "NSEW:  %lf, %lf, %lf, %lf\n", Area->N, Area->S, Area->E,
-	    Area->W);
-#endif
-    if (x < Area->W)
-	return (0);
-    if (x > Area->E)
-	return (0);
-    if (y < Area->S)
-	return (0);
-    if (y > Area->N)
-	return (0);
-
-    return (1);
-}

Modified: grass/trunk/lib/vector/diglib/list.c
===================================================================
--- grass/trunk/lib/vector/diglib/list.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/list.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -28,6 +28,17 @@
     return 1;
 }
 
+/* Init box list */
+int dig_init_boxlist(struct boxlist *list)
+{
+    list->id = NULL;
+    list->box = NULL;
+    list->n_values = 0;
+    list->alloc_values = 0;
+
+    return 1;
+}
+
 /* Add item to list, does not check for duplicates */
 int dig_list_add(struct ilist *list, int val)
 {
@@ -46,3 +57,31 @@
 
     return 1;
 }
+
+/* Add item to box list, does not check for duplicates */
+int dig_boxlist_add(struct boxlist *list, int id, struct bound_box box)
+{
+    if (list->n_values == list->alloc_values) {
+	size_t size = (list->n_values + 1000) * sizeof(int);
+	void *p = G_realloc((void *)list->id, size);
+
+	if (p == NULL)
+	    return 0;
+	list->id = (int *)p;
+
+	size = (list->n_values + 1000) * sizeof(struct bound_box);
+	p = G_realloc((void *)list->box, size);
+
+	if (p == NULL)
+	    return 0;
+	list->box = (int *)p;
+
+	list->alloc_values = list->n_values + 1000;
+    }
+
+    list->id[list->n_values] = id;
+    list->box[list->n_values] = box;
+    list->n_values++;
+
+    return 1;
+}

Modified: grass/trunk/lib/vector/diglib/plus_area.c
===================================================================
--- grass/trunk/lib/vector/diglib/plus_area.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/plus_area.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -58,6 +58,7 @@
     static int array_size;	/* 0 on startup */
     int n_lines;
     struct P_line *Line;
+    struct P_topo_b *topo;
     int node;
 
     if (debug_level == -1) {
@@ -75,7 +76,11 @@
     /* First check if line is not degenerated (degenerated lines have angle -9) 
      *  Following degenerated lines are skip by dig_angle_next_line() */
     Line = plus->Line[first_line];
-    node = Line->N1;		/* to check one is enough, because if degenerated N1 == N2 */
+    if (Line->type != GV_BOUNDARY)
+	return -1;
+
+    topo = (struct P_topo_b *)Line->topo;
+    node = topo->N1;		/* to check one is enough, because if degenerated N1 == N2 */
     if (dig_node_line_angle(plus, node, first_line) == -9.) {
 	G_debug(3, "First line degenerated");
 	return (0);
@@ -172,13 +177,14 @@
  * \return number of new area
  * \return -1 on error
  */
-int dig_add_area(struct Plus_head *plus, int n_lines, plus_t * lines)
+int dig_add_area(struct Plus_head *plus, int n_lines, plus_t * lines,
+		 struct bound_box *box)
 {
     register int i;
     register int area, line;
     struct P_area *Area;
     struct P_line *Line;
-    struct bound_box box, abox;
+    struct P_topo_b *topo;
 
     G_debug(3, "dig_add_area():");
     /* First look if we have space in array of pointers to areas
@@ -202,41 +208,36 @@
 	line = lines[i];
 	Area->lines[i] = line;
 	Line = plus->Line[abs(line)];
+	topo = (struct P_topo_b *)Line->topo;
 	if (plus->do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line < 0) {		/* revers direction -> area on left */
-	    if (Line->left != 0) {
+	    if (topo->left != 0) {
 		G_warning(_("Line %d already has area/isle %d to left"), line,
-			  Line->left);
+			  topo->left);
 		return -1;
 	    }
 
 	    G_debug(3, "  Line %d left set to %d.", line, area);
-	    Line->left = area;
+	    topo->left = area;
 	}
 	else {
-	    if (Line->right != 0) {
+	    if (topo->right != 0) {
 		G_warning(_("Line %d already has area/isle %d to right"),
-			  line, Line->right);
+			  line, topo->right);
 		return -1;
 	    }
 
 	    G_debug(3, "  Line %d right set to %d.", line, area);
-	    Line->right = area;
+	    topo->right = area;
 	}
-	dig_line_get_box(plus, abs(line), &box);
-	if (i == 0)
-	    dig_box_copy(&abox, &box);
-	else
-	    dig_box_extend(&abox, &box);
     }
     Area->n_lines = n_lines;
     Area->centroid = 0;
 
     plus->Area[area] = Area;
-    dig_area_set_box(plus, area, &abox);
 
-    dig_spidx_add_area(plus, area, &abox);
+    dig_spidx_add_area(plus, area, box);
 
     plus->n_areas++;
 
@@ -264,7 +265,8 @@
 	G_fatal_error("Attempt to add isle to dead area");
 
     for (i = 0; i < Area->n_isles; i++) {
-	if (Area->isles[i] == isle) {	/* Already exist */
+	if (Area->isles[i] == isle) {
+	    /* Already exists: bug in vector libs */
 	    G_debug(3, "isle already registered in area");
 	    return 0;
 	}
@@ -348,6 +350,7 @@
     struct P_area *Area;
     struct P_line *Line;
     struct P_isle *Isle;
+    struct P_topo_b *topo;
 
     G_debug(3, "dig_del_area() area =  %d", area);
     Area = plus->Area[area];
@@ -364,15 +367,16 @@
     for (i = 0; i < Area->n_lines; i++) {
 	line = Area->lines[i];	/* >0 = clockwise -> right, <0 = counterclockwise ->left */
 	Line = plus->Line[abs(line)];
+	topo = (struct P_topo_b *)Line->topo;
 	if (plus->do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line > 0) {
 	    G_debug(3, "  Set line %d right side to 0", line);
-	    Line->right = 0;
+	    topo->right = 0;
 	}
 	else {
 	    G_debug(3, "  Set line %d left side to 0", line);
-	    Line->left = 0;
+	    topo->left = 0;
 	}
 
 	/* Find the isle this area is part of (used late below) */
@@ -397,7 +401,8 @@
 		      line);
 	}
 	else {
-	    Line->left = 0;
+	    topo = (struct P_topo_b *)Line->topo;
+	    topo->left = 0;
 	    if (plus->do_uplist)
 		dig_line_add_updated(plus, line);
 	}
@@ -432,32 +437,7 @@
     return 1;
 }
 
-/*!
- * \brief Set area bounding box
- *
- * \param[in] plus pointer to Plus_head structure
- * \param[in] area area id
- * \param[in] Box bounding box
- *
- * \return 1
- */
-int dig_area_set_box(struct Plus_head *plus, plus_t area, struct bound_box * Box)
-{
-    struct P_area *Area;
 
-    Area = plus->Area[area];
-
-    Area->N = Box->N;
-    Area->S = Box->S;
-    Area->E = Box->E;
-    Area->W = Box->W;
-    Area->T = Box->T;
-    Area->B = Box->B;
-
-    return (1);
-}
-
-
 /*!
  * \brief Find number line of next angle to follow an line
  *
@@ -497,11 +477,32 @@
 	    current_line, side, type);
 
     Line = plus->Line[abs(current_line)];
-    if (current_line > 0)
-	node = Line->N1;
-    else
-	node = Line->N2;
+    
+    if (!(Line->type & GV_LINES))
+	return 0;
 
+    node = 0;
+    if (current_line > 0) {
+	if (Line->type == GV_LINE) {
+	    struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
+	    node = topo->N1;
+	}
+	else if (Line->type == GV_BOUNDARY) {
+	    struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+	    node = topo->N1;
+	}
+    }
+    else {
+	if (Line->type == GV_LINE) {
+	    struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
+	    node = topo->N2;
+	}
+	else if (Line->type == GV_BOUNDARY) {
+	    struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+	    node = topo->N2;
+	}
+    }
+
     G_debug(3, " node = %d", node);
 
     Node = plus->Node[node];
@@ -588,11 +589,29 @@
     G_debug(3, "dig_node_angle_check: line = %d, type = %d", line, type);
 
     Line = plus->Line[abs(line)];
+    if (!(Line->type & GV_LINES))
+	return 0;
 
-    if (line > 0)
-	node = Line->N1;
-    else
-	node = Line->N2;
+    if (line > 0) {
+	if (Line->type == GV_LINE) {
+	    struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
+	    node = topo->N1;
+	}
+	else if (Line->type == GV_BOUNDARY) {
+	    struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+	    node = topo->N1;
+	}
+    }
+    else {
+	if (Line->type == GV_LINE) {
+	    struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
+	    node = topo->N2;
+	}
+	else if (Line->type == GV_BOUNDARY) {
+	    struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+	    node = topo->N2;
+	}
+    }
 
     angle1 = dig_node_line_angle(plus, node, line);
 
@@ -634,13 +653,14 @@
  * \return number of new isle
  * \return -1 on error
  */
-int dig_add_isle(struct Plus_head *plus, int n_lines, plus_t * lines)
+int dig_add_isle(struct Plus_head *plus, int n_lines, plus_t * lines,
+		 struct bound_box *box)
 {
     register int i;
     register int isle, line;
     struct P_isle *Isle;
     struct P_line *Line;
-    struct bound_box box, abox;
+    struct P_topo_b *topo;
 
     G_debug(3, "dig_add_isle():");
     /* First look if we have space in array of pointers to isles
@@ -661,50 +681,39 @@
 
     Isle->area = 0;
 
-    Isle->N = 0;
-    Isle->S = 0;
-    Isle->E = 0;
-    Isle->W = 0;
-
     for (i = 0; i < n_lines; i++) {
 	line = lines[i];
 	G_debug(3, " i = %d line = %d", i, line);
 	Isle->lines[i] = line;
 	Line = plus->Line[abs(line)];
+	topo = (struct P_topo_b *)Line->topo;
 	if (plus->do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line < 0) {		/* revers direction -> isle on left */
-	    if (Line->left != 0) {
+	    if (topo->left != 0) {
 		G_warning(_("Line %d already has area/isle %d to left"), line,
-			  Line->left);
+			  topo->left);
 		return -1;
 	    }
-	    Line->left = -isle;
+	    topo->left = -isle;
 	}
 	else {
-	    if (Line->right != 0) {
+	    if (topo->right != 0) {
 		G_warning(_("Line %d already has area/isle %d to left"), line,
-			  Line->right);
+			  topo->right);
 		return -1;
 	    }
 
-	    Line->right = -isle;
+	    topo->right = -isle;
 	}
-	dig_line_get_box(plus, abs(line), &box);
-	if (i == 0)
-	    dig_box_copy(&abox, &box);
-	else
-	    dig_box_extend(&abox, &box);
     }
 
     Isle->n_lines = n_lines;
 
     plus->Isle[isle] = Isle;
 
-    dig_isle_set_box(plus, isle, &abox);
+    dig_spidx_add_isle(plus, isle, box);
 
-    dig_spidx_add_isle(plus, isle, &abox);
-
     plus->n_isles++;
 
     return (isle);
@@ -712,31 +721,6 @@
 
 
 /*!
- * \brief Set isle bounding box
- * 
- * \param[in] plus pointer to Plus_head structure
- * \param[in] isle isle id
- * \param[in] Box bounding box
- *
- * \return 1
- */
-int dig_isle_set_box(struct Plus_head *plus, plus_t isle, struct bound_box * Box)
-{
-    struct P_isle *Isle;
-
-    Isle = plus->Isle[isle];
-
-    Isle->N = Box->N;
-    Isle->S = Box->S;
-    Isle->E = Box->E;
-    Isle->W = Box->W;
-    Isle->T = Box->T;
-    Isle->B = Box->B;
-
-    return (1);
-}
-
-/*!
  * \brief Delete island from Plus_head structure
  *
  * Reset references to it in lines and area outside.
@@ -751,6 +735,7 @@
     int i, line;
     struct P_line *Line;
     struct P_isle *Isle;
+    struct P_topo_b *topo;
 
     G_debug(3, "dig_del_isle() isle =  %d", isle);
     Isle = plus->Isle[isle];
@@ -761,12 +746,13 @@
     for (i = 0; i < Isle->n_lines; i++) {
 	line = Isle->lines[i];	/* >0 = clockwise -> right, <0 = counterclockwise ->left */
 	Line = plus->Line[abs(line)];
+	topo = (struct P_topo_b *)Line->topo;
 	if (plus->do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line > 0)
-	    Line->right = 0;
+	    topo->right = 0;
 	else
-	    Line->left = 0;
+	    topo->left = 0;
     }
 
     /* Delete reference from area it is within */

Modified: grass/trunk/lib/vector/diglib/plus_line.c
===================================================================
--- grass/trunk/lib/vector/diglib/plus_line.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/plus_line.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -19,16 +19,36 @@
 #include <grass/vector.h>
 
 static int add_line(struct Plus_head *plus, int lineid, int type, const struct line_pnts *Points,
-		    off_t offset)
+		    struct bound_box *box, off_t offset)
 {
     int node, lp;
     struct P_line *line;
-    struct bound_box box;
 
     plus->Line[lineid] = dig_alloc_line();
     line = plus->Line[lineid];
 
-    /* Add nodes */
+    line->type = type;
+    line->offset = offset;
+
+    dig_spidx_add_line(plus, lineid, box);
+    if (plus->do_uplist)
+	dig_line_add_updated(plus, lineid);
+
+    if (type & GV_POINT) {
+	line->topo = NULL;
+	return (lineid);
+    }
+    
+    line->topo = dig_alloc_topo(type);
+
+    if (type & GV_CENTROID) {
+	struct P_topo_c *topo = (struct P_topo_c *)line->topo;
+
+	topo->area = 0;
+	return (lineid);
+    }
+
+    /* Add nodes for lines */
     G_debug(3, "Register node: type = %d,  %f,%f", type, Points->x[0],
 	    Points->y[0]);
 
@@ -41,49 +61,53 @@
     else {
 	G_debug(3, "Old node found: %d", node);
     }
-    line->N1 = node;
+    if (type == GV_LINE) {
+	struct P_topo_l *topo = (struct P_topo_l *)line->topo;
+
+	topo->N1 = node;
+	topo->N2 = 0;
+    }
+    else if (type == GV_BOUNDARY) {
+	struct P_topo_b *topo = (struct P_topo_b *)line->topo;
+
+	topo->N1 = node;
+	topo->N2 = 0;
+	topo->left = 0;
+	topo->right = 0;
+    }
+
     dig_node_add_line(plus, node, lineid, Points, type);
     if (plus->do_uplist)
 	dig_node_add_updated(plus, node);
 
-    if (type & GV_LINES) {
-	lp = Points->n_points - 1;
-	G_debug(3, "Register node %f,%f", Points->x[lp], Points->y[lp]);
+    lp = Points->n_points - 1;
+    G_debug(3, "Register node %f,%f", Points->x[lp], Points->y[lp]);
+    node =
+	dig_find_node(plus, Points->x[lp], Points->y[lp], Points->z[lp]);
+    G_debug(3, "node = %d", node);
+    if (node == 0) {
 	node =
-	    dig_find_node(plus, Points->x[lp], Points->y[lp], Points->z[lp]);
-	G_debug(3, "node = %d", node);
-	if (node == 0) {
-	    node =
-		dig_add_node(plus, Points->x[lp], Points->y[lp],
-			     Points->z[lp]);
-	    G_debug(3, "Add new node: %d", node);
-	}
-	else {
-	    G_debug(3, "Old node found: %d", node);
-	}
-	line->N2 = node;
-	dig_node_add_line(plus, node, -lineid, Points, type);
-	if (plus->do_uplist)
-	    dig_node_add_updated(plus, node);
+	    dig_add_node(plus, Points->x[lp], Points->y[lp],
+			 Points->z[lp]);
+	G_debug(3, "Add new node: %d", node);
     }
     else {
-	line->N2 = 0;
+	G_debug(3, "Old node found: %d", node);
     }
+    if (type == GV_LINE) {
+	struct P_topo_l *topo = (struct P_topo_l *)line->topo;
 
-    line->type = type;
-    line->offset = offset;
-    line->left = 0;
-    line->right = 0;
-    line->N = 0;
-    line->S = 0;
-    line->E = 0;
-    line->W = 0;
+	topo->N2 = node;
+    }
+    else if (type == GV_BOUNDARY) {
+	struct P_topo_b *topo = (struct P_topo_b *)line->topo;
 
-    dig_line_box(Points, &box);
-    dig_line_set_box(plus, lineid, &box);
-    dig_spidx_add_line(plus, lineid, &box);
+	topo->N2 = node;
+    }
+
+    dig_node_add_line(plus, node, -lineid, Points, type);
     if (plus->do_uplist)
-	dig_line_add_updated(plus, lineid);
+	dig_node_add_updated(plus, node);
 
     return (lineid);
 }
@@ -101,7 +125,7 @@
  */
 int
 dig_add_line(struct Plus_head *plus, int type, const struct line_pnts *Points,
-	     off_t offset)
+             struct bound_box *box, off_t offset)
 {
     int ret;
     
@@ -112,7 +136,7 @@
 	    return -1;
     }
 
-    ret = add_line(plus, plus->n_lines + 1, type, Points, offset);
+    ret = add_line(plus, plus->n_lines + 1, type, Points, box, offset);
 
     if (ret == -1)
 	return ret;
@@ -157,13 +181,13 @@
 int
 dig_restore_line(struct Plus_head *plus, int lineid,
 		 int type, struct line_pnts *Points,
-		 off_t offset)
+		 struct bound_box *box, off_t offset)
 {
     if (lineid < 1 || lineid > plus->n_lines) {
 	return -1;
     }
 
-    return add_line(plus, lineid, type, Points, offset);    
+    return add_line(plus, lineid, type, Points, box, offset);    
 }
 
 /*!
@@ -181,19 +205,40 @@
  * \return  0 OK
  *
  */
-int dig_del_line(struct Plus_head *plus, int line)
+int dig_del_line(struct Plus_head *plus, int line, double x, double y, double z)
 {
     int i, mv;
+    plus_t N1, N2;
     struct P_line *Line;
     struct P_node *Node;
 
     G_debug(3, "dig_del_line() line =  %d", line);
 
     Line = plus->Line[line];
-    dig_spidx_del_line(plus, line);
+    dig_spidx_del_line(plus, line, x, y, z);
 
+    if (!(Line->type & GV_LINES)) {
+	/* Delete line */
+	dig_free_line(Line);
+	plus->Line[line] = NULL;
+
+	return 0;
+    }
+
     /* Delete from nodes (and nodes) */
-    Node = plus->Node[Line->N1];
+    if (Line->type == GV_LINE) {
+	struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
+
+	N1 = topo->N1;
+    }
+    else if (Line->type == GV_BOUNDARY) {
+	struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+
+	N1 = topo->N1;
+    }
+
+    Node = plus->Node[N1];
+
     mv = 0;
     for (i = 0; i < Node->n_lines; i++) {
 	if (mv) {
@@ -206,44 +251,55 @@
 	}
     }
     Node->n_lines--;
+
     if (Node->n_lines == 0) {
-	G_debug(3, "    node %d has 0 lines -> delete", Line->N1);
-	dig_spidx_del_node(plus, Line->N1);
+
+	G_debug(3, "    node %d has 0 lines -> delete", N1);
+	dig_spidx_del_node(plus, N1);
 	/* free structures */
 	dig_free_node(Node);
-	plus->Node[Line->N1] = NULL;
+	plus->Node[N1] = NULL;
     }
     else {
 	if (plus->do_uplist)
-	    dig_node_add_updated(plus, Line->N1);
+	    dig_node_add_updated(plus, N1);
     }
 
-    if (Line->type & GV_LINES) {
-	Node = plus->Node[Line->N2];
-	mv = 0;
-	for (i = 0; i < Node->n_lines; i++) {
-	    if (mv) {
-		Node->lines[i - 1] = Node->lines[i];
-		Node->angles[i - 1] = Node->angles[i];
-	    }
-	    else {
-		if (abs(Node->lines[i]) == line)
-		    mv = 1;
-	    }
+    if (Line->type == GV_LINE) {
+	struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
+
+	N2 = topo->N2;
+    }
+    else if (Line->type == GV_BOUNDARY) {
+	struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+
+	N2 = topo->N2;
+    }
+
+    Node = plus->Node[N2];
+    mv = 0;
+    for (i = 0; i < Node->n_lines; i++) {
+	if (mv) {
+	    Node->lines[i - 1] = Node->lines[i];
+	    Node->angles[i - 1] = Node->angles[i];
 	}
-	Node->n_lines--;
-	if (Node->n_lines == 0) {
-	    G_debug(3, "    node %d has 0 lines -> delete", Line->N2);
-	    dig_spidx_del_node(plus, Line->N2);
-	    /* free structures */
-	    dig_free_node(Node);
-	    plus->Node[Line->N2] = NULL;
-	}
 	else {
-	    if (plus->do_uplist)
-		dig_node_add_updated(plus, Line->N2);
+	    if (abs(Node->lines[i]) == line)
+		mv = 1;
 	}
     }
+    Node->n_lines--;
+    if (Node->n_lines == 0) {
+	G_debug(3, "    node %d has 0 lines -> delete", N2);
+	dig_spidx_del_node(plus, N2);
+	/* free structures */
+	dig_free_node(Node);
+	plus->Node[N2] = NULL;
+    }
+    else {
+	if (plus->do_uplist)
+	    dig_node_add_updated(plus, N2);
+    }
 
     /* Delete line */
     dig_free_line(Line);
@@ -266,20 +322,25 @@
 plus_t dig_line_get_area(struct Plus_head * plus, plus_t line, int side)
 {
     struct P_line *Line;
+    struct P_topo_b *topo;
 
     Line = plus->Line[line];
+    if (Line->type != GV_BOUNDARY)
+	return (-1);
+
+    topo = (struct P_topo_b *)Line->topo;
     if (side == GV_LEFT) {
 	G_debug(3,
 		"dig_line_get_area(): line = %d, side = %d (left), area = %d",
-		line, side, Line->left);
-	return (Line->left);
+		line, side, topo->left);
+	return (topo->left);
     }
     if (side == GV_RIGHT) {
 	G_debug(3,
 		"dig_line_get_area(): line = %d, side = %d (right), area = %d",
-		line, side, Line->right);
+		line, side, topo->right);
 
-	return (Line->right);
+	return (topo->right);
     }
 
     return (-1);
@@ -299,13 +360,19 @@
 dig_line_set_area(struct Plus_head *plus, plus_t line, int side, plus_t area)
 {
     struct P_line *Line;
+    struct P_topo_b *topo;
 
     Line = plus->Line[line];
+    if (Line->type != GV_BOUNDARY)
+	return (0);
+
+    topo = (struct P_topo_b *)Line->topo;
+
     if (side == GV_LEFT) {
-	Line->left = area;
+	topo->left = area;
     }
     else if (side == GV_RIGHT) {
-	Line->right = area;
+	topo->right = area;
     }
 
     return (1);
@@ -320,6 +387,7 @@
  *
  * \return 1
  */
+/*
 int dig_line_set_box(struct Plus_head *plus, plus_t line, struct bound_box * Box)
 {
     struct P_line *Line;
@@ -335,6 +403,7 @@
 
     return (1);
 }
+*/
 
 /*!
  * \brief Get line bounding box saved in topo
@@ -345,6 +414,7 @@
  *
  * \return 1
  */
+/*
 int dig_line_get_box(struct Plus_head *plus, plus_t line, struct bound_box * Box)
 {
     struct P_line *Line;
@@ -360,3 +430,4 @@
 
     return (1);
 }
+*/

Modified: grass/trunk/lib/vector/diglib/plus_struct.c
===================================================================
--- grass/trunk/lib/vector/diglib/plus_struct.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/plus_struct.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -147,10 +147,9 @@
 
 int dig_Rd_P_line(struct Plus_head *Plus, int n, struct gvfile * fp)
 {
-    int n_edges, vol;
+    int n_edges;
     char tp;
     struct P_line *ptr;
-    struct P_node *Node;
 
     G_debug(3, "dig_Rd_P_line()");
 
@@ -173,85 +172,73 @@
     if (0 >= dig__fread_port_O(&(ptr->offset), 1, fp, Plus->off_t_size))
 	return (-1);
 
-    /* first node */
-    if (ptr->type & (GV_POINTS | GV_LINES | GV_KERNEL))
-	if (0 >= dig__fread_port_P(&(ptr->N1), 1, fp))
-	    return -1;
+    if (ptr->type == GV_POINT) {
+	ptr->topo = NULL;
+    }
+    else {
+	ptr->topo = dig_alloc_topo(ptr->type);
+    }
 
-    /* second node, for points/centroids not needed */
-    if (ptr->type & (GV_LINE | GV_BOUNDARY)) {
-	if (0 >= dig__fread_port_P(&(ptr->N2), 1, fp))
+    /* 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;
     }
-    else if (ptr->type & (GV_POINTS | GV_KERNEL))
-	ptr->N2 = ptr->N1;
+    /* lines */
+    else if (ptr->type & GV_LINE) {
+	struct P_topo_l *topo = (struct P_topo_l *)ptr->topo;
 
-    /* left area for boundary, area for centroid */
-    if (ptr->type & (GV_BOUNDARY | GV_CENTROID))
-	if (0 >= dig__fread_port_P(&(ptr->left), 1, fp))
+	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 */
+    if (ptr->type & GV_BOUNDARY) {
+	struct P_topo_b *topo = (struct P_topo_b *)ptr->topo;
 
-    /* right area */
-    if (ptr->type & GV_BOUNDARY)
-	if (0 >= dig__fread_port_P(&(ptr->right), 1, fp))
+	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 ((ptr->type & GV_FACE) && Plus->with_z) {	/* reserved for face edges */
 	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(&vol, 1, fp))
+	if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
 	    return -1;
-	if (0 >= dig__fread_port_P(&vol, 1, fp))
+	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 ((ptr->type & GV_KERNEL) && Plus->with_z)	/* reserved for kernel (volume number) */
-	if (0 >= dig__fread_port_P(&vol, 1, fp))
+	if (0 >= dig__fread_port_P(&(topo->volume), 1, fp))
 	    return -1;
-
-    /* bounding box */
-    if (ptr->type & (GV_LINE | GV_BOUNDARY | GV_FACE)) {
-	if (0 >= dig__fread_port_D(&(ptr->N), 1, fp))
-	    return -1;
-	if (0 >= dig__fread_port_D(&(ptr->S), 1, fp))
-	    return -1;
-	if (0 >= dig__fread_port_D(&(ptr->E), 1, fp))
-	    return -1;
-	if (0 >= dig__fread_port_D(&(ptr->W), 1, fp))
-	    return -1;
-
-	if (Plus->with_z) {
-	    if (0 >= dig__fread_port_D(&(ptr->T), 1, fp))
-		return -1;
-	    if (0 >= dig__fread_port_D(&(ptr->B), 1, fp))
-		return -1;
-	}
-	else {
-	    ptr->T = 0.0;
-	    ptr->B = 0.0;
-	}
     }
-    else {
-	Node = Plus->Node[ptr->N1];
-	ptr->N = Node->y;
-	ptr->S = Node->y;
-	ptr->E = Node->x;
-	ptr->W = Node->x;
-	ptr->T = Node->z;
-	ptr->B = Node->z;
-    }
 
     Plus->Line[n] = ptr;
+
     return (0);
 }
 
 int dig_Wr_P_line(struct Plus_head *Plus, int n, struct gvfile * fp)
 {
-    int n_edges = 0, vol = 0;
+    int n_edges = 0;
     char ch;
     struct P_line *ptr;
 
@@ -277,61 +264,63 @@
     /* offset */
     if (0 >= dig__fwrite_port_O(&(ptr->offset), 1, fp, Plus->off_t_size))
 	return (-1);
+	
+    if (!ptr->topo)
+	return (0);
+	
+    /* nothing else for points */
 
-    /* first node */
-    if (ptr->type & (GV_POINTS | GV_LINES | GV_KERNEL))
-	if (0 >= dig__fwrite_port_P(&(ptr->N1), 1, fp))
+    /* centroids */
+    if (ptr->type & GV_CENTROID) {
+	struct P_topo_c *topo = (struct P_topo_c *)ptr->topo;
+	
+	if (0 >= dig__fwrite_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;
 
-    /* second node, for points/centroids not needed */
-    if (ptr->type & (GV_LINE | GV_BOUNDARY))
-	if (0 >= dig__fwrite_port_P(&(ptr->N2), 1, fp))
+	if (0 >= dig__fwrite_port_P(&(topo->N1), 1, fp))
 	    return (-1);
-
-    /* left area for boundary, area for centroid */
-    if (ptr->type & (GV_BOUNDARY | GV_CENTROID))
-	if (0 >= dig__fwrite_port_P(&(ptr->left), 1, fp))
+	if (0 >= dig__fwrite_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;
 
-    /* right area */
-    if (ptr->type & GV_BOUNDARY)
-	if (0 >= dig__fwrite_port_P(&(ptr->right), 1, fp))
+	if (0 >= dig__fwrite_port_P(&(topo->N1), 1, fp))
 	    return (-1);
+	if (0 >= dig__fwrite_port_P(&(topo->N2), 1, fp))
+	    return (-1);
+	if (0 >= dig__fwrite_port_P(&(topo->left), 1, fp))
+	    return (-1);
+	if (0 >= dig__fwrite_port_P(&(topo->right), 1, fp))
+	    return (-1);
+    }
+    /* faces */
+    else if ((ptr->type & GV_FACE) && Plus->with_z) {	/* reserved for face */
+	struct P_topo_f *topo = (struct P_topo_f *)ptr->topo;
 
-    if ((ptr->type & GV_FACE) && Plus->with_z) {	/* reserved for face */
 	if (0 >= dig__fwrite_port_I(&n_edges, 1, fp))
 	    return (-1);
 
 	/* here will be list of edges */
 
-	/* left / right volume */
-	if (0 >= dig__fwrite_port_P(&vol, 1, fp))
+	/* left / right volume / hole */
+	if (0 >= dig__fwrite_port_P(&(topo->left), 1, fp))
 	    return (-1);
-	if (0 >= dig__fwrite_port_P(&vol, 1, fp))
+	if (0 >= dig__fwrite_port_P(&(topo->right), 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 ((ptr->type & GV_KERNEL) && Plus->with_z)	/* reserved for kernel (volume number) */
-	if (0 >= dig__fwrite_port_P(&vol, 1, fp))
+	/* volume */
+	if (0 >= dig__fwrite_port_P(&(topo->volume), 1, fp))
 	    return (-1);
-
-    /* bounding box */
-    if (ptr->type & (GV_LINE | GV_BOUNDARY | GV_FACE)) {
-	if (0 >= dig__fwrite_port_D(&(ptr->N), 1, fp))
-	    return (-1);
-	if (0 >= dig__fwrite_port_D(&(ptr->S), 1, fp))
-	    return (-1);
-	if (0 >= dig__fwrite_port_D(&(ptr->E), 1, fp))
-	    return (-1);
-	if (0 >= dig__fwrite_port_D(&(ptr->W), 1, fp))
-	    return (-1);
-
-	if (Plus->with_z) {
-	    if (0 >= dig__fwrite_port_D(&(ptr->T), 1, fp))
-		return (-1);
-	    if (0 >= dig__fwrite_port_D(&(ptr->B), 1, fp))
-		return (-1);
-	}
     }
 
     return (0);
@@ -342,9 +331,7 @@
     int cnt;
     struct P_area *ptr;
 
-#ifdef GDEBUG
     G_debug(3, "dig_Rd_P_area(): n = %d", n);
-#endif
 
     if (0 >= dig__fread_port_P(&cnt, 1, fp))
 	return (-1);
@@ -356,7 +343,7 @@
 
     ptr = dig_alloc_area();
 
-    /* lines */
+    /* boundaries */
     ptr->n_lines = cnt;
 
     if (dig_area_alloc_line(ptr, ptr->n_lines) == -1)
@@ -381,27 +368,6 @@
     if (0 >= dig__fread_port_P(&(ptr->centroid), 1, fp))
 	return -1;
 
-    /* bounding box */
-    if (0 >= dig__fread_port_D(&(ptr->N), 1, fp))
-	return -1;
-    if (0 >= dig__fread_port_D(&(ptr->S), 1, fp))
-	return -1;
-    if (0 >= dig__fread_port_D(&(ptr->E), 1, fp))
-	return -1;
-    if (0 >= dig__fread_port_D(&(ptr->W), 1, fp))
-	return -1;
-
-    if (Plus->with_z) {
-	if (0 >= dig__fread_port_D(&(ptr->T), 1, fp))
-	    return -1;
-	if (0 >= dig__fread_port_D(&(ptr->B), 1, fp))
-	    return -1;
-    }
-    else {
-	ptr->T = 0.0;
-	ptr->B = 0.0;
-    }
-
     Plus->Area[n] = ptr;
 
     return (0);
@@ -422,7 +388,7 @@
 	return 0;
     }
 
-    /* lines */
+    /* boundaries */
     if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
 	return (-1);
 
@@ -442,23 +408,6 @@
     if (0 >= dig__fwrite_port_P(&(ptr->centroid), 1, fp))
 	return (-1);
 
-    /* bounding box */
-    if (0 >= dig__fwrite_port_D(&(ptr->N), 1, fp))
-	return (-1);
-    if (0 >= dig__fwrite_port_D(&(ptr->S), 1, fp))
-	return (-1);
-    if (0 >= dig__fwrite_port_D(&(ptr->E), 1, fp))
-	return (-1);
-    if (0 >= dig__fwrite_port_D(&(ptr->W), 1, fp))
-	return (-1);
-
-    if (Plus->with_z) {
-	if (0 >= dig__fwrite_port_D(&(ptr->T), 1, fp))
-	    return (-1);
-	if (0 >= dig__fwrite_port_D(&(ptr->B), 1, fp))
-	    return (-1);
-    }
-
     return (0);
 }
 
@@ -467,9 +416,7 @@
     int cnt;
     struct P_isle *ptr;
 
-#ifdef GDEBUG
     G_debug(3, "dig_Rd_P_isle()");
-#endif
 
     if (0 >= dig__fread_port_P(&cnt, 1, fp))
 	return (-1);
@@ -481,7 +428,7 @@
 
     ptr = dig_alloc_isle();
 
-    /* lines */
+    /* boundaries */
     ptr->n_lines = cnt;
 
     if (dig_isle_alloc_line(ptr, ptr->n_lines) == -1)
@@ -495,27 +442,6 @@
     if (0 >= dig__fread_port_P(&(ptr->area), 1, fp))
 	return -1;
 
-    /* bounding box */
-    if (0 >= dig__fread_port_D(&(ptr->N), 1, fp))
-	return -1;
-    if (0 >= dig__fread_port_D(&(ptr->S), 1, fp))
-	return -1;
-    if (0 >= dig__fread_port_D(&(ptr->E), 1, fp))
-	return -1;
-    if (0 >= dig__fread_port_D(&(ptr->W), 1, fp))
-	return -1;
-
-    if (Plus->with_z) {
-	if (0 >= dig__fread_port_D(&(ptr->T), 1, fp))
-	    return -1;
-	if (0 >= dig__fread_port_D(&(ptr->B), 1, fp))
-	    return -1;
-    }
-    else {
-	ptr->T = 0.0;
-	ptr->B = 0.0;
-    }
-
     Plus->Isle[n] = ptr;
 
     return (0);
@@ -548,23 +474,6 @@
     if (0 >= dig__fwrite_port_P(&(ptr->area), 1, fp))
 	return (-1);
 
-    /* bounding box */
-    if (0 >= dig__fwrite_port_D(&(ptr->N), 1, fp))
-	return (-1);
-    if (0 >= dig__fwrite_port_D(&(ptr->S), 1, fp))
-	return (-1);
-    if (0 >= dig__fwrite_port_D(&(ptr->E), 1, fp))
-	return (-1);
-    if (0 >= dig__fwrite_port_D(&(ptr->W), 1, fp))
-	return (-1);
-
-    if (Plus->with_z) {
-	if (0 >= dig__fwrite_port_D(&(ptr->T), 1, fp))
-	    return (-1);
-	if (0 >= dig__fwrite_port_D(&(ptr->B), 1, fp))
-	    return (-1);
-    }
-
     return (0);
 }
 

Modified: grass/trunk/lib/vector/diglib/spindex.c
===================================================================
--- grass/trunk/lib/vector/diglib/spindex.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/spindex.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -393,7 +393,7 @@
 
    \return 0
  */
-int dig_spidx_del_line(struct Plus_head *Plus, int line)
+int dig_spidx_del_line(struct Plus_head *Plus, int line, double x, double y, double z)
 {
     struct P_line *Line;
     struct Rect rect;
@@ -403,16 +403,13 @@
 
     Line = Plus->Line[line];
 
-    G_debug(3, "  box(x1,y1,z1,x2,y2,z2): %f %f %f %f %f %f", Line->W,
-	    Line->S, Line->B, Line->E, Line->N, Line->T);
+    rect.boundary[0] = x;
+    rect.boundary[1] = y;
+    rect.boundary[2] = z;
+    rect.boundary[3] = x;
+    rect.boundary[4] = y;
+    rect.boundary[5] = z;
 
-    rect.boundary[0] = Line->W;
-    rect.boundary[1] = Line->S;
-    rect.boundary[2] = Line->B;
-    rect.boundary[3] = Line->E;
-    rect.boundary[4] = Line->N;
-    rect.boundary[5] = Line->T;
-
     ret = RTreeDeleteRect(&rect, line, Plus->Line_spidx);
 
     G_debug(3, "  ret = %d", ret);
@@ -438,6 +435,9 @@
     int ret;
     struct P_area *Area;
     struct Rect rect;
+    struct P_line *Line;
+    struct P_node *Node;
+    struct P_topo_b *topo;
 
     G_debug(3, "dig_spidx_del_area(): area = %d", area);
 
@@ -447,13 +447,17 @@
 	G_fatal_error(_("Attempt to delete sidx for dead area"));
     }
 
-    rect.boundary[0] = Area->W;
-    rect.boundary[1] = Area->S;
-    rect.boundary[2] = Area->B;
-    rect.boundary[3] = Area->E;
-    rect.boundary[4] = Area->N;
-    rect.boundary[5] = Area->T;
+    Line = Plus->Line[Area->lines[0]];
+    topo = (struct P_topo_b *)Line->topo;
+    Node = Plus->Node[topo->N1];
 
+    rect.boundary[0] = Node->x;
+    rect.boundary[1] = Node->y;
+    rect.boundary[2] = Node->z;
+    rect.boundary[3] = Node->x;
+    rect.boundary[4] = Node->y;
+    rect.boundary[5] = Node->z;
+
     ret = RTreeDeleteRect(&rect, area, Plus->Area_spidx);
 
     if (ret)
@@ -477,18 +481,25 @@
     int ret;
     struct P_isle *Isle;
     struct Rect rect;
+    struct P_line *Line;
+    struct P_node *Node;
+    struct P_topo_b *topo;
 
     G_debug(3, "dig_spidx_del_isle(): isle = %d", isle);
 
     Isle = Plus->Isle[isle];
 
-    rect.boundary[0] = Isle->W;
-    rect.boundary[1] = Isle->S;
-    rect.boundary[2] = Isle->B;
-    rect.boundary[3] = Isle->E;
-    rect.boundary[4] = Isle->N;
-    rect.boundary[5] = Isle->T;
+    Line = Plus->Line[Isle->lines[0]];
+    topo = (struct P_topo_b *)Line->topo;
+    Node = Plus->Node[topo->N1];
 
+    rect.boundary[0] = Node->x;
+    rect.boundary[1] = Node->y;
+    rect.boundary[2] = Node->z;
+    rect.boundary[3] = Node->x;
+    rect.boundary[4] = Node->y;
+    rect.boundary[5] = Node->z;
+
     ret = RTreeDeleteRect(&rect, isle, Plus->Isle_spidx);
 
     if (ret)
@@ -497,13 +508,49 @@
     return 0;
 }
 
-/* This function is called by  RTreeSearch() to add selected node/line/area/isle to thelist */
-static int _add_item(int id, struct ilist *list)
+/* This function is called by RTreeSearch() to add selected node/line/area/isle to the list */
+static int _add_item(int id, struct Rect rect, struct ilist *list)
 {
     dig_list_add(list, id);
     return 1;
 }
 
+/* This function is called by RTreeSearch() to add 
+ * selected node/line/area/isle to the box list */
+static int _add_item_with_box(int id, struct Rect rect, struct boxlist *list)
+{
+    struct bound_box box;
+    
+    box.W = rect.boundary[0];
+    box.S = rect.boundary[1];
+    box.B = rect.boundary[2];
+    box.E = rect.boundary[3];
+    box.N = rect.boundary[4];
+    box.T = rect.boundary[5];
+
+    dig_boxlist_add(list, id, box);
+    return 1;
+}
+
+/* This function is called by RTreeSearch() to add 
+ * selected node/line/area/isle to the box list */
+static int _set_item_box(int id, struct Rect rect, struct boxlist *list)
+{
+    if (id == list->id[0]) {
+	
+	list->box[0].W = rect.boundary[0];
+	list->box[0].S = rect.boundary[1];
+	list->box[0].B = rect.boundary[2];
+	list->box[0].E = rect.boundary[3];
+	list->box[0].N = rect.boundary[4];
+	list->box[0].T = rect.boundary[5];
+	
+	return 0;
+    }
+
+    return 1;
+}
+
 /*!
    \brief Select nodes by bbox 
 
@@ -539,8 +586,8 @@
     return (list->n_values);
 }
 
-/* This function is called by  RTreeSearch() for nodes to add selected node to list */
-static int _add_node(int id, int *node)
+/* This function is called by RTreeSearch() for nodes to find the node id */
+static int _add_node(int id, struct Rect rect, int *node)
 {
     *node = id;
     return 0;
@@ -615,6 +662,74 @@
     return (list->n_values);
 }
 
+/*!
+   \brief Select lines with boxes by box
+
+   \param Plus pointer to Plus_head structure
+   \param box bounding box
+   \param list boxlist of selected lines
+
+   \return number of selected lines
+   \return 0 not found
+ */
+int dig_select_lines_with_box(struct Plus_head *Plus, const struct bound_box *box,
+		      struct boxlist *list)
+{
+    struct Rect rect;
+
+    G_debug(3, "dig_select_lines_with_box()");
+
+    list->n_values = 0;
+
+    rect.boundary[0] = box->W;
+    rect.boundary[1] = box->S;
+    rect.boundary[2] = box->B;
+    rect.boundary[3] = box->E;
+    rect.boundary[4] = box->N;
+    rect.boundary[5] = box->T;
+
+    if (Plus->Spidx_new)
+	RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list);
+    else
+	rtree_search(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list, Plus);
+
+    return (list->n_values);
+}
+
+/*!
+   \brief Find box for line
+
+   \param Plus pointer to Plus_head structure
+   \param[in,out] list line with isle id and search box (in)/line box (out)
+
+   \return number of lines found
+   \return 0 not found
+ */
+int dig_find_line_box(const struct Plus_head *Plus, struct boxlist *list)
+{
+    struct Rect rect;
+    int ret;
+
+    G_debug(3, "dig_find_line_box()");
+
+    if (list->n_values < 1)
+	G_fatal_error(_("No line id given"));
+
+    rect.boundary[0] = list->box[0].W;
+    rect.boundary[1] = list->box[0].S;
+    rect.boundary[2] = list->box[0].B;
+    rect.boundary[3] = list->box[0].E;
+    rect.boundary[4] = list->box[0].N;
+    rect.boundary[5] = list->box[0].T;
+
+    if (Plus->Spidx_new)
+	ret = RTreeSearch(Plus->Line_spidx, &rect, (void *)_set_item_box, list);
+    else
+	ret = rtree_search(Plus->Line_spidx, &rect, (void *)_set_item_box, list, Plus);
+
+    return (ret);
+}
+
 /*! 
    \brief Select areas by box 
 
@@ -649,7 +764,75 @@
     return (list->n_values);
 }
 
+/*! 
+   \brief Select areas with boxes by box 
+
+   \param Plus pointer to Plus_head structure
+   \param box bounding box
+   \param list boxlist of selected areas
+
+   \return number of selected areas
+ */
+int
+dig_select_areas_with_box(struct Plus_head *Plus, const struct bound_box * box,
+		 struct boxlist *list)
+{
+    struct Rect rect;
+
+    G_debug(3, "dig_select_areas_with_box()");
+
+    list->n_values = 0;
+
+    rect.boundary[0] = box->W;
+    rect.boundary[1] = box->S;
+    rect.boundary[2] = box->B;
+    rect.boundary[3] = box->E;
+    rect.boundary[4] = box->N;
+    rect.boundary[5] = box->T;
+
+    if (Plus->Spidx_new)
+	RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list);
+    else
+	rtree_search(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list, Plus);
+
+    return (list->n_values);
+}
+
 /*!
+   \brief Find box for area
+
+   \param Plus pointer to Plus_head structure
+   \param[in,out] list list with area id and search box (in)/area box (out)
+
+   \return number of areas found
+   \return 0 not found
+ */
+int dig_find_area_box(const struct Plus_head *Plus, struct boxlist *list)
+{
+    struct Rect rect;
+    int ret;
+
+    G_debug(3, "dig_find_line_box()");
+
+    if (list->n_values < 1)
+	G_fatal_error(_("No line id given"));
+
+    rect.boundary[0] = list->box[0].W;
+    rect.boundary[1] = list->box[0].S;
+    rect.boundary[2] = list->box[0].B;
+    rect.boundary[3] = list->box[0].E;
+    rect.boundary[4] = list->box[0].N;
+    rect.boundary[5] = list->box[0].T;
+
+    if (Plus->Spidx_new)
+	ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, list);
+    else
+	ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, list, Plus);
+
+    return (ret);
+}
+
+/*!
    \brief Select isles by box 
 
    \param Plus pointer to Plus_head structure
@@ -682,3 +865,71 @@
 
     return (list->n_values);
 }
+
+/*! 
+   \brief Select isles with boxes by box 
+
+   \param Plus pointer to Plus_head structure
+   \param box bounding box
+   \param list boxlist of selected isles
+
+   \return number of selected isles
+ */
+int
+dig_select_isles_with_box(struct Plus_head *Plus, const struct bound_box * box,
+		 struct boxlist *list)
+{
+    struct Rect rect;
+
+    G_debug(3, "dig_select_areas_with_box()");
+
+    list->n_values = 0;
+
+    rect.boundary[0] = box->W;
+    rect.boundary[1] = box->S;
+    rect.boundary[2] = box->B;
+    rect.boundary[3] = box->E;
+    rect.boundary[4] = box->N;
+    rect.boundary[5] = box->T;
+
+    if (Plus->Spidx_new)
+	RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list);
+    else
+	rtree_search(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list, Plus);
+
+    return (list->n_values);
+}
+
+/*!
+   \brief Find box for isle
+
+   \param Plus pointer to Plus_head structure
+   \param[in,out] list list with isle id and search box (in)/isle box (out)
+
+   \return number of isles found
+   \return 0 not found
+ */
+int dig_find_isle_box(const struct Plus_head *Plus, struct boxlist *list)
+{
+    struct Rect rect;
+    int ret;
+
+    G_debug(3, "dig_find_line_box()");
+
+    if (list->n_values < 1)
+	G_fatal_error(_("No line id given"));
+
+    rect.boundary[0] = list->box[0].W;
+    rect.boundary[1] = list->box[0].S;
+    rect.boundary[2] = list->box[0].B;
+    rect.boundary[3] = list->box[0].E;
+    rect.boundary[4] = list->box[0].N;
+    rect.boundary[5] = list->box[0].T;
+
+    if (Plus->Spidx_new)
+	ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, list);
+    else
+	ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, list, Plus);
+
+    return (ret);
+}

Modified: grass/trunk/lib/vector/diglib/spindex_rw.c
===================================================================
--- grass/trunk/lib/vector/diglib/spindex_rw.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/spindex_rw.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -1368,7 +1368,8 @@
 		    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, cbarg)) {
+			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;
 			}

Modified: grass/trunk/lib/vector/diglib/struct_alloc.c
===================================================================
--- grass/trunk/lib/vector/diglib/struct_alloc.c	2011-07-01 08:53:00 UTC (rev 46899)
+++ grass/trunk/lib/vector/diglib/struct_alloc.c	2011-07-01 08:53:19 UTC (rev 46900)
@@ -124,13 +124,45 @@
     Line = (struct P_line *) G_malloc(sizeof(struct P_line));
     if (Line == NULL)
         return NULL;
+	
+    Line->topo = NULL;
 
     return (Line);
 }
 
+/* allocate new topo structure */
+void *dig_alloc_topo(char type)
+{
+    void *Topo = NULL;
+
+    switch (type) {
+	case GV_LINE:
+	Topo = G_malloc(sizeof(struct P_topo_l));
+	break;
+    case GV_BOUNDARY:
+	Topo = G_malloc(sizeof(struct P_topo_b));
+	break;
+    case GV_CENTROID:
+	Topo = G_malloc(sizeof(struct P_topo_c));
+	break;
+    case GV_FACE:
+	Topo = G_malloc(sizeof(struct P_topo_f));
+	break;
+    case GV_KERNEL:
+	Topo = G_malloc(sizeof(struct P_topo_k));
+	break;
+    default:
+	return NULL;
+    }
+
+    return (Topo);
+}
+
 /* free line structure */
 void dig_free_line(struct P_line *Line)
 {
+    if (Line->topo)
+	G_free(Line->topo);
     G_free(Line);
 }
 



More information about the grass-commit mailing list