[GRASS-SVN] r67984 - in grass/trunk: include/defs lib/vector/Vlib lib/vector/neta

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Mar 1 15:21:49 PST 2016


Author: mmetz
Date: 2016-03-01 15:21:49 -0800 (Tue, 01 Mar 2016)
New Revision: 67984

Modified:
   grass/trunk/include/defs/neta.h
   grass/trunk/lib/vector/Vlib/net_build.c
   grass/trunk/lib/vector/neta/path.c
Log:
vectorlib: +NetA_distance_to_points()

Modified: grass/trunk/include/defs/neta.h
===================================================================
--- grass/trunk/include/defs/neta.h	2016-03-01 08:54:52 UTC (rev 67983)
+++ grass/trunk/include/defs/neta.h	2016-03-01 23:21:49 UTC (rev 67984)
@@ -40,6 +40,8 @@
 /*path.c */
 int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from, int *dst,
 			      dglInt32_t ** prev);
+int NetA_distance_to_points(dglGraph_s * graph, struct ilist *to, int *dst,
+			      dglInt32_t ** nxt);
 int NetA_find_path(dglGraph_s * graph, int from, int to, int *edges,
 		   struct ilist *list);
 

Modified: grass/trunk/lib/vector/Vlib/net_build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/net_build.c	2016-03-01 08:54:52 UTC (rev 67983)
+++ grass/trunk/lib/vector/Vlib/net_build.c	2016-03-01 23:21:49 UTC (rev 67984)
@@ -84,7 +84,7 @@
     /*TODO attributes of turntable shoud be stored in one place */
     const char *tcols[] = { "cat", "ln_from", "ln_to", "cost", "isec", NULL
     };
-    dbCatValArray tvarrs[5] = { };
+    dbCatValArray tvarrs[5];
     int tctype[5] = { 0 };
     int tucfield_idx;
 
@@ -687,7 +687,7 @@
    \param abcol column with backward costs for arc (if NULL, back costs = forward costs), 
    \param ncol column with costs for nodes (if NULL, do not use node costs), 
    \param geo use geodesic calculation for length (LL), 
-   \param algorithm not used (in future code for algorithm)
+   \param version graph version to create (1, 2, 3)
 
    \return 0 on success, 1 on error
  */
@@ -698,7 +698,7 @@
 		     int nfield,
 		     const char *afcol,
 		     const char *abcol,
-		     const char *ncol, int geo, int algorithm)
+		     const char *ncol, int geo, int version)
 {
     /* TODO long function, split into smaller ones */
     int i, j, from, to, line, nlines, nnodes, ret, type, cat, skipped, cfound;
@@ -761,11 +761,14 @@
 	Map->dgraph.node_costs[i] = 0;
     }
 
+    if (version < 1 || version > 3)
+	version = 1;
+
     if (ncol != NULL)
-	dglInitialize(gr, (dglByte_t) 1, sizeof(dglInt32_t), (dglInt32_t) 0,
+	dglInitialize(gr, (dglByte_t) version, sizeof(dglInt32_t), (dglInt32_t) 0,
 		      opaqueset);
     else
-	dglInitialize(gr, (dglByte_t) 1, (dglInt32_t) 0, (dglInt32_t) 0,
+	dglInitialize(gr, (dglByte_t) version, (dglInt32_t) 0, (dglInt32_t) 0,
 		      opaqueset);
 
     if (gr == NULL)

Modified: grass/trunk/lib/vector/neta/path.c
===================================================================
--- grass/trunk/lib/vector/neta/path.c	2016-03-01 08:54:52 UTC (rev 67983)
+++ grass/trunk/lib/vector/neta/path.c	2016-03-01 23:21:49 UTC (rev 67984)
@@ -22,7 +22,7 @@
 #include <grass/neta.h>
 
 /*!
-   \brief Computes shortests paths to every node from nodes in "from".
+   \brief Computes shortest paths to every node from nodes in "from".
 
    Array "dst" contains the length of the path or -1 if the node is not
    reachable. Prev contains edges from predecessor along the shortest
@@ -57,7 +57,7 @@
 	int v = from->value[i];
 
 	if (dst[v] == 0)
-	    continue;		/*ingore duplicates */
+	    continue;		/* ignore duplicates */
 	dst[v] = 0;		/* make sure all from nodes are processed first */
 	dglHeapData_u heap_data;
 
@@ -105,6 +105,94 @@
 }
 
 /*!
+   \brief Computes shortest paths from every node to nodes in "to".
+
+   Array "dst" contains the length of the path or -1 if the node is not
+   reachable. Nxt contains edges from successor along the shortest
+   path.
+
+   \param graph input graph
+   \param from list of 'from' positions
+   \param dst list of 'to' positions
+   \param[out] nxt list of edges from successor along the shortest path
+
+   \return 0 on success
+   \return -1 on failure
+ */
+int NetA_distance_to_points(dglGraph_s *graph, struct ilist *to,
+			      int *dst, dglInt32_t **nxt)
+{
+    int i, nnodes;
+    dglHeap_s heap;
+    dglEdgesetTraverser_s et;
+
+    nnodes = dglGet_NodeCount(graph);
+
+    /* initialize costs and edge list */
+    for (i = 1; i <= nnodes; i++) {
+	dst[i] = -1;
+	nxt[i] = NULL;
+    }
+
+    if (graph->Version < 2) {
+	G_warning("Directed graph must be version 2 or 3 for NetA_distance_to_points()");
+	return -1;
+    }
+
+    dglHeapInit(&heap);
+
+    for (i = 0; i < to->n_values; i++) {
+	int v = to->value[i];
+
+	if (dst[v] == 0)
+	    continue;		/* ignore duplicates */
+	dst[v] = 0;		/* make sure all to nodes are processed first */
+	dglHeapData_u heap_data;
+
+	heap_data.ul = v;
+	dglHeapInsertMin(&heap, 0, ' ', heap_data);
+    }
+    while (1) {
+	dglInt32_t v, dist;
+	dglHeapNode_s heap_node;
+	dglHeapData_u heap_data;
+
+	if (!dglHeapExtractMin(&heap, &heap_node))
+	    break;
+	v = heap_node.value.ul;
+	dist = heap_node.key;
+	if (dst[v] < dist)
+	    continue;
+
+	dglInt32_t *edge;
+
+	dglEdgeset_T_Initialize(&et, graph,
+				dglNodeGet_InEdgeset(graph,
+						      dglGetNode(graph, v)));
+
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et)) {
+	    dglInt32_t *from = dglEdgeGet_Head(graph, edge);
+	    dglInt32_t from_id = dglNodeGet_Id(graph, from);
+	    dglInt32_t d = dglEdgeGet_Cost(graph, edge);
+
+	    if (dst[from_id] < 0 || dst[from_id] > dist + d) {
+		dst[from_id] = dist + d;
+		nxt[from_id] = edge;
+		heap_data.ul = from_id;
+		dglHeapInsertMin(&heap, dist + d, ' ', heap_data);
+	    }
+	}
+
+	dglEdgeset_T_Release(&et);
+    }
+
+    dglHeapFree(&heap, NULL);
+
+    return 0;
+}
+
+/*!
    \brief Find a path (minimum number of edges) from 'from' to 'to' using only edges in 'edges'.
 
    Precisely, edge with id I is used if edges[abs(i)] == 1. List



More information about the grass-commit mailing list