فهرست منبع

update vectorlib.dox

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@56890 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 12 سال پیش
والد
کامیت
c0f639f291

+ 14 - 2
lib/vector/Vlib/dgraph.c

@@ -222,8 +222,8 @@ struct seg_intersections *find_all_intersections(const struct line_pnts *Points)
     int looped;
     int looped;
     /* double EPSILON = 0.00000001; */
     /* double EPSILON = 0.00000001; */
     double EPSILON = GRASS_EPSILON;
     double EPSILON = GRASS_EPSILON;
-    double *x, *y;
-    double x1, y1, x2, y2;
+    double *x, *y, az1, az2, bz1, bz2;
+    double x1, y1, z1, x2, y2, z2;
     int res;
     int res;
 
 
     /*int res2
     /*int res2
@@ -237,6 +237,7 @@ struct seg_intersections *find_all_intersections(const struct line_pnts *Points)
     np = Points->n_points;
     np = Points->n_points;
     x = Points->x;
     x = Points->x;
     y = Points->y;
     y = Points->y;
+    az1 = az2 = bz1 = bz2 = 0;
 
 
     si = create_si_struct(np - 1);
     si = create_si_struct(np - 1);
 
 
@@ -252,6 +253,17 @@ struct seg_intersections *find_all_intersections(const struct line_pnts *Points)
 		segment_intersection_2d(x[i], y[i], x[i + 1], y[i + 1], x[j],
 		segment_intersection_2d(x[i], y[i], x[i + 1], y[i + 1], x[j],
 					y[j], x[j + 1], y[j + 1], &x1, &y1,
 					y[j], x[j + 1], y[j + 1], &x1, &y1,
 					&x2, &y2);
 					&x2, &y2);
+
+	    /*
+	    res =
+		Vect_segment_intersection(x[i], y[i], az1,
+		                          x[i + 1], y[i + 1], az2,
+					  x[j], y[j], bz1,
+					  x[j + 1], y[j + 1], bz2, 
+					  &x1, &y1, &z1, &x2, &y2, &z2, 0);
+	    */
+
+
 	    /*            res2 = segment_intersection_2d_e(x[i], y[i], x[i+1], y[i+1], x[j], y[j], x[j+1], y[j+1], &x1_, &y1_, &x2_, &y2_);
 	    /*            res2 = segment_intersection_2d_e(x[i], y[i], x[i+1], y[i+1], x[j], y[j], x[j+1], y[j+1], &x1_, &y1_, &x2_, &y2_);
 	       if ((res != res2) || ((res != 0) && (x1!=x1_ || y1!=y1_)) ) {
 	       if ((res != res2) || ((res != 0) && (x1!=x1_ || y1!=y1_)) ) {
 	       G_debug(1, "exact=%d orig=%d", res, res2);
 	       G_debug(1, "exact=%d orig=%d", res, res2);

+ 25 - 25
lib/vector/Vlib/e_intersect.c

@@ -745,6 +745,31 @@ int segment_intersection_2d(double ax1, double ay1, double ax2, double ay2,
 	return 0;
 	return 0;
     }
     }
 
 
+    /* swap endpoints if needed */
+    /* if segments are vertical, we swap x-coords with y-coords */
+    vertical = 0;
+    if (ax1 > ax2) {
+	SWAP(ax1, ax2);
+	SWAP(ay1, ay2);
+    }
+    else if (ax1 == ax2) {
+	vertical = 1;
+	if (ay1 > ay2)
+	    SWAP(ay1, ay2);
+	SWAP(ax1, ay1);
+	SWAP(ax2, ay2);
+    }
+    if (bx1 > bx2) {
+	SWAP(bx1, bx2);
+	SWAP(by1, by2);
+    }
+    else if (bx1 == bx2) {
+	if (by1 > by2)
+	    SWAP(by1, by2);
+	SWAP(bx1, by1);
+	SWAP(bx2, by2);
+    }
+
     d = D;
     d = D;
     if (d != 0) {
     if (d != 0) {
 	G_debug(DLEVEL, "    general position");
 	G_debug(DLEVEL, "    general position");
@@ -805,31 +830,6 @@ int segment_intersection_2d(double ax1, double ay1, double ax2, double ay2,
 
 
     /* segments are colinear. check for overlap */
     /* segments are colinear. check for overlap */
 
 
-    /* swap endpoints if needed */
-    /* if segments are vertical, we swap x-coords with y-coords */
-    vertical = 0;
-    if (ax1 > ax2) {
-	SWAP(ax1, ax2);
-	SWAP(ay1, ay2);
-    }
-    else if (ax1 == ax2) {
-	vertical = 1;
-	if (ay1 > ay2)
-	    SWAP(ay1, ay2);
-	SWAP(ax1, ay1);
-	SWAP(ax2, ay2);
-    }
-    if (bx1 > bx2) {
-	SWAP(bx1, bx2);
-	SWAP(by1, by2);
-    }
-    else if (bx1 == bx2) {
-	if (by1 > by2)
-	    SWAP(by1, by2);
-	SWAP(bx1, by1);
-	SWAP(bx2, by2);
-    }
-
     G_debug(DLEVEL, "    collinear segments");
     G_debug(DLEVEL, "    collinear segments");
 
 
     if ((bx2 < ax1) || (bx1 > ax2)) {
     if ((bx2 < ax1) || (bx1 > ax2)) {

+ 1 - 0
lib/vector/diglib/head.c

@@ -75,6 +75,7 @@ int dig__write_head(struct Map_info *Map)
     }
     }
 
 
     G_debug(2, "coor body offset %"PRI_OFF_T, dig_ftell(&(Map->dig_fp)));
     G_debug(2, "coor body offset %"PRI_OFF_T, dig_ftell(&(Map->dig_fp)));
+
     return 1;
     return 1;
 }
 }
 
 

+ 8 - 16
lib/vector/diglib/portable.c

@@ -192,15 +192,13 @@ int dig__fread_port_O(off_t *buf, size_t cnt, struct gvfile * fp, size_t port_of
 		if (off_t_order == ENDIAN_LITTLE) {
 		if (off_t_order == ENDIAN_LITTLE) {
 		    if (c1[port_off_t_size - 1] & 0x80)
 		    if (c1[port_off_t_size - 1] & 0x80)
 			memset(c2, 0xff, sizeof(off_t));
 			memset(c2, 0xff, sizeof(off_t));
+		    memcpy(c2, c1, port_off_t_size);
 		}
 		}
 		else {
 		else {
 		    if (c1[0] & 0x80)
 		    if (c1[0] & 0x80)
 			memset(c2, 0xff, sizeof(off_t));
 			memset(c2, 0xff, sizeof(off_t));
-		}
-		if (off_t_order == ENDIAN_LITTLE)
-		    memcpy(c2, c1, port_off_t_size);
-		else
 		    memcpy(c2 + nat_off_t - port_off_t_size, c1, port_off_t_size);
 		    memcpy(c2 + nat_off_t - port_off_t_size, c1, port_off_t_size);
+		}
 		c1 += port_off_t_size;
 		c1 += port_off_t_size;
 		c2 += sizeof(off_t);
 		c2 += sizeof(off_t);
 	    }
 	    }
@@ -287,15 +285,13 @@ int dig__fread_port_L(long *buf, size_t cnt, struct gvfile * fp)
 		if (lng_order == ENDIAN_LITTLE) {
 		if (lng_order == ENDIAN_LITTLE) {
 		    if (c1[PORT_LONG - 1] & 0x80)
 		    if (c1[PORT_LONG - 1] & 0x80)
 			memset(c2, 0xff, sizeof(long));
 			memset(c2, 0xff, sizeof(long));
+		    memcpy(c2, c1, PORT_LONG);
 		}
 		}
 		else {
 		else {
 		    if (c1[0] & 0x80)
 		    if (c1[0] & 0x80)
 			memset(c2, 0xff, sizeof(long));
 			memset(c2, 0xff, sizeof(long));
-		}
-		if (lng_order == ENDIAN_LITTLE)
-		    memcpy(c2, c1, PORT_LONG);
-		else
 		    memcpy(c2 + nat_lng - PORT_LONG, c1, PORT_LONG);
 		    memcpy(c2 + nat_lng - PORT_LONG, c1, PORT_LONG);
+		}
 		c1 += PORT_LONG;
 		c1 += PORT_LONG;
 		c2 += sizeof(long);
 		c2 += sizeof(long);
 	    }
 	    }
@@ -372,15 +368,13 @@ int dig__fread_port_I(int *buf, size_t cnt, struct gvfile * fp)
 		if (int_order == ENDIAN_LITTLE) {
 		if (int_order == ENDIAN_LITTLE) {
 		    if (c1[PORT_INT - 1] & 0x80)
 		    if (c1[PORT_INT - 1] & 0x80)
 			memset(c2, 0xff, sizeof(int));
 			memset(c2, 0xff, sizeof(int));
+		    memcpy(c2, c1, PORT_INT);
 		}
 		}
 		else {
 		else {
 		    if (c1[0] & 0x80)
 		    if (c1[0] & 0x80)
 			memset(c2, 0xff, sizeof(int));
 			memset(c2, 0xff, sizeof(int));
-		}
-		if (int_order == ENDIAN_LITTLE)
-		    memcpy(c2, c1, PORT_INT);
-		else
 		    memcpy(c2 + nat_int - PORT_INT, c1, PORT_INT);
 		    memcpy(c2 + nat_int - PORT_INT, c1, PORT_INT);
+		}
 		c1 += PORT_INT;
 		c1 += PORT_INT;
 		c2 += sizeof(int);
 		c2 += sizeof(int);
 	    }
 	    }
@@ -457,15 +451,13 @@ int dig__fread_port_S(short *buf, size_t cnt, struct gvfile * fp)
 		if (shrt_order == ENDIAN_LITTLE) {
 		if (shrt_order == ENDIAN_LITTLE) {
 		    if (c1[PORT_SHORT - 1] & 0x80)
 		    if (c1[PORT_SHORT - 1] & 0x80)
 			memset(c2, 0xff, sizeof(short));
 			memset(c2, 0xff, sizeof(short));
+		    memcpy(c2, c1, PORT_SHORT);
 		}
 		}
 		else {
 		else {
 		    if (c1[0] & 0x80)
 		    if (c1[0] & 0x80)
 			memset(c2, 0xff, sizeof(short));
 			memset(c2, 0xff, sizeof(short));
-		}
-		if (shrt_order == ENDIAN_LITTLE)
-		    memcpy(c2, c1, PORT_SHORT);
-		else
 		    memcpy(c2 + nat_shrt - PORT_SHORT, c1, PORT_SHORT);
 		    memcpy(c2 + nat_shrt - PORT_SHORT, c1, PORT_SHORT);
+		}
 		c1 += PORT_SHORT;
 		c1 += PORT_SHORT;
 		c2 += sizeof(short);
 		c2 += sizeof(short);
 	    }
 	    }

+ 3 - 2
lib/vector/neta/articulation_point.c

@@ -100,11 +100,12 @@ int NetA_articulation_points(dglGraph_s * graph,
 			min_tin[node_id] = min_tin[to];
 			min_tin[node_id] = min_tin[to];
 		    current_edge[node_id] = dglEdgeset_T_Next(&current[node_id]);	/*proceed to the next edge */
 		    current_edge[node_id] = dglEdgeset_T_Next(&current[node_id]);	/*proceed to the next edge */
 		}
 		}
-		for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(&current[node_id])) {	/* try next edges */
+		/*try next edges */
+		for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(&current[node_id])) {
 		    dglInt32_t *to =
 		    dglInt32_t *to =
 			dglEdgeGet_Tail(graph, current_edge[node_id]);
 			dglEdgeGet_Tail(graph, current_edge[node_id]);
 		    if (to == parent[node_id])
 		    if (to == parent[node_id])
-			continue;	/*skip parrent */
+			continue;	/*skip parent */
 		    int to_id = dglNodeGet_Id(graph, to);
 		    int to_id = dglNodeGet_Id(graph, to);
 
 
 		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
 		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */

+ 32 - 8
lib/vector/neta/path.c

@@ -22,7 +22,7 @@
 #include <grass/neta.h>
 #include <grass/neta.h>
 
 
 /*!
 /*!
-   \brief Computes shortests paths to every node from  nodes in "from".
+   \brief Computes shortests paths to every node from nodes in "from".
 
 
    Array "dst" contains the length of the path or -1 if the node is not
    Array "dst" contains the length of the path or -1 if the node is not
    reachable. Prev contains edges from predecessor along the shortest
    reachable. Prev contains edges from predecessor along the shortest
@@ -36,8 +36,8 @@
    \return 0 on success
    \return 0 on success
    \return -1 on failure
    \return -1 on failure
  */
  */
-int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from,
-			      int *dst, dglInt32_t ** prev)
+int NetA_distance_from_points(dglGraph_s *graph, struct ilist *from,
+			      int *dst, dglInt32_t **prev)
 {
 {
     int i, nnodes;
     int i, nnodes;
     dglHeap_s heap;
     dglHeap_s heap;
@@ -45,6 +45,7 @@ int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from,
     nnodes = dglGet_NodeCount(graph);
     nnodes = dglGet_NodeCount(graph);
     dglEdgesetTraverser_s et;
     dglEdgesetTraverser_s et;
 
 
+    /* initialize costs and edge list */
     for (i = 1; i <= nnodes; i++) {
     for (i = 1; i <= nnodes; i++) {
 	dst[i] = -1;
 	dst[i] = -1;
 	prev[i] = NULL;
 	prev[i] = NULL;
@@ -55,13 +56,13 @@ int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from,
     for (i = 0; i < from->n_values; i++) {
     for (i = 0; i < from->n_values; i++) {
 	int v = from->value[i];
 	int v = from->value[i];
 
 
-	if (dst[v] == 0)
+	if (dst[v] == -2)
 	    continue;		/*ingore duplicates */
 	    continue;		/*ingore duplicates */
-	dst[v] = 0;
+	dst[v] = -2;		/* make sure all from nodes are processed first */
 	dglHeapData_u heap_data;
 	dglHeapData_u heap_data;
 
 
 	heap_data.ul = v;
 	heap_data.ul = v;
-	dglHeapInsertMin(&heap, 0, ' ', heap_data);
+	dglHeapInsertMin(&heap, -2, ' ', heap_data);
     }
     }
     while (1) {
     while (1) {
 	dglInt32_t v, dist;
 	dglInt32_t v, dist;
@@ -80,13 +81,26 @@ int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from,
 	dglEdgeset_T_Initialize(&et, graph,
 	dglEdgeset_T_Initialize(&et, graph,
 				dglNodeGet_OutEdgeset(graph,
 				dglNodeGet_OutEdgeset(graph,
 						      dglGetNode(graph, v)));
 						      dglGetNode(graph, v)));
+
+	if (dglGet_NodeAttrSize(graph) > 0) {
+	    dglInt32_t ncost;
+	    
+	    memcpy(&ncost, dglNodeGet_Attr(graph, dglGetNode(graph, v)),
+		   sizeof(ncost));
+	    /* do not route paths through closed nodes */
+	    if (ncost < 0 && dist >= 0)
+		continue;
+
+	    dist += ncost;
+	}
+
 	for (edge = dglEdgeset_T_First(&et); edge;
 	for (edge = dglEdgeset_T_First(&et); edge;
 	     edge = dglEdgeset_T_Next(&et)) {
 	     edge = dglEdgeset_T_Next(&et)) {
 	    dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
 	    dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
 	    dglInt32_t to_id = dglNodeGet_Id(graph, to);
 	    dglInt32_t to_id = dglNodeGet_Id(graph, to);
 	    dglInt32_t d = dglEdgeGet_Cost(graph, edge);
 	    dglInt32_t d = dglEdgeGet_Cost(graph, edge);
 
 
-	    if (dst[to_id] == -1 || dst[to_id] > dist + d) {
+	    if (dst[to_id] < 0 || dst[to_id] > dist + d) {
 		dst[to_id] = dist + d;
 		dst[to_id] = dist + d;
 		prev[to_id] = edge;
 		prev[to_id] = edge;
 		heap_data.ul = to_id;
 		heap_data.ul = to_id;
@@ -105,7 +119,7 @@ int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from,
 /*!
 /*!
    \brief Find a path (minimum number of edges) from 'from' to 'to' using only edges in 'edges'.
    \brief Find a path (minimum number of edges) from 'from' to 'to' using only edges in 'edges'.
 
 
-   Precisely, edge with id I is used iff edges[abs(i)] == 1. List
+   Precisely, edge with id I is used if edges[abs(i)] == 1. List
    stores the indices of lines on the path. Method return number of
    stores the indices of lines on the path. Method return number of
    edges or -1 if no path exist.
    edges or -1 if no path exist.
 
 
@@ -148,6 +162,16 @@ int NetA_find_path(dglGraph_s * graph, int from, int to, int *edges,
 	    break;
 	    break;
 	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
 	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
 
 
+
+	if (dglGet_NodeAttrSize(graph) > 0) {
+	    dglInt32_t ncost;
+	    
+	    memcpy(&ncost, dglNodeGet_Attr(graph, node), sizeof(ncost));
+	    /* do not route paths through closed nodes */
+	    if (ncost < 0 && vertex != from)
+		continue;
+	}
+
 	dglEdgeset_T_Initialize(&et, graph,
 	dglEdgeset_T_Initialize(&et, graph,
 				dglNodeGet_OutEdgeset(graph, node));
 				dglNodeGet_OutEdgeset(graph, node));
 	for (edge = dglEdgeset_T_First(&et); edge;
 	for (edge = dglEdgeset_T_First(&et); edge;

+ 3 - 0
lib/vector/rtree/node.c

@@ -36,6 +36,7 @@ struct dist
 static void RTreeInitNodeBranchM(struct RTree_Branch *b, struct RTree *t)
 static void RTreeInitNodeBranchM(struct RTree_Branch *b, struct RTree *t)
 {
 {
     RTreeInitRect(&(b->rect), t);
     RTreeInitRect(&(b->rect), t);
+    memset(&(b->child), 0, sizeof(union RTree_Child));
     b->child.ptr = NULL;
     b->child.ptr = NULL;
 }
 }
 
 
@@ -43,6 +44,7 @@ static void RTreeInitNodeBranchM(struct RTree_Branch *b, struct RTree *t)
 static void RTreeInitNodeBranchF(struct RTree_Branch *b, struct RTree *t)
 static void RTreeInitNodeBranchF(struct RTree_Branch *b, struct RTree *t)
 {
 {
     RTreeInitRect(&(b->rect), t);
     RTreeInitRect(&(b->rect), t);
+    memset(&(b->child), 0, sizeof(union RTree_Child));
     b->child.pos = -1;
     b->child.pos = -1;
 }
 }
 
 
@@ -50,6 +52,7 @@ static void RTreeInitNodeBranchF(struct RTree_Branch *b, struct RTree *t)
 static void RTreeInitLeafBranch(struct RTree_Branch *b, struct RTree *t)
 static void RTreeInitLeafBranch(struct RTree_Branch *b, struct RTree *t)
 {
 {
     RTreeInitRect(&(b->rect), t);
     RTreeInitRect(&(b->rect), t);
+    memset(&(b->child), 0, sizeof(union RTree_Child));
     b->child.id = 0;
     b->child.id = 0;
 }
 }
 
 

+ 17 - 12
lib/vector/vectorlib.dox

@@ -32,7 +32,7 @@ besides the coordinates describing the location of the primitives
 (points, lines, boundaries, centroids, faces, kernels, and volumes),
 (points, lines, boundaries, centroids, faces, kernels, and volumes),
 their spatial relations are also stored. In general, topological GIS
 their spatial relations are also stored. In general, topological GIS
 requires a data structure where the common boundary between two
 requires a data structure where the common boundary between two
-adjacent areas is stored as a single line, simplifying the vector data
+adjacent areas is stored as a single boundary, simplifying vector data
 maintenance.
 maintenance.
 
 
 
 
@@ -75,19 +75,24 @@ The current implementation includes:
 
 
 GRASS vector maps are stored in an <em>arc-node</em> representation,
 GRASS vector maps are stored in an <em>arc-node</em> representation,
 consisting of curves called arcs. An arc is stored as a series of
 consisting of curves called arcs. An arc is stored as a series of
-x,y,z coordinate pairs. The two endpoints of an arc are called
-<em>nodes</em>. Two consecutive x,y,z pairs define an arc segment. The
-user specifies the type of input to GRASS; GRASS doesn't decide. GRASS
+x,y,z coordinate pairs. Two consecutive x,y,z pairs define an arc segment. 
+<em>Nodes</em> are created automatically for the two endpoints of an arc. 
+The user specifies the type of input to GRASS; GRASS doesn't decide. GRASS
 supports feature type definition which allows for multiple types to
 supports feature type definition which allows for multiple types to
-co-exist in the same map. A centroid is assigned to the area it is
-within/inside (geometrically). An area is defined by one or more 
-boundaries that form a losed ring. The category to which an area belongs 
+co-exist in the same map. An area is defined by one or more 
+boundaries that form a closed ring. A centroid is assigned to the area it is
+within/inside (geometrically). The category to which an area belongs 
 is stored with the centroid. Such centroids are stored in the same binary
 is stored with the centroid. Such centroids are stored in the same binary
-'coor' file with other primitives. Each element may have none, one or
-more categories (cats). More cats can be distinguished by field number
-(field, called "layer" at user level).  Single and multi-category
-support on modules level are implemented. The z coordinate is optional 
-and both 2D and 3D files may be written.
+'coor' file with other primitives. Areas without centroids are from a 
+user's perspective holes within another area, therefore not presented to 
+a user as a real area, the equivalent of a polygon in Simple Feature Access.
+Each vector object may have none, one or more categories (cats). More 
+categories can be distinguished by field number (field, called "layer" 
+at user level). A vector object can also have multiple categories in the 
+same layer, an example would be buffers where a single area might belong 
+to multiple buffers of multiple buffered features. Single and 
+multi-category support on module level is implemented. The z coordinate 
+is optional and both 2D and 3D files may be written.
 
 
 The following <em>vector feature types (primitives)</em> are defined
 The following <em>vector feature types (primitives)</em> are defined
 by the vector library (and holds by the coor file; see also \ref
 by the vector library (and holds by the coor file; see also \ref