[GRASS-SVN] r41783 - in grass/branches/develbranch_6: include include/Make lib lib/vector lib/vector/neta

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Apr 10 14:00:55 EDT 2010


Author: martinl
Date: 2010-04-10 14:00:54 -0400 (Sat, 10 Apr 2010)
New Revision: 41783

Added:
   grass/branches/develbranch_6/include/neta.h
   grass/branches/develbranch_6/lib/vector/neta/
   grass/branches/develbranch_6/lib/vector/neta/Makefile
   grass/branches/develbranch_6/lib/vector/neta/allpairs.c
   grass/branches/develbranch_6/lib/vector/neta/articulation_point.c
   grass/branches/develbranch_6/lib/vector/neta/bridge.c
   grass/branches/develbranch_6/lib/vector/neta/centrality.c
   grass/branches/develbranch_6/lib/vector/neta/components.c
   grass/branches/develbranch_6/lib/vector/neta/flow.c
   grass/branches/develbranch_6/lib/vector/neta/netalib.dox
   grass/branches/develbranch_6/lib/vector/neta/path.c
   grass/branches/develbranch_6/lib/vector/neta/spanningtree.c
   grass/branches/develbranch_6/lib/vector/neta/timetables.c
   grass/branches/develbranch_6/lib/vector/neta/utils.c
Removed:
   grass/branches/develbranch_6/lib/vector/neta/Makefile
   grass/branches/develbranch_6/lib/vector/neta/allpairs.c
   grass/branches/develbranch_6/lib/vector/neta/articulation_point.c
   grass/branches/develbranch_6/lib/vector/neta/bridge.c
   grass/branches/develbranch_6/lib/vector/neta/centrality.c
   grass/branches/develbranch_6/lib/vector/neta/components.c
   grass/branches/develbranch_6/lib/vector/neta/flow.c
   grass/branches/develbranch_6/lib/vector/neta/path.c
   grass/branches/develbranch_6/lib/vector/neta/spanningtree.c
   grass/branches/develbranch_6/lib/vector/neta/timetables.c
   grass/branches/develbranch_6/lib/vector/neta/utils.c
Modified:
   grass/branches/develbranch_6/include/Make/Grass.make.in
   grass/branches/develbranch_6/lib/grasslib.dox
   grass/branches/develbranch_6/lib/vector/Makefile
Log:
added neta lib from grass-addons
(merge r41777-r41779 from trunk)


Modified: grass/branches/develbranch_6/include/Make/Grass.make.in
===================================================================
--- grass/branches/develbranch_6/include/Make/Grass.make.in	2010-04-10 17:25:50 UTC (rev 41782)
+++ grass/branches/develbranch_6/include/Make/Grass.make.in	2010-04-10 18:00:54 UTC (rev 41783)
@@ -141,6 +141,7 @@
 RTREE_LIBNAME         = grass_rtree
 
 VEDIT_LIBNAME         = grass_vedit
+NETA_LIBNAME          = grass_neta
 
 # Interpolation
 INTERPDATA_LIBNAME    = grass_interpdata
@@ -246,6 +247,7 @@
 GRAPHLIB      = -l$(GRAPH_LIBNAME)
 RTREELIB      = -l$(RTREE_LIBNAME)
 VEDITLIB      = -l$(VEDIT_LIBNAME) $(GISLIB) $(VECTRLIB)
+NETALIB       = -l$(NETA_LIBNAME) $(GISLIB) $(VECTRLIB) $(GRAPHLIB)
 VECTLIB       = $(VECTRLIB) $(DIG2LIB) $(GRAPHLIB) $(RTREELIB) $(LINKMLIB) $(DBMILIB) $(GDALLIBS) $(GEOSLIBS)
 
 # Interpolation
@@ -344,6 +346,7 @@
 GRAPHDEP    = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(GRAPH_LIBNAME)$(LIB_SUFFIX)
 RTREEDEP    = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(RTREE_LIBNAME)$(LIB_SUFFIX)
 VEDITDEP    = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(VEDIT_LIBNAME)$(LIB_SUFFIX)
+NETADEP     = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(NETA_LIBNAME)$(LIB_SUFFIX)
 VECTDEP     = $(VECTRDEP) $(DIG2DEP) $(GRAPHDEP) $(RTREEDEP) $(LINKMDEP) $(DBMIDEP)
 
 # Interpolation

Copied: grass/branches/develbranch_6/include/neta.h (from rev 41777, grass/trunk/include/neta.h)
===================================================================
--- grass/branches/develbranch_6/include/neta.h	                        (rev 0)
+++ grass/branches/develbranch_6/include/neta.h	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,114 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala (Google Summer of Code 2009)
+ *
+ * PURPOSE:    NETwork Analysis Library
+ *
+ * COPYRIGHT:  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+ *
+ *             This program is free software under the GNU General
+ *             Public License (>=v2).  Read the file COPYING that
+ *             comes with GRASS for details.
+ *
+ ****************************************************************/
+
+#ifndef _NETA_H_
+#define _NETA_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*bridge.c */
+int NetA_compute_bridges(dglGraph_s * graph, struct ilist *bridge_list);
+int NetA_articulation_points(dglGraph_s * graph,
+			     struct ilist *articulation_list);
+
+/*components.c */
+int NetA_weakly_connected_components(dglGraph_s * graph, int *component);
+int NetA_strongly_connected_components(dglGraph_s * graph, int *component);
+
+/*spanningtree.c */
+int NetA_spanning_tree(dglGraph_s * graph, struct ilist *tree_list);
+
+/*allpairs.c */
+int NetA_allpairs(dglGraph_s * graph, dglInt32_t ** dist);
+
+/*neta_flow.c */
+int NetA_flow(dglGraph_s * graph, struct ilist *source_list,
+	      struct ilist *sink_list, int *flow);
+int NetA_min_cut(dglGraph_s * graph, struct ilist *source_list,
+		 struct ilist *sink_list, int *flow, struct ilist *cut);
+int NetA_split_vertices(dglGraph_s * in, dglGraph_s * out, int *node_costs);
+
+/*utils.c */
+void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
+			    struct line_cats *Cats);
+void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list);
+int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
+			int *node_costs);
+void NetA_varray_to_nodes(struct Map_info *map, struct varray * varray,
+			  struct ilist *nodes, int *nodes_to_features);
+int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
+			   char *where, char *cat, struct varray ** varray);
+/*centrality.c */
+void NetA_degree_centrality(dglGraph_s * graph, double *degree);
+int NetA_eigenvector_centrality(dglGraph_s * graph, int iterations,
+				double error, double *eigenvector);
+int NetA_betweenness_closeness(dglGraph_s * graph, double *betweenness,
+			       double *closeness);
+
+/*path.c */
+int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from, int *dst,
+			      dglInt32_t ** prev);
+int NetA_find_path(dglGraph_s * graph, int from, int to, int *edges,
+		   struct ilist *list);
+
+/*timetables.c */
+
+/*Structure containing all information about a timetable.
+ * Everything in indexed from 0.
+ */
+typedef struct
+{
+    int routes;			/*Number of different routes. Two routes are different even if they differ only in time. */
+    int *route_length;		/*Length of each route, i.e., number of stops */
+    int **route_stops;		/*list of stops on each route in order (time increases) */
+    int **route_times;		/*stop arrival times on overy route. Stops are given in the same order as above */
+    int stops;			/*number of stops */
+    int *stop_length;		/*Number of routes stopping at each stop */
+    int **stop_routes;		/*List of routes for each stop. Routes are in increasing order */
+    int **stop_times;		/*arrival times of routes for each stop. Routes are given in the same order as above */
+    int *walk_length;		/*number of stops with "walking connection" for each stop */
+    int **walk_stops;		/*list of stops within walking distance for each stop */
+    int **walk_times;		/*walking times between stops as given above */
+} neta_timetable;
+
+typedef struct
+{
+    int **dst;
+    int **prev_stop;
+    int **prev_route;
+    int **prev_conn;
+    int rows, routes;
+} neta_timetable_result;
+int NetA_init_timetable_from_db(struct Map_info *In, int route_layer,
+				int walk_layer, char *route_id, char *times,
+				char *to_stop, char *walk_length,
+				neta_timetable * timetable, int **route_ids,
+				int **stop_ids);
+int NetA_timetable_shortest_path(neta_timetable * timetable, int from_stop,
+				 int to_stop, int start_time, int min_change,
+				 int max_changes, int walking_change,
+				 neta_timetable_result * result);
+int NetA_timetable_get_route_time(neta_timetable * timetable, int stop,
+				  int route);
+void NetA_timetable_result_release(neta_timetable_result * result);
+#endif

Modified: grass/branches/develbranch_6/lib/grasslib.dox
===================================================================
--- grass/branches/develbranch_6/lib/grasslib.dox	2010-04-10 17:25:50 UTC (rev 41782)
+++ grass/branches/develbranch_6/lib/grasslib.dox	2010-04-10 18:00:54 UTC (rev 41783)
@@ -100,6 +100,7 @@
  - vask:	Cursor management library - \ref vask
  - %vector:	\ref Vector_Library (GRASS Vector and Direct Graph Library)
   - vedit:      \ref Vedit_Library - %vector editing
+  - neta:       \ref netalib
  - nviz:        \ref nvizlib (used by wxGUI Nviz extension and CLI-based Nviz module)
 <!--<li>image3:	extra imagery library (mainly still unused) - \ref image3lib-->
 <!--<li>D:		display library - \ref d_displaylib-->

Modified: grass/branches/develbranch_6/lib/vector/Makefile
===================================================================
--- grass/branches/develbranch_6/lib/vector/Makefile	2010-04-10 17:25:50 UTC (rev 41782)
+++ grass/branches/develbranch_6/lib/vector/Makefile	2010-04-10 18:00:54 UTC (rev 41783)
@@ -5,7 +5,8 @@
 	diglib \
 	Vlib \
 	transform \
-	vedit
+	vedit \
+	neta
 
 #doxygen:
 DOXNAME=vector


Property changes on: grass/branches/develbranch_6/lib/vector/neta
___________________________________________________________________
Added: svn:ignore
   + OBJ.*


Deleted: grass/branches/develbranch_6/lib/vector/neta/Makefile
===================================================================
--- grass/trunk/lib/vector/neta/Makefile	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/Makefile	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,13 +0,0 @@
-MODULE_TOPDIR = ../../..
-
-LIB = NETA
-
-LIBES = $(VECTLIB) $(DBMILIB) $(GISLIB) $(GRAPHLIB)
-DEPENDENCIES= $(VECTDEP) $(DBMIDEP) $(GISDEP) 
-EXTRA_INC = $(VECT_INC)
-EXTRA_CFLAGS = $(VECT_CFLAGS)
-
-include $(MODULE_TOPDIR)/include/Make/Lib.make
-include $(MODULE_TOPDIR)/include/Make/Doxygen.make
-
-default: lib

Copied: grass/branches/develbranch_6/lib/vector/neta/Makefile (from rev 41777, grass/trunk/lib/vector/neta/Makefile)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/Makefile	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/Makefile	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,15 @@
+MODULE_TOPDIR = ../../..
+
+LIB_NAME = $(NETA_LIBNAME)
+
+EXTRA_LIBS = $(VECTLIB) $(DBMILIB) $(GISLIB) $(GRAPHLIB)
+DEPENDENCIES= $(VECTDEP) $(DBMIDEP) $(GISDEP) 
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Lib.make
+include $(MODULE_TOPDIR)/include/Make/Doxygen.make
+
+default: lib
+
+DOXNAME=neta
\ No newline at end of file

Deleted: grass/branches/develbranch_6/lib/vector/neta/allpairs.c
===================================================================
--- grass/trunk/lib/vector/neta/allpairs.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/allpairs.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,93 +0,0 @@
-/*!
-  \file vector/neta/allpairs.c
-  
-  \brief Network Analysis library - shortest path between all pairs
-  
-  Computes the length of the shortest path between all pairs of nodes
-  in the network.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/*!
-  \brief Stores the directed distance between every pair
-
-  \todo Use only O(W*W) memory where W is the number of nodes present in the graph
-
-  Upon the completion, dist stores the directed distance between every pair (i,j)
-  or -1 if the nodes are unreachable. It must be an array of dimension [nodes+1]*[nodes+1]
-  
-  \param graph input graph
-  \param[out] dist list of directed distance
-  
-  \return -1 on error
-  \return 0 on success
- */
-int NetA_allpairs(dglGraph_s * graph, dglInt32_t ** dist)
-{
-    int nnodes, i, j, k, indices;
-    dglEdgesetTraverser_s et;
-    dglNodeTraverser_s nt;
-    dglInt32_t *node;
-    nnodes = dglGet_NodeCount(graph);
-    dglInt32_t *node_indices;
-    node_indices = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
-    if (!node_indices) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-    G_message(_("Computing all pairs shortest paths..."));
-    G_percent_reset();
-    for (i = 0; i <= nnodes; i++)
-	for (j = 0; j <= nnodes; j++)
-	    dist[i][j] = -1;
-    dglNode_T_Initialize(&nt, graph);
-    indices = 0;
-    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
-	dglInt32_t node_id = dglNodeGet_Id(graph, node);
-	node_indices[indices++] = node_id;
-	dglInt32_t *edge;
-	dglEdgeset_T_Initialize(&et, graph, dglNodeGet_OutEdgeset(graph, node));
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et))
-	    if (dglEdgeGet_Id(graph, edge) < 0)	/*ignore backward edges */
-		dist[node_id][dglNodeGet_Id
-			      (graph, dglEdgeGet_Tail(graph, edge))] =
-		    dglEdgeGet_Cost(graph, edge);
-	dglEdgeset_T_Release(&et);
-    }
-    dglNode_T_Release(&nt);
-    for (k = 0; k < indices; k++) {
-	dglInt32_t k_index = node_indices[k];
-	G_percent(k + 1, indices, 1);
-	for (i = 0; i < indices; i++) {
-	    dglInt32_t i_index = node_indices[i];
-	    if (dist[i_index][k_index] == -1)
-		continue;	/*no reason to proceed along infinite path */
-	    for (j = 0; j < indices; j++) {
-		dglInt32_t j_index = node_indices[j];
-		if (dist[k_index][j_index] != -1 &&
-		    (dist[i_index][k_index] + dist[k_index][j_index] <
-		     dist[i_index][j_index] || dist[i_index][j_index] == -1)) {
-		    dist[i_index][j_index] =
-			dist[i_index][k_index] + dist[k_index][j_index];
-		}
-	    }
-	}
-    }
-
-    G_free(node_indices);
-    return 0;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/allpairs.c (from rev 41777, grass/trunk/lib/vector/neta/allpairs.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/allpairs.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/allpairs.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,102 @@
+/*!
+   \file vector/neta/allpairs.c
+
+   \brief Network Analysis library - shortest path between all pairs
+
+   Computes the length of the shortest path between all pairs of nodes
+   in the network.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*!
+   \brief Stores the directed distance between every pair
+
+   \todo Use only O(W*W) memory where W is the number of nodes present in the graph
+
+   Upon the completion, dist stores the directed distance between every pair (i,j)
+   or -1 if the nodes are unreachable. It must be an array of dimension [nodes+1]*[nodes+1]
+
+   \param graph input graph
+   \param[out] dist list of directed distance
+
+   \return -1 on error
+   \return 0 on success
+ */
+int NetA_allpairs(dglGraph_s * graph, dglInt32_t ** dist)
+{
+    int nnodes, i, j, k, indices;
+    dglEdgesetTraverser_s et;
+    dglNodeTraverser_s nt;
+    dglInt32_t *node;
+
+    nnodes = dglGet_NodeCount(graph);
+    dglInt32_t *node_indices;
+
+    node_indices = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
+    if (!node_indices) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+    G_message(_("Computing all pairs shortest paths..."));
+    G_percent_reset();
+    for (i = 0; i <= nnodes; i++)
+	for (j = 0; j <= nnodes; j++)
+	    dist[i][j] = -1;
+    dglNode_T_Initialize(&nt, graph);
+    indices = 0;
+    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+	dglInt32_t node_id = dglNodeGet_Id(graph, node);
+
+	node_indices[indices++] = node_id;
+	dglInt32_t *edge;
+
+	dglEdgeset_T_Initialize(&et, graph,
+				dglNodeGet_OutEdgeset(graph, node));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et))
+	    if (dglEdgeGet_Id(graph, edge) < 0)	/*ignore backward edges */
+		dist[node_id][dglNodeGet_Id
+			      (graph, dglEdgeGet_Tail(graph, edge))] =
+		    dglEdgeGet_Cost(graph, edge);
+	dglEdgeset_T_Release(&et);
+    }
+    dglNode_T_Release(&nt);
+    for (k = 0; k < indices; k++) {
+	dglInt32_t k_index = node_indices[k];
+
+	G_percent(k + 1, indices, 1);
+	for (i = 0; i < indices; i++) {
+	    dglInt32_t i_index = node_indices[i];
+
+	    if (dist[i_index][k_index] == -1)
+		continue;	/*no reason to proceed along infinite path */
+	    for (j = 0; j < indices; j++) {
+		dglInt32_t j_index = node_indices[j];
+
+		if (dist[k_index][j_index] != -1 &&
+		    (dist[i_index][k_index] + dist[k_index][j_index] <
+		     dist[i_index][j_index] ||
+		     dist[i_index][j_index] == -1)) {
+		    dist[i_index][j_index] =
+			dist[i_index][k_index] + dist[k_index][j_index];
+		}
+	    }
+	}
+    }
+
+    G_free(node_indices);
+    return 0;
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/articulation_point.c
===================================================================
--- grass/trunk/lib/vector/neta/articulation_point.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/articulation_point.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,143 +0,0 @@
-/*!
-  \file vector/neta/articulation_point.c
-  
-  \brief Network Analysis library - connected components
-
-  Computes strongly and weakly connected components.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/*!
-  \brief Get number of articulation points in the graph
-
-  \param graph input graph
-  \param[out] articulation_list list of articulation points
-  
-  \return number of points
-  \return -1 on error
- */
-int NetA_articulation_points(dglGraph_s * graph,
-			     struct ilist *articulation_list)
-{
-    int nnodes;
-    int points = 0;
-
-    dglEdgesetTraverser_s *current;	/*edge to be processed when the node is visited */
-    int *tin, *min_tin;		/*time in, and smallest tin over all successors. 0 if not yet visited */
-    dglInt32_t **parent;	/*parents of the nodes */
-    dglInt32_t **stack;		/*stack of nodes */
-    dglInt32_t **current_edge;	/*current edge for each node */
-    int *mark;			/*marked articulation points */
-    dglNodeTraverser_s nt;
-    dglInt32_t *current_node;
-    int stack_size;
-    int i, time;
-    nnodes = dglGet_NodeCount(graph);
-    current =
-	(dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
-					   sizeof(dglEdgesetTraverser_s));
-    tin = (int *)G_calloc(nnodes + 1, sizeof(int));
-    min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
-    parent = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
-    stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
-    current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
-    mark = (int *)G_calloc(nnodes + 1, sizeof(int));
-    if (!tin || !min_tin || !parent || !stack || !current || !mark) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    for (i = 1; i <= nnodes; i++) {
-	dglEdgeset_T_Initialize(&current[i], graph,
-				dglNodeGet_OutEdgeset(graph,
-						      dglGetNode(graph, i)));
-	current_edge[i] = dglEdgeset_T_First(&current[i]);
-	tin[i] = mark[i] = 0;
-    }
-
-    dglNode_T_Initialize(&nt, graph);
-
-    time = 0;
-    for (current_node = dglNode_T_First(&nt); current_node;
-	 current_node = dglNode_T_Next(&nt)) {
-	dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
-	if (tin[current_id] == 0) {
-	    int children = 0;	/*number of subtrees rooted at the root/current_node */
-	    stack[0] = current_node;
-	    stack_size = 1;
-	    parent[current_id] = NULL;
-	    while (stack_size) {
-		dglInt32_t *node = stack[stack_size - 1];
-		dglInt32_t node_id = dglNodeGet_Id(graph, node);
-		if (tin[node_id] == 0)	/*vertex visited for the first time */
-		    min_tin[node_id] = tin[node_id] = ++time;
-		else {		/*return from the recursion */
-		    dglInt32_t to = dglNodeGet_Id(graph,
-						  dglEdgeGet_Tail(graph,
-								  current_edge
-								  [node_id]));
-		    if (min_tin[to] >= tin[node_id])	/*no path from the subtree above the current node */
-			mark[node_id] = 1;	/*so the current node must be an articulation point */
-
-		    if (min_tin[to] < min_tin[node_id])
-			min_tin[node_id] = min_tin[to];
-		    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
-		    dglInt32_t *to =
-			dglEdgeGet_Tail(graph, current_edge[node_id]);
-		    if (to == parent[node_id])
-			continue;	/*skip parrent */
-		    int to_id = dglNodeGet_Id(graph, to);
-		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
-			if (tin[to_id] < min_tin[node_id])
-			    min_tin[node_id] = tin[to_id];
-		    }
-		    else {	/*forward edge */
-			if (node_id == current_id)
-			    children++;	/*if root, increase number of children */
-			parent[to_id] = node;
-			stack[stack_size++] = to;
-			break;
-		    }
-		}
-		if (!current_edge[node_id])
-		    stack_size--;	/*current node completely processed */
-	    }
-	    if (children > 1)
-		mark[current_id] = 1;	/*if the root has more than 1 subtrees rooted at it, then it is an
-					 * articulation point */
-	}
-    }
-
-    for (i = 1; i <= nnodes; i++)
-	if (mark[i]) {
-	    points++;
-	    Vect_list_append(articulation_list, i);
-	}
-
-    dglNode_T_Release(&nt);
-    for (i = 1; i <= nnodes; i++)
-	dglEdgeset_T_Release(&current[i]);
-
-    G_free(current);
-    G_free(tin);
-    G_free(min_tin);
-    G_free(parent);
-    G_free(stack);
-    G_free(current_edge);
-    return points;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/articulation_point.c (from rev 41777, grass/trunk/lib/vector/neta/articulation_point.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/articulation_point.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/articulation_point.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,148 @@
+/*!
+   \file vector/neta/articulation_point.c
+
+   \brief Network Analysis library - connected components
+
+   Computes strongly and weakly connected components.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*!
+   \brief Get number of articulation points in the graph
+
+   \param graph input graph
+   \param[out] articulation_list list of articulation points
+
+   \return number of points
+   \return -1 on error
+ */
+int NetA_articulation_points(dglGraph_s * graph,
+			     struct ilist *articulation_list)
+{
+    int nnodes;
+    int points = 0;
+
+    dglEdgesetTraverser_s *current;	/*edge to be processed when the node is visited */
+    int *tin, *min_tin;		/*time in, and smallest tin over all successors. 0 if not yet visited */
+    dglInt32_t **parent;	/*parents of the nodes */
+    dglInt32_t **stack;		/*stack of nodes */
+    dglInt32_t **current_edge;	/*current edge for each node */
+    int *mark;			/*marked articulation points */
+    dglNodeTraverser_s nt;
+    dglInt32_t *current_node;
+    int stack_size;
+    int i, time;
+
+    nnodes = dglGet_NodeCount(graph);
+    current =
+	(dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
+					   sizeof(dglEdgesetTraverser_s));
+    tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+    min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+    parent = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    mark = (int *)G_calloc(nnodes + 1, sizeof(int));
+    if (!tin || !min_tin || !parent || !stack || !current || !mark) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    for (i = 1; i <= nnodes; i++) {
+	dglEdgeset_T_Initialize(&current[i], graph,
+				dglNodeGet_OutEdgeset(graph,
+						      dglGetNode(graph, i)));
+	current_edge[i] = dglEdgeset_T_First(&current[i]);
+	tin[i] = mark[i] = 0;
+    }
+
+    dglNode_T_Initialize(&nt, graph);
+
+    time = 0;
+    for (current_node = dglNode_T_First(&nt); current_node;
+	 current_node = dglNode_T_Next(&nt)) {
+	dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
+
+	if (tin[current_id] == 0) {
+	    int children = 0;	/*number of subtrees rooted at the root/current_node */
+
+	    stack[0] = current_node;
+	    stack_size = 1;
+	    parent[current_id] = NULL;
+	    while (stack_size) {
+		dglInt32_t *node = stack[stack_size - 1];
+		dglInt32_t node_id = dglNodeGet_Id(graph, node);
+
+		if (tin[node_id] == 0)	/*vertex visited for the first time */
+		    min_tin[node_id] = tin[node_id] = ++time;
+		else {		/*return from the recursion */
+		    dglInt32_t to = dglNodeGet_Id(graph,
+						  dglEdgeGet_Tail(graph,
+								  current_edge
+								  [node_id]));
+		    if (min_tin[to] >= tin[node_id])	/*no path from the subtree above the current node */
+			mark[node_id] = 1;	/*so the current node must be an articulation point */
+
+		    if (min_tin[to] < min_tin[node_id])
+			min_tin[node_id] = min_tin[to];
+		    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
+		    dglInt32_t *to =
+			dglEdgeGet_Tail(graph, current_edge[node_id]);
+		    if (to == parent[node_id])
+			continue;	/*skip parrent */
+		    int to_id = dglNodeGet_Id(graph, to);
+
+		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
+			if (tin[to_id] < min_tin[node_id])
+			    min_tin[node_id] = tin[to_id];
+		    }
+		    else {	/*forward edge */
+			if (node_id == current_id)
+			    children++;	/*if root, increase number of children */
+			parent[to_id] = node;
+			stack[stack_size++] = to;
+			break;
+		    }
+		}
+		if (!current_edge[node_id])
+		    stack_size--;	/*current node completely processed */
+	    }
+	    if (children > 1)
+		mark[current_id] = 1;	/*if the root has more than 1 subtrees rooted at it, then it is an
+					 * articulation point */
+	}
+    }
+
+    for (i = 1; i <= nnodes; i++)
+	if (mark[i]) {
+	    points++;
+	    Vect_list_append(articulation_list, i);
+	}
+
+    dglNode_T_Release(&nt);
+    for (i = 1; i <= nnodes; i++)
+	dglEdgeset_T_Release(&current[i]);
+
+    G_free(current);
+    G_free(tin);
+    G_free(min_tin);
+    G_free(parent);
+    G_free(stack);
+    G_free(current_edge);
+    return points;
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/bridge.c
===================================================================
--- grass/trunk/lib/vector/neta/bridge.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/bridge.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,133 +0,0 @@
-/*!
-  \file vector/neta/bridges.c
-  
-  \brief Network Analysis library - bridges
-
-  Computes number of bridges in the graph.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/*!
-  \brief Get number of bridges in the graph.
-  
-  Bridge is an array containing the indices of the bridges.
-
-  \param graph input graph
-  \param[out] bridges_list list of bridges
-
-  \return number of bridges
-  \return -1 on error
-*/
-int NetA_compute_bridges(dglGraph_s * graph, struct ilist *bridge_list)
-{
-    int nnodes;
-    int bridges = 0;
-
-    dglEdgesetTraverser_s *current;	/*edge to be processed when the node is visited */
-    int *tin, *min_tin;		/*time in, and smallest tin over all successors. 0 if not yet visited */
-    dglInt32_t *parent;		/*edge from parent to the node */
-    dglInt32_t **stack;		/*stack of nodes */
-    dglInt32_t **current_edge;	/*current edge for each node */
-    dglNodeTraverser_s nt;
-    dglInt32_t *current_node;
-    int stack_size;
-    int i, time;
-    nnodes = dglGet_NodeCount(graph);
-    current =
-	(dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
-					   sizeof(dglEdgesetTraverser_s));
-    tin = (int *)G_calloc(nnodes + 1, sizeof(int));
-    min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
-    parent = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
-    current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
-    if (!tin || !min_tin || !parent || !stack || !current) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    for (i = 1; i <= nnodes; i++) {
-	dglEdgeset_T_Initialize(&current[i], graph,
-				dglNodeGet_OutEdgeset(graph,
-						      dglGetNode(graph, i)));
-	current_edge[i] = dglEdgeset_T_First(&current[i]);
-	tin[i] = 0;
-    }
-
-    dglNode_T_Initialize(&nt, graph);
-
-    time = 0;
-    for (current_node = dglNode_T_First(&nt); current_node;
-	 current_node = dglNode_T_Next(&nt)) {
-	dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
-	if (tin[current_id] == 0) {
-	    stack[0] = current_node;
-	    stack_size = 1;
-	    parent[current_id] = 0;
-	    while (stack_size) {
-		dglInt32_t *node = stack[stack_size - 1];
-		dglInt32_t node_id = dglNodeGet_Id(graph, node);
-		if (tin[node_id] == 0)	/*vertex visited for the first time */
-		    min_tin[node_id] = tin[node_id] = ++time;
-		else {		/*return from the recursion */
-		    dglInt32_t to = dglNodeGet_Id(graph,
-						  dglEdgeGet_Tail(graph,
-								  current_edge
-								  [node_id]));
-		    if (min_tin[to] > tin[node_id]) {	/*no path from the subtree above the current node */
-			Vect_list_append(bridge_list, dglEdgeGet_Id(graph, current_edge[node_id]));	/*so it must be a bridge */
-			bridges++;
-		    }
-		    if (min_tin[to] < min_tin[node_id])
-			min_tin[node_id] = min_tin[to];
-		    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
-		    dglInt32_t *to =
-			dglEdgeGet_Tail(graph, current_edge[node_id]);
-		    dglInt32_t edge_id =
-			dglEdgeGet_Id(graph, current_edge[node_id]);
-		    if (abs(edge_id) == parent[node_id])
-			continue;	/*skip edge we used to travel to this node */
-		    int to_id = dglNodeGet_Id(graph, to);
-		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
-			if (tin[to_id] < min_tin[node_id])
-			    min_tin[node_id] = tin[to_id];
-		    }
-		    else {	/*forward edge */
-			parent[to_id] = abs(edge_id);
-			stack[stack_size++] = to;
-			break;
-		    }
-		}
-		if (!current_edge[node_id])
-		    stack_size--;	/*current node completely processed */
-	    }
-	}
-    }
-
-    dglNode_T_Release(&nt);
-    for (i = 1; i <= nnodes; i++)
-	dglEdgeset_T_Release(&current[i]);
-
-    G_free(current);
-    G_free(tin);
-    G_free(min_tin);
-    G_free(parent);
-    G_free(stack);
-    G_free(current_edge);
-    return bridges;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/bridge.c (from rev 41777, grass/trunk/lib/vector/neta/bridge.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/bridge.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/bridge.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,137 @@
+/*!
+   \file vector/neta/bridges.c
+
+   \brief Network Analysis library - bridges
+
+   Computes number of bridges in the graph.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*!
+   \brief Get number of bridges in the graph.
+
+   Bridge is an array containing the indices of the bridges.
+
+   \param graph input graph
+   \param[out] bridges_list list of bridges
+
+   \return number of bridges
+   \return -1 on error
+ */
+int NetA_compute_bridges(dglGraph_s * graph, struct ilist *bridge_list)
+{
+    int nnodes;
+    int bridges = 0;
+
+    dglEdgesetTraverser_s *current;	/*edge to be processed when the node is visited */
+    int *tin, *min_tin;		/*time in, and smallest tin over all successors. 0 if not yet visited */
+    dglInt32_t *parent;		/*edge from parent to the node */
+    dglInt32_t **stack;		/*stack of nodes */
+    dglInt32_t **current_edge;	/*current edge for each node */
+    dglNodeTraverser_s nt;
+    dglInt32_t *current_node;
+    int stack_size;
+    int i, time;
+
+    nnodes = dglGet_NodeCount(graph);
+    current =
+	(dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
+					   sizeof(dglEdgesetTraverser_s));
+    tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+    min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
+    parent = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    if (!tin || !min_tin || !parent || !stack || !current) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    for (i = 1; i <= nnodes; i++) {
+	dglEdgeset_T_Initialize(&current[i], graph,
+				dglNodeGet_OutEdgeset(graph,
+						      dglGetNode(graph, i)));
+	current_edge[i] = dglEdgeset_T_First(&current[i]);
+	tin[i] = 0;
+    }
+
+    dglNode_T_Initialize(&nt, graph);
+
+    time = 0;
+    for (current_node = dglNode_T_First(&nt); current_node;
+	 current_node = dglNode_T_Next(&nt)) {
+	dglInt32_t current_id = dglNodeGet_Id(graph, current_node);
+
+	if (tin[current_id] == 0) {
+	    stack[0] = current_node;
+	    stack_size = 1;
+	    parent[current_id] = 0;
+	    while (stack_size) {
+		dglInt32_t *node = stack[stack_size - 1];
+		dglInt32_t node_id = dglNodeGet_Id(graph, node);
+
+		if (tin[node_id] == 0)	/*vertex visited for the first time */
+		    min_tin[node_id] = tin[node_id] = ++time;
+		else {		/*return from the recursion */
+		    dglInt32_t to = dglNodeGet_Id(graph,
+						  dglEdgeGet_Tail(graph,
+								  current_edge
+								  [node_id]));
+		    if (min_tin[to] > tin[node_id]) {	/*no path from the subtree above the current node */
+			Vect_list_append(bridge_list, dglEdgeGet_Id(graph, current_edge[node_id]));	/*so it must be a bridge */
+			bridges++;
+		    }
+		    if (min_tin[to] < min_tin[node_id])
+			min_tin[node_id] = min_tin[to];
+		    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
+		    dglInt32_t *to =
+			dglEdgeGet_Tail(graph, current_edge[node_id]);
+		    dglInt32_t edge_id =
+			dglEdgeGet_Id(graph, current_edge[node_id]);
+		    if (abs(edge_id) == parent[node_id])
+			continue;	/*skip edge we used to travel to this node */
+		    int to_id = dglNodeGet_Id(graph, to);
+
+		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
+			if (tin[to_id] < min_tin[node_id])
+			    min_tin[node_id] = tin[to_id];
+		    }
+		    else {	/*forward edge */
+			parent[to_id] = abs(edge_id);
+			stack[stack_size++] = to;
+			break;
+		    }
+		}
+		if (!current_edge[node_id])
+		    stack_size--;	/*current node completely processed */
+	    }
+	}
+    }
+
+    dglNode_T_Release(&nt);
+    for (i = 1; i <= nnodes; i++)
+	dglEdgeset_T_Release(&current[i]);
+
+    G_free(current);
+    G_free(tin);
+    G_free(min_tin);
+    G_free(parent);
+    G_free(stack);
+    G_free(current_edge);
+    return bridges;
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/centrality.c
===================================================================
--- grass/trunk/lib/vector/neta/centrality.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/centrality.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,237 +0,0 @@
-/*!
-  \file vector/neta/centality.c
-  
-  \brief Network Analysis library - centrality
-
-  Centrality measures
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-#include <grass/neta.h>
-
-/*!
-  \brief Computes degree centrality measure.
-
-  Array degree has to be properly initialised to nnodes+1 elements
-
-  \param graph input graph
-  \param[out] array of degrees
-*/
-void NetA_degree_centrality(dglGraph_s * graph, double *degree)
-{
-    int i;
-    double nnodes = dglGet_NodeCount(graph);
-    for (i = 1; i <= nnodes; i++)
-	degree[i] =
-	    dglNodeGet_OutDegree(graph,
-				 dglGetNode(graph, (dglInt32_t) i)) / nnodes;
-}
-
-/*!
-  \brief Computes eigenvector centrality using edge costs as weights.
-
-  \param graph input graph
-  \param iterations number of iterations
-  \param error ?
-  \param[out] eigenvector eigen vector value
-  
-  \return 0 on success
-  \return -1 on failure
-*/
-int NetA_eigenvector_centrality(dglGraph_s * graph, int iterations,
-				double error, double *eigenvector)
-{
-    int i, iter, nnodes;
-    double *tmp;
-    nnodes = dglGet_NodeCount(graph);
-    tmp = (double *)G_calloc(nnodes + 1, sizeof(double));
-    if (!tmp) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    error *= error;
-    for (i = 1; i <= nnodes; i++)
-	eigenvector[i] = 1;
-    for (iter = 0; iter < iterations; iter++) {
-	for (i = 1; i <= nnodes; i++)
-	    tmp[i] = 0;
-	dglInt32_t *node;
-	dglNodeTraverser_s nt;
-	dglEdgesetTraverser_s et;
-	dglNode_T_Initialize(&nt, graph);
-	for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
-	    dglInt32_t node_id = dglNodeGet_Id(graph, node);
-	    double cur_value = eigenvector[node_id];
-	    dglInt32_t *edge;
-	    dglEdgeset_T_Initialize(&et, graph,
-				    dglNodeGet_OutEdgeset(graph, node));
-	    for (edge = dglEdgeset_T_First(&et); edge;
-		 edge = dglEdgeset_T_Next(&et))
-		tmp[dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge))] +=
-		    cur_value * dglEdgeGet_Cost(graph, edge);
-
-	    dglEdgeset_T_Release(&et);
-	}
-	dglNode_T_Release(&nt);
-	double cum_error = 0, max_value = tmp[1];
-	for (i = 2; i <= nnodes; i++)
-	    if (tmp[i] > max_value)
-		max_value = tmp[i];
-	for (i = 1; i <= nnodes; i++) {
-	    tmp[i] /= max_value;
-	    cum_error += (tmp[i] - eigenvector[i]) * (tmp[i] - eigenvector[i]);
-	    eigenvector[i] = tmp[i];
-	}
-	if (cum_error < error)
-	    break;
-
-    }
-
-    G_free(tmp);
-    return 0;
-}
-
-/*!
-  \brief Computes betweenness and closeness centrality measure using Brandes algorithm. 
-
-  Edge costs must be nonnegative. If some edge costs are negative then
-  the behaviour of this method is undefined.
-  
-  \param graph input graph
-  \param[out] betweenness betweeness values
-  \param[out] closeness cloneness values
-  
-  \return 0 on success
-  \return -1 on failure
-*/  
-int NetA_betweenness_closeness(dglGraph_s * graph, double *betweenness,
-			       double *closeness)
-{
-    int i, j, nnodes, stack_size, count;
-    dglInt32_t *dst, *node, *stack, *cnt, *delta;
-    dglNodeTraverser_s nt;
-    dglEdgesetTraverser_s et;
-    dglHeap_s heap;
-    struct ilist **prev;
-
-    nnodes = dglGet_NodeCount(graph);
-
-    dst = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    prev = (struct ilist **)G_calloc(nnodes + 1, sizeof(struct ilist *));
-    stack = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
-    cnt = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    delta = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-
-    if (!dst || !prev || !stack || !cnt || !delta) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-
-    for (i = 1; i <= nnodes; i++) {
-	prev[i] = Vect_new_list();
-	if (closeness)
-	    closeness[i] = 0;
-	if (betweenness)
-	    betweenness[i] = 0;
-    }
-
-    count = 0;
-    G_percent_reset();
-    dglNode_T_Initialize(&nt, graph);
-    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
-	G_percent(count++, nnodes, 1);
-	dglInt32_t s = dglNodeGet_Id(graph, node);
-	dglHeapData_u heap_data;
-	dglHeapNode_s heap_node;
-
-	stack_size = 0;
-	for (i = 1; i <= nnodes; i++)
-	    Vect_reset_list(prev[i]);
-	for (i = 1; i <= nnodes; i++) {
-	    cnt[i] = 0;
-	    dst[i] = -1;
-	}
-	dst[s] = 0;
-	cnt[s] = 1;
-	dglHeapInit(&heap);
-	heap_data.ul = s;
-	dglHeapInsertMin(&heap, 0, ' ', heap_data);
-	while (1) {
-	    dglInt32_t v, dist;
-	    if (!dglHeapExtractMin(&heap, &heap_node))
-		break;
-	    v = heap_node.value.ul;
-	    dist = heap_node.key;
-	    if (dst[v] < dist)
-		continue;
-	    stack[stack_size++] = v;
-
-	    dglInt32_t *edge;
-	    dglEdgeset_T_Initialize(&et, graph,
-				    dglNodeGet_OutEdgeset(graph,
-							  dglGetNode(graph,
-								     v)));
-	    for (edge = dglEdgeset_T_First(&et); edge;
-		 edge = dglEdgeset_T_Next(&et)) {
-		dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
-		dglInt32_t to_id = dglNodeGet_Id(graph, to);
-		dglInt32_t d = dglEdgeGet_Cost(graph, edge);
-		if (dst[to_id] == -1 || dst[to_id] > dist + d) {
-		    dst[to_id] = dist + d;
-		    Vect_reset_list(prev[to_id]);
-		    heap_data.ul = to_id;
-		    dglHeapInsertMin(&heap, dist + d, ' ', heap_data);
-		}
-		if (dst[to_id] == dist + d) {
-		    cnt[to_id] += cnt[v];
-		    Vect_list_append(prev[to_id], v);
-		}
-	    }
-
-	    dglEdgeset_T_Release(&et);
-	}
-	dglHeapFree(&heap, NULL);
-	for (i = 1; i <= nnodes; i++)
-	    delta[i] = 0;
-	for (i = stack_size - 1; i >= 0; i--) {
-	    dglInt32_t w = stack[i];
-	    if (closeness)
-		closeness[s] += dst[w];
-
-	    for (j = 0; j < prev[w]->n_values; j++) {
-		dglInt32_t v = prev[w]->value[j];
-		delta[v] += (cnt[v] / (double)cnt[w]) * (1.0 + delta[w]);
-	    }
-	    if (w != s && betweenness)
-		betweenness[w] += delta[w];
-
-	}
-	if (closeness)
-	    closeness[s] /= (double)stack_size;
-    }
-    dglNode_T_Release(&nt);
-
-    for (i = 1; i <= nnodes; i++)
-	Vect_destroy_list(prev[i]);
-    G_free(delta);
-    G_free(cnt);
-    G_free(stack);
-    G_free(prev);
-    G_free(dst);
-
-    return 0;
-};

Copied: grass/branches/develbranch_6/lib/vector/neta/centrality.c (from rev 41777, grass/trunk/lib/vector/neta/centrality.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/centrality.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/centrality.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,248 @@
+/*!
+   \file vector/neta/centality.c
+
+   \brief Network Analysis library - centrality
+
+   Centrality measures
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+#include <grass/neta.h>
+
+/*!
+   \brief Computes degree centrality measure.
+
+   Array degree has to be properly initialised to nnodes+1 elements
+
+   \param graph input graph
+   \param[out] array of degrees
+ */
+void NetA_degree_centrality(dglGraph_s * graph, double *degree)
+{
+    int i;
+    double nnodes = dglGet_NodeCount(graph);
+
+    for (i = 1; i <= nnodes; i++)
+	degree[i] =
+	    dglNodeGet_OutDegree(graph,
+				 dglGetNode(graph, (dglInt32_t) i)) / nnodes;
+}
+
+/*!
+   \brief Computes eigenvector centrality using edge costs as weights.
+
+   \param graph input graph
+   \param iterations number of iterations
+   \param error ?
+   \param[out] eigenvector eigen vector value
+
+   \return 0 on success
+   \return -1 on failure
+ */
+int NetA_eigenvector_centrality(dglGraph_s * graph, int iterations,
+				double error, double *eigenvector)
+{
+    int i, iter, nnodes;
+    double *tmp;
+
+    nnodes = dglGet_NodeCount(graph);
+    tmp = (double *)G_calloc(nnodes + 1, sizeof(double));
+    if (!tmp) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    error *= error;
+    for (i = 1; i <= nnodes; i++)
+	eigenvector[i] = 1;
+    for (iter = 0; iter < iterations; iter++) {
+	for (i = 1; i <= nnodes; i++)
+	    tmp[i] = 0;
+	dglInt32_t *node;
+	dglNodeTraverser_s nt;
+	dglEdgesetTraverser_s et;
+
+	dglNode_T_Initialize(&nt, graph);
+	for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+	    dglInt32_t node_id = dglNodeGet_Id(graph, node);
+	    double cur_value = eigenvector[node_id];
+	    dglInt32_t *edge;
+
+	    dglEdgeset_T_Initialize(&et, graph,
+				    dglNodeGet_OutEdgeset(graph, node));
+	    for (edge = dglEdgeset_T_First(&et); edge;
+		 edge = dglEdgeset_T_Next(&et))
+		tmp[dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge))] +=
+		    cur_value * dglEdgeGet_Cost(graph, edge);
+
+	    dglEdgeset_T_Release(&et);
+	}
+	dglNode_T_Release(&nt);
+	double cum_error = 0, max_value = tmp[1];
+
+	for (i = 2; i <= nnodes; i++)
+	    if (tmp[i] > max_value)
+		max_value = tmp[i];
+	for (i = 1; i <= nnodes; i++) {
+	    tmp[i] /= max_value;
+	    cum_error +=
+		(tmp[i] - eigenvector[i]) * (tmp[i] - eigenvector[i]);
+	    eigenvector[i] = tmp[i];
+	}
+	if (cum_error < error)
+	    break;
+
+    }
+
+    G_free(tmp);
+    return 0;
+}
+
+/*!
+   \brief Computes betweenness and closeness centrality measure using Brandes algorithm. 
+
+   Edge costs must be nonnegative. If some edge costs are negative then
+   the behaviour of this method is undefined.
+
+   \param graph input graph
+   \param[out] betweenness betweeness values
+   \param[out] closeness cloneness values
+
+   \return 0 on success
+   \return -1 on failure
+ */
+int NetA_betweenness_closeness(dglGraph_s * graph, double *betweenness,
+			       double *closeness)
+{
+    int i, j, nnodes, stack_size, count;
+    dglInt32_t *dst, *node, *stack, *cnt, *delta;
+    dglNodeTraverser_s nt;
+    dglEdgesetTraverser_s et;
+    dglHeap_s heap;
+    struct ilist **prev;
+
+    nnodes = dglGet_NodeCount(graph);
+
+    dst = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    prev = (struct ilist **)G_calloc(nnodes + 1, sizeof(struct ilist *));
+    stack = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
+    cnt = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    delta = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+
+    if (!dst || !prev || !stack || !cnt || !delta) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+
+    for (i = 1; i <= nnodes; i++) {
+	prev[i] = Vect_new_list();
+	if (closeness)
+	    closeness[i] = 0;
+	if (betweenness)
+	    betweenness[i] = 0;
+    }
+
+    count = 0;
+    G_percent_reset();
+    dglNode_T_Initialize(&nt, graph);
+    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+	G_percent(count++, nnodes, 1);
+	dglInt32_t s = dglNodeGet_Id(graph, node);
+	dglHeapData_u heap_data;
+	dglHeapNode_s heap_node;
+
+	stack_size = 0;
+	for (i = 1; i <= nnodes; i++)
+	    Vect_reset_list(prev[i]);
+	for (i = 1; i <= nnodes; i++) {
+	    cnt[i] = 0;
+	    dst[i] = -1;
+	}
+	dst[s] = 0;
+	cnt[s] = 1;
+	dglHeapInit(&heap);
+	heap_data.ul = s;
+	dglHeapInsertMin(&heap, 0, ' ', heap_data);
+	while (1) {
+	    dglInt32_t v, dist;
+
+	    if (!dglHeapExtractMin(&heap, &heap_node))
+		break;
+	    v = heap_node.value.ul;
+	    dist = heap_node.key;
+	    if (dst[v] < dist)
+		continue;
+	    stack[stack_size++] = v;
+
+	    dglInt32_t *edge;
+
+	    dglEdgeset_T_Initialize(&et, graph,
+				    dglNodeGet_OutEdgeset(graph,
+							  dglGetNode(graph,
+								     v)));
+	    for (edge = dglEdgeset_T_First(&et); edge;
+		 edge = dglEdgeset_T_Next(&et)) {
+		dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
+		dglInt32_t to_id = dglNodeGet_Id(graph, to);
+		dglInt32_t d = dglEdgeGet_Cost(graph, edge);
+
+		if (dst[to_id] == -1 || dst[to_id] > dist + d) {
+		    dst[to_id] = dist + d;
+		    Vect_reset_list(prev[to_id]);
+		    heap_data.ul = to_id;
+		    dglHeapInsertMin(&heap, dist + d, ' ', heap_data);
+		}
+		if (dst[to_id] == dist + d) {
+		    cnt[to_id] += cnt[v];
+		    Vect_list_append(prev[to_id], v);
+		}
+	    }
+
+	    dglEdgeset_T_Release(&et);
+	}
+	dglHeapFree(&heap, NULL);
+	for (i = 1; i <= nnodes; i++)
+	    delta[i] = 0;
+	for (i = stack_size - 1; i >= 0; i--) {
+	    dglInt32_t w = stack[i];
+
+	    if (closeness)
+		closeness[s] += dst[w];
+
+	    for (j = 0; j < prev[w]->n_values; j++) {
+		dglInt32_t v = prev[w]->value[j];
+
+		delta[v] += (cnt[v] / (double)cnt[w]) * (1.0 + delta[w]);
+	    }
+	    if (w != s && betweenness)
+		betweenness[w] += delta[w];
+
+	}
+	if (closeness)
+	    closeness[s] /= (double)stack_size;
+    }
+    dglNode_T_Release(&nt);
+
+    for (i = 1; i <= nnodes; i++)
+	Vect_destroy_list(prev[i]);
+    G_free(delta);
+    G_free(cnt);
+    G_free(stack);
+    G_free(prev);
+    G_free(dst);
+
+    return 0;
+};

Deleted: grass/branches/develbranch_6/lib/vector/neta/components.c
===================================================================
--- grass/trunk/lib/vector/neta/components.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/components.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,190 +0,0 @@
-/*!
-  \file vector/neta/components.c
-  
-  \brief Network Analysis library - graph componets
-
-  Computes strongly and weakly connected components.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-/*!
-  \brief Computes weekly connected components
-
-  \param graph input graph
-  \param[out] component list of components
-
-  \return number of components
-  \return -1 on failure
-*/
-int NetA_weakly_connected_components(dglGraph_s * graph, int *component)
-{
-    int nnodes;
-    dglInt32_t *stack;
-    int *visited;
-    int stack_size, components;
-    dglInt32_t *cur_node;
-    dglNodeTraverser_s nt;
-
-    components = 0;
-    nnodes = dglGet_NodeCount(graph);
-    stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    visited = (int *)G_calloc(nnodes + 1, sizeof(int));
-    if (!stack || !visited) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    dglNode_T_Initialize(&nt, graph);
-
-    for (cur_node = dglNode_T_First(&nt); cur_node;
-	 cur_node = dglNode_T_Next(&nt)) {
-	dglInt32_t node_id = dglNodeGet_Id(graph, cur_node);
-	if (!visited[node_id]) {
-	    visited[node_id] = 1;
-	    stack[0] = node_id;
-	    stack_size = 1;
-	    component[node_id] = ++components;
-	    while (stack_size) {
-		dglInt32_t *node, *edgeset, *edge;
-		dglEdgesetTraverser_s et;
-		node = dglGetNode(graph, stack[--stack_size]);
-		edgeset = dglNodeGet_OutEdgeset(graph, node);
-		dglEdgeset_T_Initialize(&et, graph, edgeset);
-		for (edge = dglEdgeset_T_First(&et); edge;
-		     edge = dglEdgeset_T_Next(&et)) {
-		    dglInt32_t to;
-		    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-		    if (!visited[to]) {
-			visited[to] = 1;
-			component[to] = components;
-			stack[stack_size++] = to;
-		    }
-		}
-		dglEdgeset_T_Release(&et);
-	    }
-	}
-    }
-    dglNode_T_Release(&nt);
-    G_free(visited);
-    return components;
-}
-
-/*!
-  \brief Computes strongly connected components
-
-  \param graph input graph
-  \param[out] component list of components
-
-  \return number of components
-  \return -1 on failure
-*/
-int NetA_strongly_connected_components(dglGraph_s * graph, int *component)
-{
-    int nnodes;
-    dglInt32_t *stack, *order;
-    int *visited, *processed;
-    int stack_size, order_size, components;
-    dglInt32_t *node;
-    dglNodeTraverser_s nt;
-
-    components = 0;
-    nnodes = dglGet_NodeCount(graph);
-    stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    order = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    visited = (int *)G_calloc(nnodes + 1, sizeof(int));
-    processed = (int *)G_calloc(nnodes + 1, sizeof(int));
-    if (!stack || !visited || !order || !processed) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    order_size = 0;
-    dglNode_T_Initialize(&nt, graph);
-
-    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
-	dglInt32_t node_id = dglNodeGet_Id(graph, node);
-	component[node_id] = 0;
-	if (!visited[node_id]) {
-	    visited[node_id] = 1;
-	    stack[0] = node_id;
-	    stack_size = 1;
-	    while (stack_size) {
-		dglInt32_t *node, *edgeset, *edge;
-		dglEdgesetTraverser_s et;
-		dglInt32_t cur_node_id = stack[stack_size - 1];
-		if (processed[cur_node_id]) {
-		    stack_size--;
-		    order[order_size++] = cur_node_id;
-		    continue;
-		}
-		processed[cur_node_id] = 1;
-		node = dglGetNode(graph, cur_node_id);
-		edgeset = dglNodeGet_OutEdgeset(graph, node);
-		dglEdgeset_T_Initialize(&et, graph, edgeset);
-		for (edge = dglEdgeset_T_First(&et); edge;
-		     edge = dglEdgeset_T_Next(&et)) {
-		    dglInt32_t to;
-		    if (dglEdgeGet_Id(graph, edge) < 0)
-			continue;	/*ignore backward edges */
-		    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-		    if (!visited[to]) {
-			visited[to] = 1;
-			stack[stack_size++] = to;
-		    }
-		}
-		dglEdgeset_T_Release(&et);
-	    }
-	}
-    }
-
-    dglNode_T_Release(&nt);
-
-    while (order_size) {
-	dglInt32_t node_id = order[--order_size];
-	if (component[node_id])
-	    continue;
-	components++;
-	component[node_id] = components;
-	stack[0] = node_id;
-	stack_size = 1;
-	while (stack_size) {
-	    dglInt32_t *node, *edgeset, *edge;
-	    dglEdgesetTraverser_s et;
-	    dglInt32_t cur_node_id = stack[--stack_size];
-	    node = dglGetNode(graph, cur_node_id);
-	    edgeset = dglNodeGet_OutEdgeset(graph, node);
-	    dglEdgeset_T_Initialize(&et, graph, edgeset);
-	    for (edge = dglEdgeset_T_First(&et); edge;
-		 edge = dglEdgeset_T_Next(&et)) {
-		dglInt32_t to;
-		if (dglEdgeGet_Id(graph, edge) > 0)
-		    continue;	/*ignore forward edges */
-		to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-		if (!component[to]) {
-		    component[to] = components;
-		    stack[stack_size++] = to;
-		}
-	    }
-	    dglEdgeset_T_Release(&et);
-	}
-    }
-
-    G_free(stack);
-    G_free(visited);
-    G_free(order);
-    G_free(processed);
-    return components;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/components.c (from rev 41777, grass/trunk/lib/vector/neta/components.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/components.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/components.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,199 @@
+/*!
+   \file vector/neta/components.c
+
+   \brief Network Analysis library - graph componets
+
+   Computes strongly and weakly connected components.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*!
+   \brief Computes weekly connected components
+
+   \param graph input graph
+   \param[out] component list of components
+
+   \return number of components
+   \return -1 on failure
+ */
+int NetA_weakly_connected_components(dglGraph_s * graph, int *component)
+{
+    int nnodes;
+    dglInt32_t *stack;
+    int *visited;
+    int stack_size, components;
+    dglInt32_t *cur_node;
+    dglNodeTraverser_s nt;
+
+    components = 0;
+    nnodes = dglGet_NodeCount(graph);
+    stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    visited = (int *)G_calloc(nnodes + 1, sizeof(int));
+    if (!stack || !visited) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    dglNode_T_Initialize(&nt, graph);
+
+    for (cur_node = dglNode_T_First(&nt); cur_node;
+	 cur_node = dglNode_T_Next(&nt)) {
+	dglInt32_t node_id = dglNodeGet_Id(graph, cur_node);
+
+	if (!visited[node_id]) {
+	    visited[node_id] = 1;
+	    stack[0] = node_id;
+	    stack_size = 1;
+	    component[node_id] = ++components;
+	    while (stack_size) {
+		dglInt32_t *node, *edgeset, *edge;
+		dglEdgesetTraverser_s et;
+
+		node = dglGetNode(graph, stack[--stack_size]);
+		edgeset = dglNodeGet_OutEdgeset(graph, node);
+		dglEdgeset_T_Initialize(&et, graph, edgeset);
+		for (edge = dglEdgeset_T_First(&et); edge;
+		     edge = dglEdgeset_T_Next(&et)) {
+		    dglInt32_t to;
+
+		    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+		    if (!visited[to]) {
+			visited[to] = 1;
+			component[to] = components;
+			stack[stack_size++] = to;
+		    }
+		}
+		dglEdgeset_T_Release(&et);
+	    }
+	}
+    }
+    dglNode_T_Release(&nt);
+    G_free(visited);
+    return components;
+}
+
+/*!
+   \brief Computes strongly connected components
+
+   \param graph input graph
+   \param[out] component list of components
+
+   \return number of components
+   \return -1 on failure
+ */
+int NetA_strongly_connected_components(dglGraph_s * graph, int *component)
+{
+    int nnodes;
+    dglInt32_t *stack, *order;
+    int *visited, *processed;
+    int stack_size, order_size, components;
+    dglInt32_t *node;
+    dglNodeTraverser_s nt;
+
+    components = 0;
+    nnodes = dglGet_NodeCount(graph);
+    stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    order = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    visited = (int *)G_calloc(nnodes + 1, sizeof(int));
+    processed = (int *)G_calloc(nnodes + 1, sizeof(int));
+    if (!stack || !visited || !order || !processed) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    order_size = 0;
+    dglNode_T_Initialize(&nt, graph);
+
+    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+	dglInt32_t node_id = dglNodeGet_Id(graph, node);
+
+	component[node_id] = 0;
+	if (!visited[node_id]) {
+	    visited[node_id] = 1;
+	    stack[0] = node_id;
+	    stack_size = 1;
+	    while (stack_size) {
+		dglInt32_t *node, *edgeset, *edge;
+		dglEdgesetTraverser_s et;
+		dglInt32_t cur_node_id = stack[stack_size - 1];
+
+		if (processed[cur_node_id]) {
+		    stack_size--;
+		    order[order_size++] = cur_node_id;
+		    continue;
+		}
+		processed[cur_node_id] = 1;
+		node = dglGetNode(graph, cur_node_id);
+		edgeset = dglNodeGet_OutEdgeset(graph, node);
+		dglEdgeset_T_Initialize(&et, graph, edgeset);
+		for (edge = dglEdgeset_T_First(&et); edge;
+		     edge = dglEdgeset_T_Next(&et)) {
+		    dglInt32_t to;
+
+		    if (dglEdgeGet_Id(graph, edge) < 0)
+			continue;	/*ignore backward edges */
+		    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+		    if (!visited[to]) {
+			visited[to] = 1;
+			stack[stack_size++] = to;
+		    }
+		}
+		dglEdgeset_T_Release(&et);
+	    }
+	}
+    }
+
+    dglNode_T_Release(&nt);
+
+    while (order_size) {
+	dglInt32_t node_id = order[--order_size];
+
+	if (component[node_id])
+	    continue;
+	components++;
+	component[node_id] = components;
+	stack[0] = node_id;
+	stack_size = 1;
+	while (stack_size) {
+	    dglInt32_t *node, *edgeset, *edge;
+	    dglEdgesetTraverser_s et;
+	    dglInt32_t cur_node_id = stack[--stack_size];
+
+	    node = dglGetNode(graph, cur_node_id);
+	    edgeset = dglNodeGet_OutEdgeset(graph, node);
+	    dglEdgeset_T_Initialize(&et, graph, edgeset);
+	    for (edge = dglEdgeset_T_First(&et); edge;
+		 edge = dglEdgeset_T_Next(&et)) {
+		dglInt32_t to;
+
+		if (dglEdgeGet_Id(graph, edge) > 0)
+		    continue;	/*ignore forward edges */
+		to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+		if (!component[to]) {
+		    component[to] = components;
+		    stack[stack_size++] = to;
+		}
+	    }
+	    dglEdgeset_T_Release(&et);
+	}
+    }
+
+    G_free(stack);
+    G_free(visited);
+    G_free(order);
+    G_free(processed);
+    return components;
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/flow.c
===================================================================
--- grass/trunk/lib/vector/neta/flow.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/flow.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,297 +0,0 @@
-/*!
-  \file vector/neta/flow.c
-  
-  \brief Network Analysis library - flow in graph
-
-  Computes the length of the shortest path between all pairs of nodes
-  in the network.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-#include <grass/neta.h>
-
-dglInt32_t sign(dglInt32_t x)
-{
-    if (x >= 0)
-	return 1;
-    return -1;
-}
-
-/*!
-  \brief Get max flow from source to sink.
-
-  Array flow stores flow for each edge. Negative flow corresponds to a
-  flow in opposite direction The function assumes that the edge costs
-  correspond to edge capacities.
-
-  \param graph input graph
-  \param source_list list of sources
-  \param sink_list list of sinks
-  \param[out] flow max flows
-
-  \return number of flows
-  \return -1 on failure
-*/
-int NetA_flow(dglGraph_s * graph, struct ilist *source_list,
-	      struct ilist *sink_list, int *flow)
-{
-    int nnodes, nlines, i;
-    dglEdgesetTraverser_s et;
-    dglInt32_t *queue;
-    dglInt32_t **prev;
-    char *is_source, *is_sink;
-    int begin, end, total_flow;
-
-    nnodes = dglGet_NodeCount(graph);
-    nlines = dglGet_EdgeCount(graph) / 2;	/*each line corresponds to two edges. One in each direction */
-    queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
-    prev = (dglInt32_t **) G_calloc(nnodes + 3, sizeof(dglInt32_t *));
-    is_source = (char *)G_calloc(nnodes + 3, sizeof(char));
-    is_sink = (char *)G_calloc(nnodes + 3, sizeof(char));
-    if (!queue || !prev || !is_source || !is_sink) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    for (i = 0; i < source_list->n_values; i++)
-	is_source[source_list->value[i]] = 1;
-    for (i = 0; i < sink_list->n_values; i++)
-	is_sink[sink_list->value[i]] = 1;
-
-    for (i = 0; i <= nlines; i++)
-	flow[i] = 0;
-
-    total_flow = 0;
-    while (1) {
-	dglInt32_t node, edge_id, min_residue;
-	int found = -1;
-	begin = end = 0;
-	for (i = 0; i < source_list->n_values; i++)
-	    queue[end++] = source_list->value[i];
-
-	for (i = 1; i <= nnodes; i++) {
-	    prev[i] = NULL;
-	}
-	while (begin != end && found == -1) {
-	    dglInt32_t vertex = queue[begin++];
-	    dglInt32_t *edge, *node = dglGetNode(graph, vertex);
-	    dglEdgeset_T_Initialize(&et, graph,
-				    dglNodeGet_OutEdgeset(graph, node));
-	    for (edge = dglEdgeset_T_First(&et); edge;
-		 edge = dglEdgeset_T_Next(&et)) {
-		dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
-		dglInt32_t id = dglEdgeGet_Id(graph, edge);
-		dglInt32_t to =
-		    dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-		if (!is_source[to] && prev[to] == NULL &&
-		    cap > sign(id) * flow[abs(id)]) {
-		    prev[to] = edge;
-		    if (is_sink[to]) {
-			found = to;
-			break;
-		    }
-		    queue[end++] = to;
-		}
-	    }
-	    dglEdgeset_T_Release(&et);
-	}
-	if (found == -1)
-	    break;		/*no augmenting path */
-	/*find minimum residual capacity along the augmenting path */
-	node = found;
-	edge_id = dglEdgeGet_Id(graph, prev[node]);
-	min_residue =
-	    dglEdgeGet_Cost(graph,
-			    prev[node]) - sign(edge_id) * flow[abs(edge_id)];
-	while (!is_source[node]) {
-	    dglInt32_t residue;
-	    edge_id = dglEdgeGet_Id(graph, prev[node]);
-	    residue =
-		dglEdgeGet_Cost(graph,
-				prev[node]) -
-		sign(edge_id) * flow[abs(edge_id)];
-	    if (residue < min_residue)
-		min_residue = residue;
-	    node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
-	}
-	total_flow += min_residue;
-	/*update flow along the augmenting path */
-	node = found;
-	while (!is_source[node]) {
-	    edge_id = dglEdgeGet_Id(graph, prev[node]);
-	    flow[abs(edge_id)] += sign(edge_id) * min_residue;
-	    node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
-	}
-    }
-
-    G_free(queue);
-    G_free(prev);
-    G_free(is_source);
-    G_free(is_sink);
-
-    return total_flow;
-}
-
-/*!
-  \brief Calculates minimum cut between source(s) and sink(s).
-
-  Flow is the array produced by NetA_flow() method when called with
-  source_list and sink_list as the input. The output of this and
-  NetA_flow() method should be the same.
-
-  \param graph input graph
-  \param source_list list of sources
-  \param sink_list list of sinks
-  \param[out] cut list of edges (cut)
-
-  \return number of edges
-  \return -1 on failure
-*/
-int NetA_min_cut(dglGraph_s * graph, struct ilist *source_list,
-		 struct ilist *sink_list, int *flow, struct ilist *cut)
-{
-    int nnodes, i;
-    dglEdgesetTraverser_s et;
-    dglInt32_t *queue;
-    char *visited;
-    int begin, end, total_flow;
-
-    nnodes = dglGet_NodeCount(graph);
-    queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
-    visited = (char *)G_calloc(nnodes + 3, sizeof(char));
-    if (!queue || !visited) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-
-    total_flow = begin = end = 0;
-
-    for (i = 1; i <= nnodes; i++)
-	visited[i] = 0;
-
-    for (i = 0; i < source_list->n_values; i++) {
-	queue[end++] = source_list->value[i];
-	visited[source_list->value[i]] = 1;
-    }
-
-    /* find vertices reachable from source(s) using only non-saturated edges */
-    while (begin != end) {
-	dglInt32_t vertex = queue[begin++];
-	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
-	dglEdgeset_T_Initialize(&et, graph, dglNodeGet_OutEdgeset(graph, node));
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et)) {
-	    dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
-	    dglInt32_t id = dglEdgeGet_Id(graph, edge);
-	    dglInt32_t to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-	    if (!visited[to] && cap > sign(id) * flow[abs(id)]) {
-		visited[to] = 1;
-		queue[end++] = to;
-	    }
-	}
-	dglEdgeset_T_Release(&et);
-    }
-    /*saturated edges from reachable vertices to non-reachable ones form a minimum cost */
-    Vect_reset_list(cut);
-    for (i = 1; i <= nnodes; i++) {
-	if (!visited[i])
-	    continue;
-	dglInt32_t *node, *edgeset, *edge;
-	node = dglGetNode(graph, i);
-	edgeset = dglNodeGet_OutEdgeset(graph, node);
-	dglEdgeset_T_Initialize(&et, graph, edgeset);
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et)) {
-	    dglInt32_t to, edge_id;
-	    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-	    edge_id = abs(dglEdgeGet_Id(graph, edge));
-	    if (!visited[to] && flow[edge_id] != 0) {
-		Vect_list_append(cut, edge_id);
-		total_flow += abs(flow[abs(edge_id)]);
-	    }
-	}
-	dglEdgeset_T_Release(&et);
-    }
-
-    G_free(visited);
-    G_free(queue);
-    return total_flow;
-}
-
-/*!
-  \brief Splits each vertex of in graph into two vertices
-
-  The method splits each vertex of in graph into two vertices: in
-  vertex and out vertex. Also, it adds an edge from an in vertex to
-  the corresponding out vertex (capacity=2) and it adds an edge from
-  out vertex to in vertex for each edge present in the in graph
-  (forward capacity=1, backward capacity=0). If the id of a vertex is
-  v then id of in vertex is 2*v-1 and of out vertex 2*v.
-  
-  \param in from graph
-  \param out to graph
-  \param node_cost list of node costs
-
-  \return number of undirected edges in the graph
-  \return -1 on failure
-*/
-int NetA_split_vertices(dglGraph_s * in, dglGraph_s * out, int *node_costs)
-{
-    dglInt32_t opaqueset[16] =
-	{ 360000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    dglNodeTraverser_s nt;
-    dglInt32_t nnodes, edge_cnt;
-    dglInt32_t *cur_node;
-    nnodes = dglGet_NodeCount(in);
-    dglInitialize(out, (dglByte_t) 1, (dglInt32_t) 0, (dglInt32_t) 0,
-		  opaqueset);
-    dglNode_T_Initialize(&nt, in);
-    edge_cnt = 0;
-    dglInt32_t max_node_cost = 0;
-    for (cur_node = dglNode_T_First(&nt); cur_node;
-	 cur_node = dglNode_T_Next(&nt)) {
-	dglInt32_t v = dglNodeGet_Id(in, cur_node);
-	edge_cnt++;
-	dglInt32_t cost = 1;
-	if (node_costs)
-	    cost = node_costs[v];
-	if (cost > max_node_cost)
-	    max_node_cost = cost;
-	dglAddEdge(out, 2 * v - 1, 2 * v, cost, edge_cnt);
-	dglAddEdge(out, 2 * v, 2 * v - 1, (dglInt32_t) 0, -edge_cnt);
-    }
-    dglNode_T_Release(&nt);
-    dglNode_T_Initialize(&nt, in);
-    for (cur_node = dglNode_T_First(&nt); cur_node;
-	 cur_node = dglNode_T_Next(&nt)) {
-	dglEdgesetTraverser_s et;
-	dglInt32_t *edge;
-	dglInt32_t v = dglNodeGet_Id(in, cur_node);
-	dglEdgeset_T_Initialize(&et, in, dglNodeGet_OutEdgeset(in, cur_node));
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et)) {
-	    dglInt32_t to;
-	    to = dglNodeGet_Id(in, dglEdgeGet_Tail(in, edge));
-	    edge_cnt++;
-	    dglAddEdge(out, 2 * v, 2 * to - 1, max_node_cost + 1, edge_cnt);
-	    dglAddEdge(out, 2 * to - 1, 2 * v, (dglInt32_t) 0, -edge_cnt);
-	}
-	dglEdgeset_T_Release(&et);
-    }
-    dglNode_T_Release(&nt);
-    if (dglFlatten(out) < 0)
-	G_fatal_error(_("GngFlatten error"));
-    return edge_cnt;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/flow.c (from rev 41777, grass/trunk/lib/vector/neta/flow.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/flow.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/flow.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,311 @@
+/*!
+   \file vector/neta/flow.c
+
+   \brief Network Analysis library - flow in graph
+
+   Computes the length of the shortest path between all pairs of nodes
+   in the network.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+#include <grass/neta.h>
+
+dglInt32_t sign(dglInt32_t x)
+{
+    if (x >= 0)
+	return 1;
+    return -1;
+}
+
+/*!
+   \brief Get max flow from source to sink.
+
+   Array flow stores flow for each edge. Negative flow corresponds to a
+   flow in opposite direction The function assumes that the edge costs
+   correspond to edge capacities.
+
+   \param graph input graph
+   \param source_list list of sources
+   \param sink_list list of sinks
+   \param[out] flow max flows
+
+   \return number of flows
+   \return -1 on failure
+ */
+int NetA_flow(dglGraph_s * graph, struct ilist *source_list,
+	      struct ilist *sink_list, int *flow)
+{
+    int nnodes, nlines, i;
+    dglEdgesetTraverser_s et;
+    dglInt32_t *queue;
+    dglInt32_t **prev;
+    char *is_source, *is_sink;
+    int begin, end, total_flow;
+
+    nnodes = dglGet_NodeCount(graph);
+    nlines = dglGet_EdgeCount(graph) / 2;	/*each line corresponds to two edges. One in each direction */
+    queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
+    prev = (dglInt32_t **) G_calloc(nnodes + 3, sizeof(dglInt32_t *));
+    is_source = (char *)G_calloc(nnodes + 3, sizeof(char));
+    is_sink = (char *)G_calloc(nnodes + 3, sizeof(char));
+    if (!queue || !prev || !is_source || !is_sink) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    for (i = 0; i < source_list->n_values; i++)
+	is_source[source_list->value[i]] = 1;
+    for (i = 0; i < sink_list->n_values; i++)
+	is_sink[sink_list->value[i]] = 1;
+
+    for (i = 0; i <= nlines; i++)
+	flow[i] = 0;
+
+    total_flow = 0;
+    while (1) {
+	dglInt32_t node, edge_id, min_residue;
+	int found = -1;
+
+	begin = end = 0;
+	for (i = 0; i < source_list->n_values; i++)
+	    queue[end++] = source_list->value[i];
+
+	for (i = 1; i <= nnodes; i++) {
+	    prev[i] = NULL;
+	}
+	while (begin != end && found == -1) {
+	    dglInt32_t vertex = queue[begin++];
+	    dglInt32_t *edge, *node = dglGetNode(graph, vertex);
+
+	    dglEdgeset_T_Initialize(&et, graph,
+				    dglNodeGet_OutEdgeset(graph, node));
+	    for (edge = dglEdgeset_T_First(&et); edge;
+		 edge = dglEdgeset_T_Next(&et)) {
+		dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
+		dglInt32_t id = dglEdgeGet_Id(graph, edge);
+		dglInt32_t to =
+		    dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+		if (!is_source[to] && prev[to] == NULL &&
+		    cap > sign(id) * flow[abs(id)]) {
+		    prev[to] = edge;
+		    if (is_sink[to]) {
+			found = to;
+			break;
+		    }
+		    queue[end++] = to;
+		}
+	    }
+	    dglEdgeset_T_Release(&et);
+	}
+	if (found == -1)
+	    break;		/*no augmenting path */
+	/*find minimum residual capacity along the augmenting path */
+	node = found;
+	edge_id = dglEdgeGet_Id(graph, prev[node]);
+	min_residue =
+	    dglEdgeGet_Cost(graph,
+			    prev[node]) - sign(edge_id) * flow[abs(edge_id)];
+	while (!is_source[node]) {
+	    dglInt32_t residue;
+
+	    edge_id = dglEdgeGet_Id(graph, prev[node]);
+	    residue =
+		dglEdgeGet_Cost(graph,
+				prev[node]) -
+		sign(edge_id) * flow[abs(edge_id)];
+	    if (residue < min_residue)
+		min_residue = residue;
+	    node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
+	}
+	total_flow += min_residue;
+	/*update flow along the augmenting path */
+	node = found;
+	while (!is_source[node]) {
+	    edge_id = dglEdgeGet_Id(graph, prev[node]);
+	    flow[abs(edge_id)] += sign(edge_id) * min_residue;
+	    node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
+	}
+    }
+
+    G_free(queue);
+    G_free(prev);
+    G_free(is_source);
+    G_free(is_sink);
+
+    return total_flow;
+}
+
+/*!
+   \brief Calculates minimum cut between source(s) and sink(s).
+
+   Flow is the array produced by NetA_flow() method when called with
+   source_list and sink_list as the input. The output of this and
+   NetA_flow() method should be the same.
+
+   \param graph input graph
+   \param source_list list of sources
+   \param sink_list list of sinks
+   \param[out] cut list of edges (cut)
+
+   \return number of edges
+   \return -1 on failure
+ */
+int NetA_min_cut(dglGraph_s * graph, struct ilist *source_list,
+		 struct ilist *sink_list, int *flow, struct ilist *cut)
+{
+    int nnodes, i;
+    dglEdgesetTraverser_s et;
+    dglInt32_t *queue;
+    char *visited;
+    int begin, end, total_flow;
+
+    nnodes = dglGet_NodeCount(graph);
+    queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
+    visited = (char *)G_calloc(nnodes + 3, sizeof(char));
+    if (!queue || !visited) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+
+    total_flow = begin = end = 0;
+
+    for (i = 1; i <= nnodes; i++)
+	visited[i] = 0;
+
+    for (i = 0; i < source_list->n_values; i++) {
+	queue[end++] = source_list->value[i];
+	visited[source_list->value[i]] = 1;
+    }
+
+    /* find vertices reachable from source(s) using only non-saturated edges */
+    while (begin != end) {
+	dglInt32_t vertex = queue[begin++];
+	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
+
+	dglEdgeset_T_Initialize(&et, graph,
+				dglNodeGet_OutEdgeset(graph, node));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et)) {
+	    dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
+	    dglInt32_t id = dglEdgeGet_Id(graph, edge);
+	    dglInt32_t to =
+		dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+	    if (!visited[to] && cap > sign(id) * flow[abs(id)]) {
+		visited[to] = 1;
+		queue[end++] = to;
+	    }
+	}
+	dglEdgeset_T_Release(&et);
+    }
+    /*saturated edges from reachable vertices to non-reachable ones form a minimum cost */
+    Vect_reset_list(cut);
+    for (i = 1; i <= nnodes; i++) {
+	if (!visited[i])
+	    continue;
+	dglInt32_t *node, *edgeset, *edge;
+
+	node = dglGetNode(graph, i);
+	edgeset = dglNodeGet_OutEdgeset(graph, node);
+	dglEdgeset_T_Initialize(&et, graph, edgeset);
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et)) {
+	    dglInt32_t to, edge_id;
+
+	    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+	    edge_id = abs(dglEdgeGet_Id(graph, edge));
+	    if (!visited[to] && flow[edge_id] != 0) {
+		Vect_list_append(cut, edge_id);
+		total_flow += abs(flow[abs(edge_id)]);
+	    }
+	}
+	dglEdgeset_T_Release(&et);
+    }
+
+    G_free(visited);
+    G_free(queue);
+    return total_flow;
+}
+
+/*!
+   \brief Splits each vertex of in graph into two vertices
+
+   The method splits each vertex of in graph into two vertices: in
+   vertex and out vertex. Also, it adds an edge from an in vertex to
+   the corresponding out vertex (capacity=2) and it adds an edge from
+   out vertex to in vertex for each edge present in the in graph
+   (forward capacity=1, backward capacity=0). If the id of a vertex is
+   v then id of in vertex is 2*v-1 and of out vertex 2*v.
+
+   \param in from graph
+   \param out to graph
+   \param node_cost list of node costs
+
+   \return number of undirected edges in the graph
+   \return -1 on failure
+ */
+int NetA_split_vertices(dglGraph_s * in, dglGraph_s * out, int *node_costs)
+{
+    dglInt32_t opaqueset[16] =
+	{ 360000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+    dglNodeTraverser_s nt;
+    dglInt32_t nnodes, edge_cnt;
+    dglInt32_t *cur_node;
+
+    nnodes = dglGet_NodeCount(in);
+    dglInitialize(out, (dglByte_t) 1, (dglInt32_t) 0, (dglInt32_t) 0,
+		  opaqueset);
+    dglNode_T_Initialize(&nt, in);
+    edge_cnt = 0;
+    dglInt32_t max_node_cost = 0;
+
+    for (cur_node = dglNode_T_First(&nt); cur_node;
+	 cur_node = dglNode_T_Next(&nt)) {
+	dglInt32_t v = dglNodeGet_Id(in, cur_node);
+
+	edge_cnt++;
+	dglInt32_t cost = 1;
+
+	if (node_costs)
+	    cost = node_costs[v];
+	if (cost > max_node_cost)
+	    max_node_cost = cost;
+	dglAddEdge(out, 2 * v - 1, 2 * v, cost, edge_cnt);
+	dglAddEdge(out, 2 * v, 2 * v - 1, (dglInt32_t) 0, -edge_cnt);
+    }
+    dglNode_T_Release(&nt);
+    dglNode_T_Initialize(&nt, in);
+    for (cur_node = dglNode_T_First(&nt); cur_node;
+	 cur_node = dglNode_T_Next(&nt)) {
+	dglEdgesetTraverser_s et;
+	dglInt32_t *edge;
+	dglInt32_t v = dglNodeGet_Id(in, cur_node);
+
+	dglEdgeset_T_Initialize(&et, in, dglNodeGet_OutEdgeset(in, cur_node));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et)) {
+	    dglInt32_t to;
+
+	    to = dglNodeGet_Id(in, dglEdgeGet_Tail(in, edge));
+	    edge_cnt++;
+	    dglAddEdge(out, 2 * v, 2 * to - 1, max_node_cost + 1, edge_cnt);
+	    dglAddEdge(out, 2 * to - 1, 2 * v, (dglInt32_t) 0, -edge_cnt);
+	}
+	dglEdgeset_T_Release(&et);
+    }
+    dglNode_T_Release(&nt);
+    if (dglFlatten(out) < 0)
+	G_fatal_error(_("GngFlatten error"));
+    return edge_cnt;
+}

Copied: grass/branches/develbranch_6/lib/vector/neta/netalib.dox (from rev 41779, grass/trunk/lib/vector/neta/netalib.dox)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/netalib.dox	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/netalib.dox	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,45 @@
+/*! \page netalib GRASS Network Analysis Library
+
+by GRASS Development Team (http://grass.osgeo.org)
+
+This library is used for network-based analysis, see <tt>v.net.*</tt>
+modules for implementation issues.
+
+\section netaFn Functions
+
+- NetA_add_point_on_node()
+- NetA_allpairs()
+- NetA_articulation_points()
+- NetA_betweenness_closeness()
+- NetA_compute_bridges()
+- NetA_degree_centrality()
+- NetA_distance_from_points()
+- NetA_eigenvector_centrality()
+- NetA_find_path()
+- NetA_flow()
+- NetA_get_node_costs()
+- NetA_initialise_varray()
+- NetA_init_timetable_from_db()
+- NetA_min_cut()
+- NetA_points_to_nodes()
+- NetA_spanning_tree()
+- NetA_split_vertices()
+- NetA_strongly_connected_components()
+- NetA_timetable_get_route_time()
+- NetA_timetable_result_release()
+- NetA_timetable_shortest_path()
+- NetA_varray_to_nodes()
+- NetA_weakly_connected_components()
+
+\section netaAuthors Authors
+
+ Daniel Bundala (Google Summer of Code 2009)
+
+\section netaSeeAlso See Also
+
+ - \ref Vector_Library
+  
+ - \ref dbmilib
+
+Last change: $Date$
+*/

Deleted: grass/branches/develbranch_6/lib/vector/neta/path.c
===================================================================
--- grass/trunk/lib/vector/neta/path.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/path.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,171 +0,0 @@
-/*!
-  \file vector/neta/path.c
-  
-  \brief Network Analysis library - shortest path
-
-  Shortest paths from a set of nodes.
-
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-#include <grass/neta.h>
-
-/*!
-  \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
-  reachable. Prev contains edges from predecessor along the shortest
-  path.
-
-  \param graph input graph
-  \param from list of 'from' positions
-  \param dst list of 'to' positions
-  \param[out] prev list of edges from predecessor along the shortest path
-  
-  \return 0 on success
-  \return -1 on failure
-*/
-int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from, int *dst,
-			      dglInt32_t ** prev)
-{
-    int i, nnodes;
-    dglHeap_s heap;
-    nnodes = dglGet_NodeCount(graph);
-    dglEdgesetTraverser_s et;
-    for (i = 1; i <= nnodes; i++) {
-	dst[i] = -1;
-	prev[i] = NULL;
-    }
-
-    dglHeapInit(&heap);
-
-    for (i = 0; i < from->n_values; i++) {
-	int v = from->value[i];
-	if (dst[v] == 0)
-	    continue;		/*ingore duplicates */
-	dst[v] = 0;
-	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_OutEdgeset(graph,
-						      dglGetNode(graph, v)));
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et)) {
-	    dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
-	    dglInt32_t to_id = dglNodeGet_Id(graph, to);
-	    dglInt32_t d = dglEdgeGet_Cost(graph, edge);
-	    if (dst[to_id] == -1 || dst[to_id] > dist + d) {
-		dst[to_id] = dist + d;
-		prev[to_id] = edge;
-		heap_data.ul = to_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 iff edges[abs(i)] == 1. List
-  stores the indices of lines on the path. Method return number of
-  edges or -1 if no path exist.
-
-  \param graph input graph
-  \param from 'from' position
-  \param to 'to' position
-  \param edges list of available edges
-  \param[out] list list of edges
-  
-  \return number of edges
-  \return -1 on failure
-*/
-int NetA_find_path(dglGraph_s * graph, int from, int to, int *edges,
-		   struct ilist *list)
-{
-    dglInt32_t **prev, *queue;
-    dglEdgesetTraverser_s et;
-    char *vis;
-    int begin, end, cur, nnodes;
-
-    nnodes = dglGet_NodeCount(graph);
-    prev = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
-    queue = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
-    vis = (char *)G_calloc(nnodes + 1, sizeof(char));
-    if (!prev || !queue || !vis) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-    Vect_reset_list(list);
-
-    begin = 0;
-    end = 1;
-    vis[from] = 'y';
-    queue[0] = from;
-    prev[from] = NULL;
-    while (begin != end) {
-	dglInt32_t vertex = queue[begin++];
-	if (vertex == to)
-	    break;
-	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
-	dglEdgeset_T_Initialize(&et, graph, dglNodeGet_OutEdgeset(graph, node));
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et)) {
-	    dglInt32_t id = abs(dglEdgeGet_Id(graph, edge));
-	    dglInt32_t to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
-	    if (edges[id] && !vis[to]) {
-		vis[to] = 'y';
-		prev[to] = edge;
-		queue[end++] = to;
-	    }
-	}
-	dglEdgeset_T_Release(&et);
-    }
-    G_free(queue);
-    if (!vis[to]) {
-	G_free(prev);
-	G_free(vis);
-	return -1;
-    }
-
-    cur = to;
-    while (prev[cur] != NULL) {
-	Vect_list_append(list, abs(dglEdgeGet_Id(graph, prev[cur])));
-	cur = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[cur]));
-    }
-
-    G_free(prev);
-    G_free(vis);
-    return list->n_values;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/path.c (from rev 41777, grass/trunk/lib/vector/neta/path.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/path.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/path.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,182 @@
+/*!
+   \file vector/neta/path.c
+
+   \brief Network Analysis library - shortest path
+
+   Shortest paths from a set of nodes.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+#include <grass/neta.h>
+
+/*!
+   \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
+   reachable. Prev contains edges from predecessor along the shortest
+   path.
+
+   \param graph input graph
+   \param from list of 'from' positions
+   \param dst list of 'to' positions
+   \param[out] prev list of edges from predecessor along the shortest path
+
+   \return 0 on success
+   \return -1 on failure
+ */
+int NetA_distance_from_points(dglGraph_s * graph, struct ilist *from,
+			      int *dst, dglInt32_t ** prev)
+{
+    int i, nnodes;
+    dglHeap_s heap;
+
+    nnodes = dglGet_NodeCount(graph);
+    dglEdgesetTraverser_s et;
+
+    for (i = 1; i <= nnodes; i++) {
+	dst[i] = -1;
+	prev[i] = NULL;
+    }
+
+    dglHeapInit(&heap);
+
+    for (i = 0; i < from->n_values; i++) {
+	int v = from->value[i];
+
+	if (dst[v] == 0)
+	    continue;		/*ingore duplicates */
+	dst[v] = 0;
+	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_OutEdgeset(graph,
+						      dglGetNode(graph, v)));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et)) {
+	    dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
+	    dglInt32_t to_id = dglNodeGet_Id(graph, to);
+	    dglInt32_t d = dglEdgeGet_Cost(graph, edge);
+
+	    if (dst[to_id] == -1 || dst[to_id] > dist + d) {
+		dst[to_id] = dist + d;
+		prev[to_id] = edge;
+		heap_data.ul = to_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 iff edges[abs(i)] == 1. List
+   stores the indices of lines on the path. Method return number of
+   edges or -1 if no path exist.
+
+   \param graph input graph
+   \param from 'from' position
+   \param to 'to' position
+   \param edges list of available edges
+   \param[out] list list of edges
+
+   \return number of edges
+   \return -1 on failure
+ */
+int NetA_find_path(dglGraph_s * graph, int from, int to, int *edges,
+		   struct ilist *list)
+{
+    dglInt32_t **prev, *queue;
+    dglEdgesetTraverser_s et;
+    char *vis;
+    int begin, end, cur, nnodes;
+
+    nnodes = dglGet_NodeCount(graph);
+    prev = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    queue = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+    vis = (char *)G_calloc(nnodes + 1, sizeof(char));
+    if (!prev || !queue || !vis) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+    Vect_reset_list(list);
+
+    begin = 0;
+    end = 1;
+    vis[from] = 'y';
+    queue[0] = from;
+    prev[from] = NULL;
+    while (begin != end) {
+	dglInt32_t vertex = queue[begin++];
+
+	if (vertex == to)
+	    break;
+	dglInt32_t *edge, *node = dglGetNode(graph, vertex);
+
+	dglEdgeset_T_Initialize(&et, graph,
+				dglNodeGet_OutEdgeset(graph, node));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et)) {
+	    dglInt32_t id = abs(dglEdgeGet_Id(graph, edge));
+	    dglInt32_t to =
+		dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+	    if (edges[id] && !vis[to]) {
+		vis[to] = 'y';
+		prev[to] = edge;
+		queue[end++] = to;
+	    }
+	}
+	dglEdgeset_T_Release(&et);
+    }
+    G_free(queue);
+    if (!vis[to]) {
+	G_free(prev);
+	G_free(vis);
+	return -1;
+    }
+
+    cur = to;
+    while (prev[cur] != NULL) {
+	Vect_list_append(list, abs(dglEdgeGet_Id(graph, prev[cur])));
+	cur = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[cur]));
+    }
+
+    G_free(prev);
+    G_free(vis);
+    return list->n_values;
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/spanningtree.c
===================================================================
--- grass/trunk/lib/vector/neta/spanningtree.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/spanningtree.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,138 +0,0 @@
-/*!
-  \file vector/neta/spanningtree.c
-  
-  \brief Network Analysis library - spanning tree
-
-  Computes minimum spanning tree in the network.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-
-struct union_find
-{
-    int *parent;
-};
-
-static int uf_initialize(struct union_find *uf, int size)
-{
-    int i;
-    uf->parent = (int *)G_calloc(size, sizeof(int));
-    if (!uf->parent)
-	return 0;
-    for (i = 0; i < size; i++)
-	uf->parent[i] = i;
-    return 1;
-}
-
-static void uf_release(struct union_find *uf)
-{
-    G_free(uf->parent);
-}
-
-static int uf_find(struct union_find *uf, int v)
-{
-    int cur = v, tmp;
-    while (uf->parent[cur] != cur)
-	cur = uf->parent[cur];
-    while (uf->parent[v] != v) {
-	tmp = uf->parent[v];
-	uf->parent[v] = cur;
-	v = tmp;
-    }
-    return cur;
-}
-
-/*TODO: union by rank */
-static void uf_union(struct union_find *uf, int u, int v)
-{
-    int parent_u = uf_find(uf, u);
-    int parent_v = uf_find(uf, v);
-    if (parent_u != parent_v)
-	uf->parent[parent_u] = parent_v;
-}
-
-typedef struct
-{
-    dglInt32_t cost;
-    dglInt32_t *edge;
-} edge_cost_pair;
-
-static int cmp_edge(const void *pa, const void *pb)
-{
-    return ((edge_cost_pair *) pa)->cost - ((edge_cost_pair *) pb)->cost;
-}
-
-/*!
-  \brief Get number of edges in the spanning forest
-
-  \param graph input graph
-  \param[out] list of edges
-
-  \return number of edges
-  \return -1 on failure
-*/
-int NetA_spanning_tree(dglGraph_s * graph, struct ilist *tree_list)
-{
-    int nnodes, edges, nedges, i, index;
-    edge_cost_pair *perm;	/*permutaion of edges in ascending order */
-    struct union_find uf;
-    dglEdgesetTraverser_s et;
-    nnodes = dglGet_NodeCount(graph);
-    nedges = dglGet_EdgeCount(graph);
-    perm = (edge_cost_pair *) G_calloc(nedges, sizeof(edge_cost_pair));
-    if (!perm || !uf_initialize(&uf, nnodes + 1)) {
-	G_fatal_error(_("Out of memory"));
-	return -1;
-    }
-    /*for some obscure reasons, dglGetEdge always returns NULL. Therefore this complicated enumeration of the edges... */
-    index = 0;
-    G_message(_("Computing minimum spanning tree..."));
-    G_percent_reset();
-    for (i = 1; i <= nnodes; i++) {
-	G_percent(i, nnodes + nedges, 1);
-	dglInt32_t *edge;
-	dglEdgeset_T_Initialize(&et, graph,
-				dglNodeGet_OutEdgeset(graph,
-						      dglGetNode(graph,
-								 (dglInt32_t)
-								 i)));
-	for (edge = dglEdgeset_T_First(&et); edge;
-	     edge = dglEdgeset_T_Next(&et))
-	    if (dglEdgeGet_Id(graph, edge) > 0) {
-		perm[index].edge = edge;
-		perm[index].cost = dglEdgeGet_Cost(graph, edge);
-		index++;
-	    }
-
-	dglEdgeset_T_Release(&et);
-    }
-    edges = 0;
-    qsort((void *)perm, index, sizeof(edge_cost_pair), cmp_edge);
-    for (i = 0; i < index; i++) {
-	G_percent(i + nnodes, nnodes + nedges, 1);
-	dglInt32_t head =
-	    dglNodeGet_Id(graph, dglEdgeGet_Head(graph, perm[i].edge));
-	dglInt32_t tail =
-	    dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, perm[i].edge));
-	if (uf_find(&uf, head) != uf_find(&uf, tail)) {
-	    uf_union(&uf, head, tail);
-	    edges++;
-	    Vect_list_append(tree_list, dglEdgeGet_Id(graph, perm[i].edge));
-	}
-    }
-    G_free(perm);
-    uf_release(&uf);
-    return edges;
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/spanningtree.c (from rev 41777, grass/trunk/lib/vector/neta/spanningtree.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/spanningtree.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/spanningtree.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,142 @@
+/*!
+   \file vector/neta/spanningtree.c
+
+   \brief Network Analysis library - spanning tree
+
+   Computes minimum spanning tree in the network.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+struct union_find
+{
+    int *parent;
+};
+
+static int uf_initialize(struct union_find *uf, int size)
+{
+    int i;
+    uf->parent = (int *)G_calloc(size, sizeof(int));
+    if (!uf->parent)
+	return 0;
+    for (i = 0; i < size; i++)
+	uf->parent[i] = i;
+    return 1;
+}
+
+static void uf_release(struct union_find *uf)
+{
+    G_free(uf->parent);
+}
+
+static int uf_find(struct union_find *uf, int v)
+{
+    int cur = v, tmp;
+
+    while (uf->parent[cur] != cur)
+	cur = uf->parent[cur];
+    while (uf->parent[v] != v) {
+	tmp = uf->parent[v];
+	uf->parent[v] = cur;
+	v = tmp;
+    }
+    return cur;
+}
+
+/*TODO: union by rank */
+static void uf_union(struct union_find *uf, int u, int v)
+{
+    int parent_u = uf_find(uf, u);
+    int parent_v = uf_find(uf, v);
+
+    if (parent_u != parent_v)
+	uf->parent[parent_u] = parent_v;
+}
+
+typedef struct
+{
+    dglInt32_t cost;
+    dglInt32_t *edge;
+} edge_cost_pair;
+
+static int cmp_edge(const void *pa, const void *pb)
+{
+    return ((edge_cost_pair *) pa)->cost - ((edge_cost_pair *) pb)->cost;
+}
+
+/*!
+   \brief Get number of edges in the spanning forest
+
+   \param graph input graph
+   \param[out] list of edges
+
+   \return number of edges
+   \return -1 on failure
+ */
+int NetA_spanning_tree(dglGraph_s * graph, struct ilist *tree_list)
+{
+    int nnodes, edges, nedges, i, index;
+    edge_cost_pair *perm;	/*permutaion of edges in ascending order */
+    struct union_find uf;
+    dglEdgesetTraverser_s et;
+
+    nnodes = dglGet_NodeCount(graph);
+    nedges = dglGet_EdgeCount(graph);
+    perm = (edge_cost_pair *) G_calloc(nedges, sizeof(edge_cost_pair));
+    if (!perm || !uf_initialize(&uf, nnodes + 1)) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+    /*for some obscure reasons, dglGetEdge always returns NULL. Therefore this complicated enumeration of the edges... */
+    index = 0;
+    G_message(_("Computing minimum spanning tree..."));
+    G_percent_reset();
+    for (i = 1; i <= nnodes; i++) {
+	G_percent(i, nnodes + nedges, 1);
+	dglInt32_t *edge;
+
+	dglEdgeset_T_Initialize(&et, graph,
+				dglNodeGet_OutEdgeset(graph,
+						      dglGetNode(graph,
+								 (dglInt32_t)
+								 i)));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et))
+	    if (dglEdgeGet_Id(graph, edge) > 0) {
+		perm[index].edge = edge;
+		perm[index].cost = dglEdgeGet_Cost(graph, edge);
+		index++;
+	    }
+
+	dglEdgeset_T_Release(&et);
+    }
+    edges = 0;
+    qsort((void *)perm, index, sizeof(edge_cost_pair), cmp_edge);
+    for (i = 0; i < index; i++) {
+	G_percent(i + nnodes, nnodes + nedges, 1);
+	dglInt32_t head =
+	    dglNodeGet_Id(graph, dglEdgeGet_Head(graph, perm[i].edge));
+	dglInt32_t tail =
+	    dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, perm[i].edge));
+	if (uf_find(&uf, head) != uf_find(&uf, tail)) {
+	    uf_union(&uf, head, tail);
+	    edges++;
+	    Vect_list_append(tree_list, dglEdgeGet_Id(graph, perm[i].edge));
+	}
+    }
+    G_free(perm);
+    uf_release(&uf);
+    return edges;
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/timetables.c
===================================================================
--- grass/trunk/lib/vector/neta/timetables.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/timetables.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,544 +0,0 @@
-/*!
-  \file vector/neta/timetables.c
-  
-  \brief Network Analysis library - timetables
-
-  Shortest path using timetables.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/dbmi.h>
-#include <grass/glocale.h>
-#include <grass/dgl/graph.h>
-#include <grass/neta.h>
-
-/*!
-  \brief Get number of distinct elements
-
-  \param driver DB driver
-  \param sql SQl string
-  \param[out] list of lengths
-  \param[out] list of ids
-  
-  \return number of distinct elements 
-  \return -1 on failure
-*/
-int NetA_init_distinct(dbDriver * driver, dbString * sql, int **lengths,
-		       int **ids)
-{
-    int count, last, cur, result, index, more;
-    dbCursor cursor;
-    dbTable *table;
-    dbColumn *column;
-    dbValue *value;
-
-    if (db_open_select_cursor(driver, sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
-	G_warning(_("Unable to open select cursor: %s"), db_get_string(sql));
-	return -1;
-    }
-    /*TODO: check column types */
-
-    count = last = 0;
-    /*count number of distinct routes */
-    table = db_get_cursor_table(&cursor);
-    column = db_get_table_column(table, 0);
-    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
-	value = db_get_column_value(column);
-	cur = db_get_value_int(value);
-	if (count == 0 || cur != last) {
-	    last = cur;
-	    count++;
-	}
-    }
-    result = count;
-    db_close_cursor(&cursor);
-
-    *lengths = (int *)G_calloc(count, sizeof(int));
-    *ids = (int *)G_calloc(count, sizeof(int));
-    if (!*lengths || !*ids) {
-	G_warning(_("Out of memory"));
-	return -1;
-    }
-    db_open_select_cursor(driver, sql, &cursor, DB_SEQUENTIAL);
-    count = index = 0;
-    /*calculate the lengths of the routes */
-    table = db_get_cursor_table(&cursor);
-    column = db_get_table_column(table, 0);
-    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
-	value = db_get_column_value(column);
-	cur = db_get_value_int(value);
-	if (count != 0 && cur != last)
-	    index++;
-	if (count == 0 || cur != last)
-	    (*ids)[index] = cur;
-	(*lengths)[index]++;
-	last = cur;
-	count++;
-    }
-    return result;
-}
-
-static int cmp_int(const void *a, const void *b)
-{
-    return *(int *)a - *(int *)b;
-}
-
-/*!
-  \brief Initialises timetable from a database
-
-  \param In pointer to Map_info structure
-  \param route_layer layer number of routes
-  \param walk_layer layer number of walkers
-  \param route_id id of route
-  \param times list of timestamps
-  \param to_stop ?
-  \param walk_length walk length as string
-  \param timetable pointer to neta_timetable
-  \param route_ids list of route ids
-  \param stop_ids lits of stop ids
-
-  \return 0 on success
-  \return non-zero value on failure
-*/
-int NetA_init_timetable_from_db(struct Map_info *In, int route_layer,
-				int walk_layer, char *route_id, char *times,
-				char *to_stop, char *walk_length,
-				neta_timetable * timetable, int **route_ids,
-				int **stop_ids)
-{
-    int more, i, stop, route, time, *stop_pnt, stop1, stop2;
-    dbString sql;
-    dbCursor cursor;
-    dbTable *table;
-    dbColumn *column1, *column2, *column3;
-    dbValue *value;
-    char buf[2000];
-
-    dbDriver *driver;
-    struct field_info *Fi;
-    Fi = Vect_get_field(In, route_layer);
-    driver = db_start_driver_open_database(Fi->driver, Fi->database);
-    if (driver == NULL)
-	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
-		      Fi->database, Fi->driver);
-
-
-    db_init_string(&sql);
-    sprintf(buf, "select %s from %s order by %s", route_id, Fi->table,
-	    route_id);
-    db_set_string(&sql, buf);
-    timetable->routes =
-	NetA_init_distinct(driver, &sql, &(timetable->route_length), route_ids);
-    if (timetable->routes < 0)
-	return 1;
-
-    sprintf(buf, "select %s from %s order by %s", Fi->key, Fi->table, Fi->key);
-    db_set_string(&sql, buf);
-    timetable->stops =
-	NetA_init_distinct(driver, &sql, &(timetable->stop_length), stop_ids);
-    if (timetable->stops < 0)
-	return 1;
-
-    timetable->route_stops = (int **)G_calloc(timetable->routes, sizeof(int *));
-    timetable->route_times = (int **)G_calloc(timetable->routes, sizeof(int *));
-    timetable->stop_routes = (int **)G_calloc(timetable->stops, sizeof(int *));
-    timetable->stop_times = (int **)G_calloc(timetable->stops, sizeof(int *));
-    timetable->walk_length = (int *)G_calloc(timetable->stops, sizeof(int));
-    timetable->walk_stops = (int **)G_calloc(timetable->stops, sizeof(int *));
-    timetable->walk_times = (int **)G_calloc(timetable->stops, sizeof(int *));
-    if (!timetable->route_stops || !timetable->route_times ||
-	!timetable->stop_routes || !timetable->stop_times ||
-	!timetable->walk_length) {
-	G_warning(_("Out of memory"));
-	return 2;
-    }
-
-    for (i = 0; i < timetable->routes; i++) {
-	timetable->route_stops[i] =
-	    (int *)G_calloc(timetable->route_length[i], sizeof(int));
-	timetable->route_times[i] =
-	    (int *)G_calloc(timetable->route_length[i], sizeof(int));
-	if (!timetable->route_stops[i] || !timetable->route_times[i]) {
-	    G_warning(_("Out of memory"));
-	    return 2;
-	}
-
-	timetable->route_length[i] = 0;
-    }
-
-    for (i = 0; i < timetable->stops; i++) {
-	timetable->stop_routes[i] =
-	    (int *)G_calloc(timetable->stop_length[i], sizeof(int));
-	timetable->stop_times[i] =
-	    (int *)G_calloc(timetable->stop_length[i], sizeof(int));
-	if (!timetable->stop_routes[i] || !timetable->stop_times[i]) {
-	    G_warning(_("Out of memory"));
-	    return 2;
-	}
-	timetable->walk_length[i] = 0;
-	timetable->stop_length[i] = 0;
-    }
-
-    sprintf(buf, "select %s, %s, %s from %s order by %s", Fi->key, route_id,
-	    times, Fi->table, times);
-    db_set_string(&sql, buf);
-
-    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
-	G_warning(_("Unable to open select cursor: %s"), db_get_string(&sql));
-	return 1;
-    }
-
-
-    table = db_get_cursor_table(&cursor);
-    column1 = db_get_table_column(table, 0);
-    column2 = db_get_table_column(table, 1);
-    column3 = db_get_table_column(table, 2);
-    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
-	value = db_get_column_value(column1);
-	stop = db_get_value_int(value);
-	value = db_get_column_value(column2);
-	route = db_get_value_int(value);
-	value = db_get_column_value(column3);
-	time = db_get_value_int(value);
-	stop =
-	    (int *)bsearch(&stop, *stop_ids, timetable->stops, sizeof(int),
-			   cmp_int) - (*stop_ids);
-	route =
-	    (int *)bsearch(&route, *route_ids, timetable->routes, sizeof(int),
-			   cmp_int) - (*route_ids);
-
-	timetable->stop_routes[stop][timetable->stop_length[stop]] = route;
-	timetable->stop_times[stop][timetable->stop_length[stop]++] = time;
-
-	timetable->route_stops[route][timetable->route_length[route]] = stop;
-	timetable->route_times[route][timetable->route_length[route]++] = time;
-    }
-    db_close_cursor(&cursor);
-
-    if (walk_layer != -1) {
-
-	Fi = Vect_get_field(In, walk_layer);
-	sprintf(buf, "select %s, %s, %s from %s", Fi->key, to_stop, walk_length,
-		Fi->table);
-	db_set_string(&sql, buf);
-
-	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
-	    DB_OK) {
-	    G_warning(_("Unable to open select cursor: %s"),
-		      db_get_string(&sql));
-	    return 1;
-	}
-
-	table = db_get_cursor_table(&cursor);
-	column1 = db_get_table_column(table, 0);
-	column2 = db_get_table_column(table, 1);
-	while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
-	    value = db_get_column_value(column2);
-	    stop = db_get_value_int(value);
-	    stop_pnt =
-		(int *)bsearch(&stop, *stop_ids, timetable->stops, sizeof(int),
-			       cmp_int);
-	    if (stop_pnt) {
-		value = db_get_column_value(column1);
-		stop = db_get_value_int(value);
-		stop_pnt =
-		    (int *)bsearch(&stop, *stop_ids, timetable->stops,
-				   sizeof(int), cmp_int);
-		if (stop_pnt) {
-		    stop = stop_pnt - (*stop_ids);
-		    timetable->walk_length[stop]++;
-		}
-	    }
-	}
-	db_close_cursor(&cursor);
-
-	for (i = 0; i < timetable->stops; i++) {
-	    timetable->walk_stops[i] =
-		(int *)G_calloc(timetable->walk_length[i], sizeof(int));
-	    timetable->walk_times[i] =
-		(int *)G_calloc(timetable->walk_length[i], sizeof(int));
-	    if (!timetable->walk_stops[i] || !timetable->walk_times[i]) {
-		G_warning(_("Out of memory"));
-		return 2;
-	    }
-	    timetable->walk_length[i] = 0;
-	}
-
-	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
-	    DB_OK) {
-	    G_warning(_("Unable to open select cursor: %s"),
-		      db_get_string(&sql));
-	    return 1;
-	}
-
-	table = db_get_cursor_table(&cursor);
-	column1 = db_get_table_column(table, 0);
-	column2 = db_get_table_column(table, 1);
-	column3 = db_get_table_column(table, 2);
-	while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
-	    value = db_get_column_value(column2);
-	    stop = db_get_value_int(value);
-	    stop_pnt =
-		(int *)bsearch(&stop, *stop_ids, timetable->stops, sizeof(int),
-			       cmp_int);
-	    if (stop_pnt) {
-		stop2 = stop_pnt - (*stop_ids);
-		value = db_get_column_value(column1);
-		stop = db_get_value_int(value);
-		stop_pnt =
-		    (int *)bsearch(&stop, *stop_ids, timetable->stops,
-				   sizeof(int), cmp_int);
-		if (stop_pnt) {
-		    stop1 = stop_pnt - (*stop_ids);
-		    value = db_get_column_value(column3);
-		    time = db_get_value_int(value);
-		    timetable->walk_stops[stop1][timetable->
-						 walk_length[stop1]] = stop2;
-		    timetable->walk_times[stop1][timetable->
-						 walk_length[stop1]++] = time;
-		}
-	    }
-	}
-	db_close_cursor(&cursor);
-    }
-    db_close_database_shutdown_driver(driver);
-
-    return 0;
-}
-
-typedef struct
-{
-    int v;
-    int conns;
-} neta_heap_data;
-
-static neta_heap_data *new_heap_data(int conns, int v)
-{
-    neta_heap_data *d = (neta_heap_data *) G_calloc(1, sizeof(neta_heap_data));
-    d->v = v;
-    d->conns = conns;
-    return d;
-}
-
-/*!
-  \brief Update Dijkstra structures
-
-  \param olc_conns old connection
-  \param new_conns new connection
-  \param to old 'to' node
-  \param new_dst new 'to' node
-  \param v ?
-  \param route id of route
-  \param rows ?
-  \param update ?
-  \param[out] result pointer to neta_timetable_result structure
-  \param heap ?
-*/
-void NetA_update_dijkstra(int old_conns, int new_conns, int to, int new_dst,
-			  int v, int route, int rows, int update,
-			  neta_timetable_result * result, dglHeap_s * heap)
-{
-    if (result->dst[new_conns][to] == -1 ||
-	result->dst[new_conns][to] > new_dst) {
-	result->dst[new_conns][to] = new_dst;
-	result->prev_stop[new_conns][to] = v;
-	result->prev_route[new_conns][to] = route;
-	result->prev_conn[new_conns][to] = old_conns;
-	if (update) {
-	    dglHeapData_u heap_data;
-	    heap_data.pv = (void *)new_heap_data(new_conns, to);
-	    dglHeapInsertMin(heap, new_dst, ' ', heap_data);
-	}
-    }
-}
-
-/*!
-  \brief Computes the earliest arrival time.
-
-  Computes the earliest arrival time to to_stop from from_stop
-  starting at start_time, or -1 if no path exists
-
-  \param timetable pointer to neta_timetable structure
-  \param from_stop 'from' node
-  \param to_stop 'to' stop
-  \param start_time start timestamp
-  \param min_change ?
-  \param max_changes ?
-  \param walking_change ?
-  \param[out] result pointer to neta_timetable_result
-
-  \return ?
-  \return -1 on error
-*/
-int NetA_timetable_shortest_path(neta_timetable * timetable, int from_stop,
-				 int to_stop, int start_time, int min_change,
-				 int max_changes, int walking_change,
-				 neta_timetable_result * result)
-{
-    int i, j;
-    dglHeap_s heap;
-
-    int opt_conns, rows = 1;
-    if (max_changes != -1)
-	rows = max_changes + 2;
-
-    result->rows = rows;
-    result->dst = (int **)G_calloc(rows, sizeof(int *));
-    result->prev_stop = (int **)G_calloc(rows, sizeof(int *));
-    result->prev_route = (int **)G_calloc(rows, sizeof(int *));
-    result->prev_conn = (int **)G_calloc(rows, sizeof(int *));
-
-    if (!result->dst || !result->prev_stop || !result->prev_route ||
-	!result->prev_conn) {
-	G_warning(_("Out of memory"));
-	return -1;
-    }
-
-    for (i = 0; i < rows; i++) {
-	result->dst[i] = (int *)G_calloc(timetable->stops, sizeof(int));
-	result->prev_stop[i] = (int *)G_calloc(timetable->stops, sizeof(int));
-	result->prev_route[i] = (int *)G_calloc(timetable->stops, sizeof(int));
-	result->prev_conn[i] = (int *)G_calloc(timetable->stops, sizeof(int));
-	if (!result->dst[i] || !result->prev_stop[i] || !result->prev_route[i]
-	    || !result->prev_conn[i]) {
-	    G_warning(_("Out of memory"));
-	    return -1;
-	}
-    }
-
-    if (from_stop == to_stop) {
-	result->dst[0][to_stop] = start_time;
-	result->prev_route[0][to_stop] = result->prev_stop[0][to_stop] = -1;
-	result->routes = 0;
-	return start_time;
-    }
-
-    result->routes = -1;
-    if (walking_change > 1)
-	walking_change = 1;
-    if (walking_change < 0 || max_changes == -1)
-	walking_change = 0;
-    dglHeapInit(&heap);
-
-    for (i = 0; i < rows; i++)
-	for (j = 0; j < timetable->stops; j++)
-	    result->dst[i][j] = result->prev_stop[i][j] =
-		result->prev_route[i][j] = -1;
-
-    result->dst[0][from_stop] = start_time - min_change;
-    result->prev_stop[0][from_stop] = result->prev_route[0][from_stop] = -1;
-    dglHeapData_u heap_data;
-    heap_data.pv = (void *)new_heap_data(0, from_stop);
-    dglHeapInsertMin(&heap, start_time - min_change, ' ', heap_data);
-
-    while (1) {
-	dglInt32_t v, dist, conns;
-	dglHeapNode_s heap_node;
-	int new_conns, walk_conns, update;
-	if (!dglHeapExtractMin(&heap, &heap_node))
-	    break;
-	v = ((neta_heap_data *) (heap_node.value.pv))->v;
-	conns = ((neta_heap_data *) (heap_node.value.pv))->conns;
-	dist = heap_node.key;
-
-	if (dist > result->dst[conns][v])
-	    continue;
-	if (v == to_stop)
-	    break;
-	new_conns = (max_changes == -1) ? 0 : (conns + 1);
-	walk_conns = conns + walking_change;
-
-	/*walking */
-	if (walk_conns < rows) {
-	    /*            update = (max_changes == -1 || walk_conns <= max_changes); */
-	    update = 1;
-	    for (i = 0; i < timetable->walk_length[v]; i++) {
-		int to = timetable->walk_stops[v][i];
-		int new_dst = dist + timetable->walk_times[v][i];
-		NetA_update_dijkstra(conns, walk_conns, to, new_dst, v, -2,
-				     rows, update, result, &heap);
-	    }
-	}
-
-	if (new_conns >= rows)
-	    continue;
-	/*process all routes arriving after dist+min_change */
-	for (i = 0; i < timetable->stop_length[v]; i++)
-	    if (timetable->stop_times[v][i] >= dist + min_change) {
-		int route = timetable->stop_routes[v][i];
-		/*find the index of v on the route */
-		for (j = 0; j < timetable->route_length[route]; j++)
-		    if (timetable->route_stops[route][j] == v)
-			break;
-		j++;
-		for (; j < timetable->route_length[route]; j++) {
-		    int to = timetable->route_stops[route][j];
-		    NetA_update_dijkstra(conns, new_conns, to,
-					 timetable->route_times[route][j], v,
-					 route, rows, 1, result, &heap);
-		}
-	    }
-    }
-    dglHeapFree(&heap, NULL);
-    opt_conns = -1;
-    for (i = 0; i < rows; i++)
-	if (result->dst[i][to_stop] != -1 &&
-	    (opt_conns == -1 ||
-	     result->dst[opt_conns][to_stop] > result->dst[i][to_stop]))
-	    opt_conns = i;
-    result->routes = opt_conns;
-
-    if (opt_conns != -1)
-	return result->dst[opt_conns][to_stop];
-    return -1;
-}
-
-/*!
-  \brief Get time
-
-  Get time when route "route" arrives at stop "stop" or -1.
-
-  \param timetable pointer to neta_timetable structure
-  \param stop 'stop' node id
-  \param route route id
-
-  \return time
-  \return -1 if not found
-*/
-int NetA_timetable_get_route_time(neta_timetable * timetable, int stop,
-				  int route)
-{
-    int i;
-    for (i = 0; i < timetable->route_length[route]; i++)
-	if (timetable->route_stops[route][i] == stop)
-	    return timetable->route_times[route][i];
-    return -1;
-}
-
-/*!
-  \brief Free neta_timetable_result structure
-  
-  \param result pointer to neta_timetable_result structure
-*/
-void NetA_timetable_result_release(neta_timetable_result * result)
-{
-    int i;
-    for (i = 0; i < result->rows; i++) {
-	G_free(result->dst[i]);
-	G_free(result->prev_stop[i]);
-	G_free(result->prev_route[i]);
-    }
-    G_free(result->dst);
-    G_free(result->prev_stop);
-    G_free(result->prev_route);
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/timetables.c (from rev 41777, grass/trunk/lib/vector/neta/timetables.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/timetables.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/timetables.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,562 @@
+/*!
+   \file vector/neta/timetables.c
+
+   \brief Network Analysis library - timetables
+
+   Shortest path using timetables.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+#include <grass/neta.h>
+
+/*!
+   \brief Get number of distinct elements
+
+   \param driver DB driver
+   \param sql SQl string
+   \param[out] list of lengths
+   \param[out] list of ids
+
+   \return number of distinct elements 
+   \return -1 on failure
+ */
+int NetA_init_distinct(dbDriver * driver, dbString * sql, int **lengths,
+		       int **ids)
+{
+    int count, last, cur, result, index, more;
+    dbCursor cursor;
+    dbTable *table;
+    dbColumn *column;
+    dbValue *value;
+
+    if (db_open_select_cursor(driver, sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
+	G_warning(_("Unable to open select cursor: %s"), db_get_string(sql));
+	return -1;
+    }
+    /*TODO: check column types */
+
+    count = last = 0;
+    /*count number of distinct routes */
+    table = db_get_cursor_table(&cursor);
+    column = db_get_table_column(table, 0);
+    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
+	value = db_get_column_value(column);
+	cur = db_get_value_int(value);
+	if (count == 0 || cur != last) {
+	    last = cur;
+	    count++;
+	}
+    }
+    result = count;
+    db_close_cursor(&cursor);
+
+    *lengths = (int *)G_calloc(count, sizeof(int));
+    *ids = (int *)G_calloc(count, sizeof(int));
+    if (!*lengths || !*ids) {
+	G_warning(_("Out of memory"));
+	return -1;
+    }
+    db_open_select_cursor(driver, sql, &cursor, DB_SEQUENTIAL);
+    count = index = 0;
+    /*calculate the lengths of the routes */
+    table = db_get_cursor_table(&cursor);
+    column = db_get_table_column(table, 0);
+    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
+	value = db_get_column_value(column);
+	cur = db_get_value_int(value);
+	if (count != 0 && cur != last)
+	    index++;
+	if (count == 0 || cur != last)
+	    (*ids)[index] = cur;
+	(*lengths)[index]++;
+	last = cur;
+	count++;
+    }
+    return result;
+}
+
+static int cmp_int(const void *a, const void *b)
+{
+    return *(int *)a - *(int *)b;
+}
+
+/*!
+   \brief Initialises timetable from a database
+
+   \param In pointer to Map_info structure
+   \param route_layer layer number of routes
+   \param walk_layer layer number of walkers
+   \param route_id id of route
+   \param times list of timestamps
+   \param to_stop ?
+   \param walk_length walk length as string
+   \param timetable pointer to neta_timetable
+   \param route_ids list of route ids
+   \param stop_ids lits of stop ids
+
+   \return 0 on success
+   \return non-zero value on failure
+ */
+int NetA_init_timetable_from_db(struct Map_info *In, int route_layer,
+				int walk_layer, char *route_id, char *times,
+				char *to_stop, char *walk_length,
+				neta_timetable * timetable, int **route_ids,
+				int **stop_ids)
+{
+    int more, i, stop, route, time, *stop_pnt, stop1, stop2;
+    dbString sql;
+    dbCursor cursor;
+    dbTable *table;
+    dbColumn *column1, *column2, *column3;
+    dbValue *value;
+    char buf[2000];
+
+    dbDriver *driver;
+    struct field_info *Fi;
+
+    Fi = Vect_get_field(In, route_layer);
+    driver = db_start_driver_open_database(Fi->driver, Fi->database);
+    if (driver == NULL)
+	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+		      Fi->database, Fi->driver);
+
+
+    db_init_string(&sql);
+    sprintf(buf, "select %s from %s order by %s", route_id, Fi->table,
+	    route_id);
+    db_set_string(&sql, buf);
+    timetable->routes =
+	NetA_init_distinct(driver, &sql, &(timetable->route_length),
+			   route_ids);
+    if (timetable->routes < 0)
+	return 1;
+
+    sprintf(buf, "select %s from %s order by %s", Fi->key, Fi->table,
+	    Fi->key);
+    db_set_string(&sql, buf);
+    timetable->stops =
+	NetA_init_distinct(driver, &sql, &(timetable->stop_length), stop_ids);
+    if (timetable->stops < 0)
+	return 1;
+
+    timetable->route_stops =
+	(int **)G_calloc(timetable->routes, sizeof(int *));
+    timetable->route_times =
+	(int **)G_calloc(timetable->routes, sizeof(int *));
+    timetable->stop_routes =
+	(int **)G_calloc(timetable->stops, sizeof(int *));
+    timetable->stop_times = (int **)G_calloc(timetable->stops, sizeof(int *));
+    timetable->walk_length = (int *)G_calloc(timetable->stops, sizeof(int));
+    timetable->walk_stops = (int **)G_calloc(timetable->stops, sizeof(int *));
+    timetable->walk_times = (int **)G_calloc(timetable->stops, sizeof(int *));
+    if (!timetable->route_stops || !timetable->route_times ||
+	!timetable->stop_routes || !timetable->stop_times ||
+	!timetable->walk_length) {
+	G_warning(_("Out of memory"));
+	return 2;
+    }
+
+    for (i = 0; i < timetable->routes; i++) {
+	timetable->route_stops[i] =
+	    (int *)G_calloc(timetable->route_length[i], sizeof(int));
+	timetable->route_times[i] =
+	    (int *)G_calloc(timetable->route_length[i], sizeof(int));
+	if (!timetable->route_stops[i] || !timetable->route_times[i]) {
+	    G_warning(_("Out of memory"));
+	    return 2;
+	}
+
+	timetable->route_length[i] = 0;
+    }
+
+    for (i = 0; i < timetable->stops; i++) {
+	timetable->stop_routes[i] =
+	    (int *)G_calloc(timetable->stop_length[i], sizeof(int));
+	timetable->stop_times[i] =
+	    (int *)G_calloc(timetable->stop_length[i], sizeof(int));
+	if (!timetable->stop_routes[i] || !timetable->stop_times[i]) {
+	    G_warning(_("Out of memory"));
+	    return 2;
+	}
+	timetable->walk_length[i] = 0;
+	timetable->stop_length[i] = 0;
+    }
+
+    sprintf(buf, "select %s, %s, %s from %s order by %s", Fi->key, route_id,
+	    times, Fi->table, times);
+    db_set_string(&sql, buf);
+
+    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
+	G_warning(_("Unable to open select cursor: %s"), db_get_string(&sql));
+	return 1;
+    }
+
+
+    table = db_get_cursor_table(&cursor);
+    column1 = db_get_table_column(table, 0);
+    column2 = db_get_table_column(table, 1);
+    column3 = db_get_table_column(table, 2);
+    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
+	value = db_get_column_value(column1);
+	stop = db_get_value_int(value);
+	value = db_get_column_value(column2);
+	route = db_get_value_int(value);
+	value = db_get_column_value(column3);
+	time = db_get_value_int(value);
+	stop =
+	    (int *)bsearch(&stop, *stop_ids, timetable->stops, sizeof(int),
+			   cmp_int) - (*stop_ids);
+	route =
+	    (int *)bsearch(&route, *route_ids, timetable->routes, sizeof(int),
+			   cmp_int) - (*route_ids);
+
+	timetable->stop_routes[stop][timetable->stop_length[stop]] = route;
+	timetable->stop_times[stop][timetable->stop_length[stop]++] = time;
+
+	timetable->route_stops[route][timetable->route_length[route]] = stop;
+	timetable->route_times[route][timetable->route_length[route]++] =
+	    time;
+    }
+    db_close_cursor(&cursor);
+
+    if (walk_layer != -1) {
+
+	Fi = Vect_get_field(In, walk_layer);
+	sprintf(buf, "select %s, %s, %s from %s", Fi->key, to_stop,
+		walk_length, Fi->table);
+	db_set_string(&sql, buf);
+
+	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
+	    DB_OK) {
+	    G_warning(_("Unable to open select cursor: %s"),
+		      db_get_string(&sql));
+	    return 1;
+	}
+
+	table = db_get_cursor_table(&cursor);
+	column1 = db_get_table_column(table, 0);
+	column2 = db_get_table_column(table, 1);
+	while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
+	    value = db_get_column_value(column2);
+	    stop = db_get_value_int(value);
+	    stop_pnt =
+		(int *)bsearch(&stop, *stop_ids, timetable->stops,
+			       sizeof(int), cmp_int);
+	    if (stop_pnt) {
+		value = db_get_column_value(column1);
+		stop = db_get_value_int(value);
+		stop_pnt =
+		    (int *)bsearch(&stop, *stop_ids, timetable->stops,
+				   sizeof(int), cmp_int);
+		if (stop_pnt) {
+		    stop = stop_pnt - (*stop_ids);
+		    timetable->walk_length[stop]++;
+		}
+	    }
+	}
+	db_close_cursor(&cursor);
+
+	for (i = 0; i < timetable->stops; i++) {
+	    timetable->walk_stops[i] =
+		(int *)G_calloc(timetable->walk_length[i], sizeof(int));
+	    timetable->walk_times[i] =
+		(int *)G_calloc(timetable->walk_length[i], sizeof(int));
+	    if (!timetable->walk_stops[i] || !timetable->walk_times[i]) {
+		G_warning(_("Out of memory"));
+		return 2;
+	    }
+	    timetable->walk_length[i] = 0;
+	}
+
+	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
+	    DB_OK) {
+	    G_warning(_("Unable to open select cursor: %s"),
+		      db_get_string(&sql));
+	    return 1;
+	}
+
+	table = db_get_cursor_table(&cursor);
+	column1 = db_get_table_column(table, 0);
+	column2 = db_get_table_column(table, 1);
+	column3 = db_get_table_column(table, 2);
+	while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
+	    value = db_get_column_value(column2);
+	    stop = db_get_value_int(value);
+	    stop_pnt =
+		(int *)bsearch(&stop, *stop_ids, timetable->stops,
+			       sizeof(int), cmp_int);
+	    if (stop_pnt) {
+		stop2 = stop_pnt - (*stop_ids);
+		value = db_get_column_value(column1);
+		stop = db_get_value_int(value);
+		stop_pnt =
+		    (int *)bsearch(&stop, *stop_ids, timetable->stops,
+				   sizeof(int), cmp_int);
+		if (stop_pnt) {
+		    stop1 = stop_pnt - (*stop_ids);
+		    value = db_get_column_value(column3);
+		    time = db_get_value_int(value);
+		    timetable->walk_stops[stop1][timetable->
+						 walk_length[stop1]] = stop2;
+		    timetable->walk_times[stop1][timetable->
+						 walk_length[stop1]++] = time;
+		}
+	    }
+	}
+	db_close_cursor(&cursor);
+    }
+    db_close_database_shutdown_driver(driver);
+
+    return 0;
+}
+
+typedef struct
+{
+    int v;
+    int conns;
+} neta_heap_data;
+
+static neta_heap_data *new_heap_data(int conns, int v)
+{
+    neta_heap_data *d =
+	(neta_heap_data *) G_calloc(1, sizeof(neta_heap_data));
+    d->v = v;
+    d->conns = conns;
+    return d;
+}
+
+/*!
+   \brief Update Dijkstra structures
+
+   \param olc_conns old connection
+   \param new_conns new connection
+   \param to old 'to' node
+   \param new_dst new 'to' node
+   \param v ?
+   \param route id of route
+   \param rows ?
+   \param update ?
+   \param[out] result pointer to neta_timetable_result structure
+   \param heap ?
+ */
+void NetA_update_dijkstra(int old_conns, int new_conns, int to, int new_dst,
+			  int v, int route, int rows, int update,
+			  neta_timetable_result * result, dglHeap_s * heap)
+{
+    if (result->dst[new_conns][to] == -1 ||
+	result->dst[new_conns][to] > new_dst) {
+	result->dst[new_conns][to] = new_dst;
+	result->prev_stop[new_conns][to] = v;
+	result->prev_route[new_conns][to] = route;
+	result->prev_conn[new_conns][to] = old_conns;
+	if (update) {
+	    dglHeapData_u heap_data;
+
+	    heap_data.pv = (void *)new_heap_data(new_conns, to);
+	    dglHeapInsertMin(heap, new_dst, ' ', heap_data);
+	}
+    }
+}
+
+/*!
+   \brief Computes the earliest arrival time.
+
+   Computes the earliest arrival time to to_stop from from_stop
+   starting at start_time, or -1 if no path exists
+
+   \param timetable pointer to neta_timetable structure
+   \param from_stop 'from' node
+   \param to_stop 'to' stop
+   \param start_time start timestamp
+   \param min_change ?
+   \param max_changes ?
+   \param walking_change ?
+   \param[out] result pointer to neta_timetable_result
+
+   \return ?
+   \return -1 on error
+ */
+int NetA_timetable_shortest_path(neta_timetable * timetable, int from_stop,
+				 int to_stop, int start_time, int min_change,
+				 int max_changes, int walking_change,
+				 neta_timetable_result * result)
+{
+    int i, j;
+    dglHeap_s heap;
+
+    int opt_conns, rows = 1;
+
+    if (max_changes != -1)
+	rows = max_changes + 2;
+
+    result->rows = rows;
+    result->dst = (int **)G_calloc(rows, sizeof(int *));
+    result->prev_stop = (int **)G_calloc(rows, sizeof(int *));
+    result->prev_route = (int **)G_calloc(rows, sizeof(int *));
+    result->prev_conn = (int **)G_calloc(rows, sizeof(int *));
+
+    if (!result->dst || !result->prev_stop || !result->prev_route ||
+	!result->prev_conn) {
+	G_warning(_("Out of memory"));
+	return -1;
+    }
+
+    for (i = 0; i < rows; i++) {
+	result->dst[i] = (int *)G_calloc(timetable->stops, sizeof(int));
+	result->prev_stop[i] = (int *)G_calloc(timetable->stops, sizeof(int));
+	result->prev_route[i] =
+	    (int *)G_calloc(timetable->stops, sizeof(int));
+	result->prev_conn[i] = (int *)G_calloc(timetable->stops, sizeof(int));
+	if (!result->dst[i] || !result->prev_stop[i] || !result->prev_route[i]
+	    || !result->prev_conn[i]) {
+	    G_warning(_("Out of memory"));
+	    return -1;
+	}
+    }
+
+    if (from_stop == to_stop) {
+	result->dst[0][to_stop] = start_time;
+	result->prev_route[0][to_stop] = result->prev_stop[0][to_stop] = -1;
+	result->routes = 0;
+	return start_time;
+    }
+
+    result->routes = -1;
+    if (walking_change > 1)
+	walking_change = 1;
+    if (walking_change < 0 || max_changes == -1)
+	walking_change = 0;
+    dglHeapInit(&heap);
+
+    for (i = 0; i < rows; i++)
+	for (j = 0; j < timetable->stops; j++)
+	    result->dst[i][j] = result->prev_stop[i][j] =
+		result->prev_route[i][j] = -1;
+
+    result->dst[0][from_stop] = start_time - min_change;
+    result->prev_stop[0][from_stop] = result->prev_route[0][from_stop] = -1;
+    dglHeapData_u heap_data;
+
+    heap_data.pv = (void *)new_heap_data(0, from_stop);
+    dglHeapInsertMin(&heap, start_time - min_change, ' ', heap_data);
+
+    while (1) {
+	dglInt32_t v, dist, conns;
+	dglHeapNode_s heap_node;
+	int new_conns, walk_conns, update;
+
+	if (!dglHeapExtractMin(&heap, &heap_node))
+	    break;
+	v = ((neta_heap_data *) (heap_node.value.pv))->v;
+	conns = ((neta_heap_data *) (heap_node.value.pv))->conns;
+	dist = heap_node.key;
+
+	if (dist > result->dst[conns][v])
+	    continue;
+	if (v == to_stop)
+	    break;
+	new_conns = (max_changes == -1) ? 0 : (conns + 1);
+	walk_conns = conns + walking_change;
+
+	/*walking */
+	if (walk_conns < rows) {
+	    /*            update = (max_changes == -1 || walk_conns <= max_changes); */
+	    update = 1;
+	    for (i = 0; i < timetable->walk_length[v]; i++) {
+		int to = timetable->walk_stops[v][i];
+		int new_dst = dist + timetable->walk_times[v][i];
+
+		NetA_update_dijkstra(conns, walk_conns, to, new_dst, v, -2,
+				     rows, update, result, &heap);
+	    }
+	}
+
+	if (new_conns >= rows)
+	    continue;
+	/*process all routes arriving after dist+min_change */
+	for (i = 0; i < timetable->stop_length[v]; i++)
+	    if (timetable->stop_times[v][i] >= dist + min_change) {
+		int route = timetable->stop_routes[v][i];
+
+		/*find the index of v on the route */
+		for (j = 0; j < timetable->route_length[route]; j++)
+		    if (timetable->route_stops[route][j] == v)
+			break;
+		j++;
+		for (; j < timetable->route_length[route]; j++) {
+		    int to = timetable->route_stops[route][j];
+
+		    NetA_update_dijkstra(conns, new_conns, to,
+					 timetable->route_times[route][j], v,
+					 route, rows, 1, result, &heap);
+		}
+	    }
+    }
+    dglHeapFree(&heap, NULL);
+    opt_conns = -1;
+    for (i = 0; i < rows; i++)
+	if (result->dst[i][to_stop] != -1 &&
+	    (opt_conns == -1 ||
+	     result->dst[opt_conns][to_stop] > result->dst[i][to_stop]))
+	    opt_conns = i;
+    result->routes = opt_conns;
+
+    if (opt_conns != -1)
+	return result->dst[opt_conns][to_stop];
+    return -1;
+}
+
+/*!
+   \brief Get time
+
+   Get time when route "route" arrives at stop "stop" or -1.
+
+   \param timetable pointer to neta_timetable structure
+   \param stop 'stop' node id
+   \param route route id
+
+   \return time
+   \return -1 if not found
+ */
+int NetA_timetable_get_route_time(neta_timetable * timetable, int stop,
+				  int route)
+{
+    int i;
+
+    for (i = 0; i < timetable->route_length[route]; i++)
+	if (timetable->route_stops[route][i] == stop)
+	    return timetable->route_times[route][i];
+    return -1;
+}
+
+/*!
+   \brief Free neta_timetable_result structure
+
+   \param result pointer to neta_timetable_result structure
+ */
+void NetA_timetable_result_release(neta_timetable_result * result)
+{
+    int i;
+
+    for (i = 0; i < result->rows; i++) {
+	G_free(result->dst[i]);
+	G_free(result->prev_stop[i]);
+	G_free(result->prev_route[i]);
+    }
+    G_free(result->dst);
+    G_free(result->prev_stop);
+    G_free(result->prev_route);
+}

Deleted: grass/branches/develbranch_6/lib/vector/neta/utils.c
===================================================================
--- grass/trunk/lib/vector/neta/utils.c	2010-04-10 15:12:32 UTC (rev 41777)
+++ grass/branches/develbranch_6/lib/vector/neta/utils.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -1,238 +0,0 @@
-/*!
-  \file vector/neta/timetables.c
-  
-  \brief Network Analysis library - utils
-
-  Utils subroutines.
-  
-  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
-  
-  This program is free software under the GNU General Public License
-  (>=v2). Read the file COPYING that comes with GRASS for details.
-  
-  \author Daniel Bundala (Google Summer of Code 2009)
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/vector.h>
-#include <grass/glocale.h>
-#include <grass/dbmi.h>
-#include <grass/neta.h>
-
-
-/*!
-  \brief Writes point
-
-  Writes GV_POINT to Out at the position of the node in <em>In</em>.
-  
-  \param In pointer to Map_info structure (input vector map)
-  \param[in,out] Out pointer to Map_info structure (output vector map)
-  \param node node id
-  \param Cats pointer to line_cats structures
-*/
-void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
-			    struct line_cats *Cats)
-{
-    static struct line_pnts *Points;
-    double x, y, z;
-    Points = Vect_new_line_struct();
-    Vect_get_node_coor(In, node, &x, &y, &z);
-    Vect_reset_line(Points);
-    Vect_append_point(Points, x, y, z);
-    Vect_write_line(Out, GV_POINT, Points, Cats);
-    Vect_destroy_line_struct(Points);
-}
-
-/* Returns the list of all points with the given category and field */
-/*void NetA_get_points_by_category(struct Map_info *In, int field, int cat, struct ilist *point_list)
- * {
- * int i, nlines;
- * struct line_cats *Cats;
- * Cats = Vect_new_cats_struct();
- * Vect_get_num_lines(In);
- * for(i=1;i<=nlines;i++){
- * int type = Vect_read_line(In, NULL, Cats, i);
- * if(type!=GV_POINT)continue;
- * }
- * 
- * Vect_destroy_cats_struct(Cats);
- * }
- */
-
-/*!
-  \brief Finds node
-
-  Find the node corresponding to each point in the point_list
-  
-  \param In pointer to Map_info structure
-  \param point_list list of points (their ids)
-*/
-void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list)
-{
-    int i, node;
-    for (i = 0; i < point_list->n_values; i++) {
-	Vect_get_line_nodes(In, point_list->value[i], &node, NULL);
-	point_list->value[i] = node;
-    }
-}
-
-/*!
-  \brief Get node cost
-
-  For each node in the map, finds the category of the point on it (if
-  there is any) and stores the value associated with this category in
-  the array node_costs. If there is no point with a category,
-  node_costs=0.
-  
-  node_costs are multiplied by 1000000 and truncated to integers (as
-  is done in Vect_net_build_graph)
-  
-  \param In pointer to Map_info structure
-  \param layer layer number
-  \param column name of column
-  \param[out] node_costs list of node costs
-
-  \returns 1 on success
-  \return 0 on failure
- */
-int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
-			int *node_costs)
-{
-    int i, nlines, nnodes;
-    dbCatValArray vals;
-    struct line_cats *Cats;
-    struct line_pnts *Points;
-
-    dbDriver *driver;
-    struct field_info *Fi;
-    Fi = Vect_get_field(In, layer);
-    driver = db_start_driver_open_database(Fi->driver, Fi->database);
-    if (driver == NULL)
-	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
-		      Fi->database, Fi->driver);
-
-    nlines = Vect_get_num_lines(In);
-    nnodes = Vect_get_num_nodes(In);
-    Cats = Vect_new_cats_struct();
-    Points = Vect_new_line_struct();
-    for (i = 1; i <= nnodes; i++)
-	node_costs[i] = 0;
-
-    db_CatValArray_init(&vals);
-
-    if (db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals)
-	== -1)
-	return 0;
-    for (i = 1; i <= nlines; i++) {
-	int type = Vect_read_line(In, Points, Cats, i);
-	if (type == GV_POINT) {
-	    int node, cat;
-	    double value;
-	    if (!Vect_cat_get(Cats, layer, &cat))
-		continue;
-	    Vect_get_line_nodes(In, i, &node, NULL);
-	    if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK)
-		node_costs[node] = value * 1000000.0;
-	}
-    }
-
-    Vect_destroy_cats_struct(Cats);
-    db_CatValArray_free(&vals);
-    db_close_database_shutdown_driver(driver);
-    return 1;
-}
-
-/*!
-  \brief Get list of nodes from varray
-
-  Returns the list of all nodes on features selected by varray.
-  nodes_to_features conains the index of a feature adjecent to each
-  node or -1 if no such feature specified by varray
-  exists. Nodes_to_features might be NULL, in which case it is left
-  unitialised.
-
-  \param map pointer to Map_info structure
-  \param varray pointer to varray structure
-  \param[out] nodes list of node ids
-  \param node_to_features ?
-*/
-void NetA_varray_to_nodes(struct Map_info *map, struct varray * varray,
-			  struct ilist *nodes, int *nodes_to_features)
-{
-    int nlines, nnodes, i;
-    nlines = Vect_get_num_lines(map);
-    nnodes = Vect_get_num_nodes(map);
-    if (nodes_to_features)
-	for (i = 1; i <= nnodes; i++)
-	    nodes_to_features[i] = -1;
-
-    for (i = 1; i <= nlines; i++)
-	if (varray->c[i]) {
-	    int type = Vect_read_line(map, NULL, NULL, i);
-	    if (type == GV_POINT) {
-		int node;
-		Vect_get_line_nodes(map, i, &node, NULL);
-		Vect_list_append(nodes, node);
-		if (nodes_to_features)
-		    nodes_to_features[node] = i;
-	    }
-	    else {
-		int node1, node2;
-		Vect_get_line_nodes(map, i, &node1, &node2);
-		Vect_list_append(nodes, node1);
-		Vect_list_append(nodes, node2);
-		if (nodes_to_features)
-		    nodes_to_features[node1] = nodes_to_features[node2] = i;
-	    }
-	}
-}
-
-/*!
-  \brief Initialize varray
-
-  \param In pointer to Map_info structure
-  \param layer layer number
-  \param mask_type ?
-  \param where where statement
-  \param cat ?
-  \param[out] pointer to varray structure
-
-  \return ?
-*/
-int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
-			   char *where, char *cat, struct varray ** varray)
-{
-    /* parse filter option and select appropriate lines */
-    if (where) {
-	if (layer < 1)
-	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "where");
-	if (cat)
-	    G_warning(_
-		      ("'where' and 'cats' parameters were supplied, cat will be ignored"));
-	*varray = Vect_new_varray(Vect_get_num_lines(In));
-	if (Vect_set_varray_from_db
-	    (In, layer, where, mask_type, 1, *varray) == -1) {
-	    G_warning(_("Unable to load data from database"));
-	    return 0;
-	}
-	return 1;
-    }
-    else if (cat) {
-	if (layer < 1)
-	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "cat");
-	*varray = Vect_new_varray(Vect_get_num_lines(In));
-	if (Vect_set_varray_from_cat_string
-	    (In, layer, cat, mask_type, 1, *varray) == -1) {
-	    G_warning(_("Problem loading category values"));
-	    return 0;
-	}
-	return 1;
-    }
-    else {
-	return 2;
-    }
-
-
-}

Copied: grass/branches/develbranch_6/lib/vector/neta/utils.c (from rev 41777, grass/trunk/lib/vector/neta/utils.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/neta/utils.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/neta/utils.c	2010-04-10 18:00:54 UTC (rev 41783)
@@ -0,0 +1,246 @@
+/*!
+   \file vector/neta/timetables.c
+
+   \brief Network Analysis library - utils
+
+   Utils subroutines.
+
+   (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Daniel Bundala (Google Summer of Code 2009)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
+
+
+/*!
+   \brief Writes point
+
+   Writes GV_POINT to Out at the position of the node in <em>In</em>.
+
+   \param In pointer to Map_info structure (input vector map)
+   \param[in,out] Out pointer to Map_info structure (output vector map)
+   \param node node id
+   \param Cats pointer to line_cats structures
+ */
+void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out,
+			    int node, struct line_cats *Cats)
+{
+    static struct line_pnts *Points;
+    double x, y, z;
+
+    Points = Vect_new_line_struct();
+    Vect_get_node_coor(In, node, &x, &y, &z);
+    Vect_reset_line(Points);
+    Vect_append_point(Points, x, y, z);
+    Vect_write_line(Out, GV_POINT, Points, Cats);
+    Vect_destroy_line_struct(Points);
+}
+
+/* Returns the list of all points with the given category and field */
+/*void NetA_get_points_by_category(struct Map_info *In, int field, int cat, struct ilist *point_list)
+ * {
+ * int i, nlines;
+ * struct line_cats *Cats;
+ * Cats = Vect_new_cats_struct();
+ * Vect_get_num_lines(In);
+ * for(i=1;i<=nlines;i++){
+ * int type = Vect_read_line(In, NULL, Cats, i);
+ * if(type!=GV_POINT)continue;
+ * }
+ * 
+ * Vect_destroy_cats_struct(Cats);
+ * }
+ */
+
+/*!
+   \brief Finds node
+
+   Find the node corresponding to each point in the point_list
+
+   \param In pointer to Map_info structure
+   \param point_list list of points (their ids)
+ */
+void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list)
+{
+    int i, node;
+
+    for (i = 0; i < point_list->n_values; i++) {
+	Vect_get_line_nodes(In, point_list->value[i], &node, NULL);
+	point_list->value[i] = node;
+    }
+}
+
+/*!
+   \brief Get node cost
+
+   For each node in the map, finds the category of the point on it (if
+   there is any) and stores the value associated with this category in
+   the array node_costs. If there is no point with a category,
+   node_costs=0.
+
+   node_costs are multiplied by 1000000 and truncated to integers (as
+   is done in Vect_net_build_graph)
+
+   \param In pointer to Map_info structure
+   \param layer layer number
+   \param column name of column
+   \param[out] node_costs list of node costs
+
+   \returns 1 on success
+   \return 0 on failure
+ */
+int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
+			int *node_costs)
+{
+    int i, nlines, nnodes;
+    dbCatValArray vals;
+    struct line_cats *Cats;
+    struct line_pnts *Points;
+
+    dbDriver *driver;
+    struct field_info *Fi;
+
+    Fi = Vect_get_field(In, layer);
+    driver = db_start_driver_open_database(Fi->driver, Fi->database);
+    if (driver == NULL)
+	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+		      Fi->database, Fi->driver);
+
+    nlines = Vect_get_num_lines(In);
+    nnodes = Vect_get_num_nodes(In);
+    Cats = Vect_new_cats_struct();
+    Points = Vect_new_line_struct();
+    for (i = 1; i <= nnodes; i++)
+	node_costs[i] = 0;
+
+    db_CatValArray_init(&vals);
+
+    if (db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals)
+	== -1)
+	return 0;
+    for (i = 1; i <= nlines; i++) {
+	int type = Vect_read_line(In, Points, Cats, i);
+
+	if (type == GV_POINT) {
+	    int node, cat;
+	    double value;
+
+	    if (!Vect_cat_get(Cats, layer, &cat))
+		continue;
+	    Vect_get_line_nodes(In, i, &node, NULL);
+	    if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK)
+		node_costs[node] = value * 1000000.0;
+	}
+    }
+
+    Vect_destroy_cats_struct(Cats);
+    db_CatValArray_free(&vals);
+    db_close_database_shutdown_driver(driver);
+    return 1;
+}
+
+/*!
+   \brief Get list of nodes from varray
+
+   Returns the list of all nodes on features selected by varray.
+   nodes_to_features conains the index of a feature adjecent to each
+   node or -1 if no such feature specified by varray
+   exists. Nodes_to_features might be NULL, in which case it is left
+   unitialised.
+
+   \param map pointer to Map_info structure
+   \param varray pointer to varray structure
+   \param[out] nodes list of node ids
+   \param node_to_features ?
+ */
+void NetA_varray_to_nodes(struct Map_info *map, struct varray *varray,
+			  struct ilist *nodes, int *nodes_to_features)
+{
+    int nlines, nnodes, i;
+
+    nlines = Vect_get_num_lines(map);
+    nnodes = Vect_get_num_nodes(map);
+    if (nodes_to_features)
+	for (i = 1; i <= nnodes; i++)
+	    nodes_to_features[i] = -1;
+
+    for (i = 1; i <= nlines; i++)
+	if (varray->c[i]) {
+	    int type = Vect_read_line(map, NULL, NULL, i);
+
+	    if (type == GV_POINT) {
+		int node;
+
+		Vect_get_line_nodes(map, i, &node, NULL);
+		Vect_list_append(nodes, node);
+		if (nodes_to_features)
+		    nodes_to_features[node] = i;
+	    }
+	    else {
+		int node1, node2;
+
+		Vect_get_line_nodes(map, i, &node1, &node2);
+		Vect_list_append(nodes, node1);
+		Vect_list_append(nodes, node2);
+		if (nodes_to_features)
+		    nodes_to_features[node1] = nodes_to_features[node2] = i;
+	    }
+	}
+}
+
+/*!
+   \brief Initialize varray
+
+   \param In pointer to Map_info structure
+   \param layer layer number
+   \param mask_type ?
+   \param where where statement
+   \param cat ?
+   \param[out] pointer to varray structure
+
+   \return ?
+ */
+int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
+			   char *where, char *cat, struct varray **varray)
+{
+    /* parse filter option and select appropriate lines */
+    if (where) {
+	if (layer < 1)
+	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "where");
+	if (cat)
+	    G_warning(_("'where' and 'cats' parameters were supplied, cat will be ignored"));
+	*varray = Vect_new_varray(Vect_get_num_lines(In));
+	if (Vect_set_varray_from_db
+	    (In, layer, where, mask_type, 1, *varray) == -1) {
+	    G_warning(_("Unable to load data from database"));
+	    return 0;
+	}
+	return 1;
+    }
+    else if (cat) {
+	if (layer < 1)
+	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "cat");
+	*varray = Vect_new_varray(Vect_get_num_lines(In));
+	if (Vect_set_varray_from_cat_string
+	    (In, layer, cat, mask_type, 1, *varray) == -1) {
+	    G_warning(_("Problem loading category values"));
+	    return 0;
+	}
+	return 1;
+    }
+    else {
+	return 2;
+    }
+
+
+}



More information about the grass-commit mailing list