[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