[GRASS-SVN] r37383 - in grass-addons/vector/net.analyze: . netalib v.net.bridge v.net.components v.net.spanningtree

svn_grass at osgeo.org svn_grass at osgeo.org
Fri May 22 18:43:38 EDT 2009


Author: dano
Date: 2009-05-22 18:43:38 -0400 (Fri, 22 May 2009)
New Revision: 37383

Added:
   grass-addons/vector/net.analyze/Makefile
   grass-addons/vector/net.analyze/netalib/Makefile
   grass-addons/vector/net.analyze/netalib/neta.h
   grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c
   grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c
   grass-addons/vector/net.analyze/v.net.components/neta_comonents.c
   grass-addons/vector/net.analyze/v.net.spanningtree/
   grass-addons/vector/net.analyze/v.net.spanningtree/Makefile
   grass-addons/vector/net.analyze/v.net.spanningtree/main.c
   grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
Removed:
   grass-addons/vector/net.analyze/v.net.bridge/bridge.c
   grass-addons/vector/net.analyze/v.net.components/components.c
Modified:
   grass-addons/vector/net.analyze/v.net.bridge/Makefile
   grass-addons/vector/net.analyze/v.net.bridge/main.c
   grass-addons/vector/net.analyze/v.net.components/Makefile
   grass-addons/vector/net.analyze/v.net.components/main.c
Log:
New module: v.net.spanningtree, v.net.bridge computes articulation points now, bug fixes

Added: grass-addons/vector/net.analyze/Makefile
===================================================================
--- grass-addons/vector/net.analyze/Makefile	                        (rev 0)
+++ grass-addons/vector/net.analyze/Makefile	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,17 @@
+MODULE_TOPDIR = ../..
+
+SUBDIRS1 = \
+	v.net.components \
+        v.net.bridge \
+        v.net.spanningtree
+
+SUBDIRS = netalib $(SUBDIRS1)
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default: parsubdirs
+
+clean: cleansubdirs
+
+$(SUBDIRS1): netalib
+


Property changes on: grass-addons/vector/net.analyze/Makefile
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/netalib/Makefile
===================================================================
--- grass-addons/vector/net.analyze/netalib/Makefile	                        (rev 0)
+++ grass-addons/vector/net.analyze/netalib/Makefile	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,15 @@
+MODULE_TOPDIR = ../../..
+
+EXTRA_LIBS = $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB) 
+DEPENDENCIES= $(VECTDEP) $(DBMIDEP) $(GISDEP) 
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+LIB_NAME = $(NETA_LIBNAME)
+
+include $(MODULE_TOPDIR)/include/Make/Lib.make
+
+default: $(ARCH_INCDIR)/neta.h lib
+
+$(ARCH_INCDIR)/neta.h: neta.h
+	cp neta.h $(ARCH_INCDIR)/neta.h


Property changes on: grass-addons/vector/net.analyze/netalib/Makefile
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/netalib/neta.h
===================================================================
--- grass-addons/vector/net.analyze/netalib/neta.h	                        (rev 0)
+++ grass-addons/vector/net.analyze/netalib/neta.h	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,39 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    NETwork Analysis Library
+ *
+ * COPYRIGHT:  (C) 2002-2005 by 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/glocale.h>
+#include <grass/dgl/graph.h>
+
+/*neta_bridge.c*/
+int neta_compute_bridges(struct dglGraph_s *graph, struct ilist *bridge_list);
+int neta_articulation_points(struct dglGraph_s *graph, struct ilist *articulation_list);
+
+/*neta_components.c*/
+int neta_weakly_connected_components(struct dglGraph_s *graph, int *component);
+int neta_strongly_connected_components(struct dglGraph_s *graph, int *component);
+
+/*neta_spanningtree.c*/
+int neta_spanning_tree(struct dglGraph_s *graph, struct ilist *tree_list);
+#endif


Property changes on: grass-addons/vector/net.analyze/netalib/neta.h
___________________________________________________________________
Name: svn:executable
   + *

Modified: grass-addons/vector/net.analyze/v.net.bridge/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/Makefile	2009-05-22 21:30:06 UTC (rev 37382)
+++ grass-addons/vector/net.analyze/v.net.bridge/Makefile	2009-05-22 22:43:38 UTC (rev 37383)
@@ -1,10 +1,9 @@
-
 MODULE_TOPDIR = ../../..
 
 PGM=v.net.bridge
 
-LIBES     = $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
-DEPENDENCIES = $(VECTDEP) $(DBMIDEP) $(GISDEP)
+LIBES     = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
+DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
 EXTRA_INC = $(VECT_INC)
 EXTRA_CFLAGS = $(VECT_CFLAGS)
  

Deleted: grass-addons/vector/net.analyze/v.net.bridge/bridge.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/bridge.c	2009-05-22 21:30:06 UTC (rev 37382)
+++ grass-addons/vector/net.analyze/v.net.bridge/bridge.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -1,125 +0,0 @@
-
-/****************************************************************
- *
- * MODULE:     v.net.components
- *
- * AUTHOR(S):  Daniel Bundala
- *
- * PURPOSE:    Computes strongly and weakly connected components
- *
- * COPYRIGHT:  (C) 2002-2005 by 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.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-
-/* return the number of bridges in the graph.
- * bridge is an array containing the indices of the bridges
- */
-int compute_bridges(struct 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;	/*parents of the nodes */
-    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] = 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 */
-			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]);
-		    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 (min_tin[to_id] < min_tin[node_id])
-			    min_tin[node_id] = min_tin[to_id];
-		    }
-		    else {	/*forward edge */
-			parent[to_id] = node;
-			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;
-}

Modified: grass-addons/vector/net.analyze/v.net.bridge/main.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/main.c	2009-05-22 21:30:06 UTC (rev 37382)
+++ grass-addons/vector/net.analyze/v.net.bridge/main.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -1,7 +1,7 @@
 
 /****************************************************************
  *
- * MODULE:     v.net.components
+ * MODULE:     v.net.bridge
  *
  * AUTHOR(S):  Daniel Bundala
  *
@@ -21,9 +21,8 @@
 #include <grass/gis.h>
 #include <grass/Vect.h>
 #include <grass/glocale.h>
+#include <grass/neta.h>
 
-int compute_bridges(struct dglGraph_s *graph, struct ilist *bridge_list);
-
 int main(int argc, char *argv[])
 {
     struct Map_info In, Out;
@@ -32,13 +31,13 @@
     char *mapset;
     struct GModule *module;	/* GRASS module for parsing arguments */
     struct Option *map_in, *map_out;
-    struct Option *cat_opt, *field_opt, *where_opt;
+    struct Option *cat_opt, *field_opt, *where_opt, *method_opt;
     int chcat, with_z;
     int layer, mask_type;
     VARRAY *varray;
     dglGraph_s *graph;
-    int i, bridges;
-    struct ilist *bridge_list;
+    int i, bridges, articulations;
+    struct ilist *bridge_list, *articulation_list;
 
     /* initialize GIS environment */
     G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
@@ -56,6 +55,16 @@
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     where_opt = G_define_standard_option(G_OPT_WHERE);
 
+    method_opt = G_define_option();
+    method_opt->key = "method";
+    method_opt->type = TYPE_STRING;
+    method_opt->required = YES;
+    method_opt->multiple = NO;
+    method_opt->options = "bridge,articulation";
+    method_opt->descriptions = _("bridge;Find bridges;"
+				 "articulation;Finds articulation points;");
+    method_opt->description = _("Feature type");
+
     /* options and flags parser */
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
@@ -117,22 +126,40 @@
 
     Vect_net_build_graph(&In, mask_type, 0, 0, NULL, NULL, NULL, 0, 0);
     graph = &(In.graph);
-    bridge_list = Vect_new_list();
-    bridges = compute_bridges(graph, bridge_list);
 
-    G_debug(3, "Bridges: %d\n", bridges);
-
     Vect_copy_head_data(&In, &Out);
     Vect_hist_copy(&In, &Out);
     Vect_hist_command(&Out);
 
-    for (i = 0; i < bridges; i++) {
-	int type =
-	    Vect_read_line(&In, Points, Cats, abs(bridge_list->value[i]));
-	Vect_write_line(&Out, type, Points, Cats);
+    if (method_opt->answer[0] == 'b') {
+	bridge_list = Vect_new_list();
+	bridges = neta_compute_bridges(graph, bridge_list);
+
+	G_debug(3, "Bridges: %d", bridges);
+
+	for (i = 0; i < bridges; i++) {
+	    int type =
+		Vect_read_line(&In, Points, Cats, abs(bridge_list->value[i]));
+	    Vect_write_line(&Out, type, Points, Cats);
+	}
+	Vect_destroy_list(bridge_list);
     }
-    Vect_destroy_list(bridge_list);
+    else {
+	articulation_list = Vect_new_list();
+	articulations = neta_articulation_points(graph, articulation_list);
+	G_debug(3, "Articulation points: %d", articulations);
 
+	for (i = 0; i < articulations; i++) {
+	    double x, y, z;
+	    Vect_get_node_coor(&In, articulation_list->value[i], &x, &y, &z);
+	    Vect_reset_line(Points);
+	    Vect_append_point(Points, x, y, z);
+	    Vect_write_line(&Out, GV_POINT, Points, Cats);
+	}
+
+	Vect_destroy_list(articulation_list);
+    }
+
     Vect_build(&Out);
 
     Vect_close(&In);

Added: grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,139 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes strongly and weakly connected components
+ *
+ * COPYRIGHT:  (C) 2002-2005 by 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.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/* return the number of articulation points in the graph.
+ */
+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;
+}


Property changes on: grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,128 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes strongly and weakly connected components
+ *
+ * COPYRIGHT:  (C) 2002-2005 by 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.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+/* return the number of bridges in the graph.
+ * bridge is an array containing the indices of the bridges
+ */
+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;
+}


Property changes on: grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c
___________________________________________________________________
Name: svn:executable
   + *

Modified: grass-addons/vector/net.analyze/v.net.components/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/Makefile	2009-05-22 21:30:06 UTC (rev 37382)
+++ grass-addons/vector/net.analyze/v.net.components/Makefile	2009-05-22 22:43:38 UTC (rev 37383)
@@ -3,8 +3,8 @@
 
 PGM=v.net.components
 
-LIBES     = $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
-DEPENDENCIES = $(VECTDEP) $(DBMIDEP) $(GISDEP)
+LIBES     = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
+DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
 EXTRA_INC = $(VECT_INC)
 EXTRA_CFLAGS = $(VECT_CFLAGS)
  

Deleted: grass-addons/vector/net.analyze/v.net.components/components.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/components.c	2009-05-22 21:30:06 UTC (rev 37382)
+++ grass-addons/vector/net.analyze/v.net.components/components.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -1,174 +0,0 @@
-
-/****************************************************************
- *
- * MODULE:     v.net.components
- *
- * AUTHOR(S):  Daniel Bundala
- *
- * PURPOSE:    Computes strongly and weakly connected components
- *
- * COPYRIGHT:  (C) 2002-2005 by 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.
- *
- ****************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/Vect.h>
-#include <grass/glocale.h>
-
-int weakly_connected_components(struct 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;
-}
-
-int strongly_connected_components(struct 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;
-}

Modified: grass-addons/vector/net.analyze/v.net.components/main.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/main.c	2009-05-22 21:30:06 UTC (rev 37382)
+++ grass-addons/vector/net.analyze/v.net.components/main.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -21,10 +21,26 @@
 #include <grass/gis.h>
 #include <grass/Vect.h>
 #include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
 
-int weakly_connected_components(struct dglGraph_s *graph, int *component);
-int strongly_connected_components(struct dglGraph_s *graph, int *component);
+int insert_new_record(dbDriver * driver, struct field_info *Fi, dbString * sql,
+		      int cat, int comp)
+{
+    char buf[2000];
+    sprintf(buf, "insert into %s values (%d, %d)", Fi->table, cat, comp);
+    db_set_string(sql, buf);
+    G_debug(3, db_get_string(sql));
 
+    if (db_execute_immediate(driver, sql) != DB_OK) {
+	db_close_database_shutdown_driver(driver);
+	G_fatal_error(_("Cannot insert new record: %s"), db_get_string(sql));
+	return 0;
+    };
+    return 1;
+}
+
+
 int main(int argc, char *argv[])
 {
     struct Map_info In, Out;
@@ -38,8 +54,14 @@
     int layer, mask_type;
     VARRAY *varray;
     dglGraph_s *graph;
-    int *component, nnodes, type, i, nlines, components;
+    int *component, nnodes, type, i, nlines, components, j, max_cat;
+    char buf[2000], *covered;
 
+    /* Attribute table */
+    dbString sql;
+    dbDriver *driver;
+    struct field_info *Fi;
+
     /* initialize GIS environment */
     G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
 
@@ -130,16 +152,46 @@
     graph = &(In.graph);
     nnodes = Vect_get_num_nodes(&In);
     component = (int *)G_calloc(nnodes + 1, sizeof(int));
-    if (!component) {
+    covered = (char *)G_calloc(nnodes + 1, sizeof(char));
+    if (!component || !covered) {
 	G_fatal_error(_("Out of memory"));
 	exit(EXIT_FAILURE);
     }
+    /* Create table */
+    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
+    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, "cat", Fi->database,
+			Fi->driver);
+
+    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);
+
+    sprintf(buf, "create table %s ( cat integer, comp integer)", Fi->table);
+
+    db_set_string(&sql, buf);
+    G_debug(2, db_get_string(&sql));
+
+    if (db_execute_immediate(driver, &sql) != DB_OK) {
+	db_close_database_shutdown_driver(driver);
+	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
+    }
+
+    if (db_create_index2(driver, Fi->table, "cat") != DB_OK)
+	G_warning(_("Cannot create index"));
+
+    if (db_grant_on_table
+	(driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
+	G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table);
+
+    db_begin_transaction(driver);
+
     if (method_opt->answer[0] == 'w')
-	components = weakly_connected_components(graph, component);
+	components = neta_weakly_connected_components(graph, component);
     else
-	components = strongly_connected_components(graph, component);
+	components = neta_strongly_connected_components(graph, component);
 
-    G_debug(3, "Components: %d\n", components);
+    G_debug(3, "Components: %d", components);
 
     Vect_copy_head_data(&In, &Out);
     Vect_hist_copy(&In, &Out);
@@ -147,13 +199,13 @@
 
     nlines = Vect_get_num_lines(&In);
     for (i = 1; i <= nlines; i++) {
-	type = Vect_read_line(&In, Points, NULL, i);
-	Vect_reset_cats(Cats);
+	int comp;
+	type = Vect_read_line(&In, Points, Cats, i);
 	if (type == GV_LINE || type == GV_BOUNDARY) {
 	    int node1, node2;
 	    Vect_get_line_nodes(&In, i, &node1, &node2);
 	    if (component[node1] == component[node2]) {
-		Vect_cat_set(Cats, 1, component[node1]);
+		comp = component[node1];
 	    }
 	    else {
 		continue;
@@ -162,12 +214,40 @@
 	else if (type == GV_POINT) {
 	    int node;
 	    Vect_get_line_nodes(&In, i, &node, NULL);
-	    Vect_cat_set(Cats, 1, component[node]);
+	    comp = component[node];
+	    covered[node] = 1;
 	}
 	else
 	    continue;
 	Vect_write_line(&Out, type, Points, Cats);
+	for (j = 0; j < Cats->n_cats; j++)
+	    insert_new_record(driver, Fi, &sql, Cats->cat[j], comp);
     };
+    /*add points on nodes not covered by any point in the network */
+    /*find the maximum cat number */
+    /*TODO: Do we want a flag for this? */
+    max_cat = 0;
+    for (i = 1; i <= nlines; i++) {
+	Vect_read_line(&In, NULL, Cats, i);
+	for (j = 0; j < Cats->n_cats; j++)
+	    if (Cats->cat[j] > max_cat)
+		max_cat = Cats->cat[j];
+    }
+    max_cat++;
+    printf("Max cat %d\n", max_cat);
+    for (i = 1; i <= nnodes; i++)
+	if (!covered[i]) {
+	    double x, y, z;
+	    Vect_reset_cats(Cats);
+	    Vect_cat_set(Cats, 1, max_cat);
+	    Vect_get_node_coor(&In, i, &x, &y, &z);
+	    Vect_reset_line(Points);
+	    Vect_append_point(Points, x, y, z);
+	    Vect_write_line(&Out, GV_POINT, Points, Cats);
+	    insert_new_record(driver, Fi, &sql, max_cat++, component[i]);
+	}
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
 
     Vect_build(&Out);
 

Added: grass-addons/vector/net.analyze/v.net.components/neta_comonents.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/neta_comonents.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.components/neta_comonents.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,175 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.components
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes strongly and weakly connected components
+ *
+ * COPYRIGHT:  (C) 2002-2005 by 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.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/dgl/graph.h>
+
+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;
+}
+
+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;
+}


Property changes on: grass-addons/vector/net.analyze/v.net.components/neta_comonents.c
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/v.net.spanningtree/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.spanningtree/Makefile	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.spanningtree/Makefile	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,13 @@
+MODULE_TOPDIR = ../../..
+
+PGM=v.net.spanningtree
+
+LIBES     = $(NETALIB) $(VECTLIB) $(VECTLIB_REAL) $(DBMILIB) $(GISLIB)
+DEPENDENCIES = $(NETADEP) $(VECTDEP) $(DBMIDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+ 
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	
+


Property changes on: grass-addons/vector/net.analyze/v.net.spanningtree/Makefile
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/v.net.spanningtree/main.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.spanningtree/main.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.spanningtree/main.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,159 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.spanningtree
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes spanning tree in the network
+ *
+ * COPYRIGHT:  (C) 2002-2005 by 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.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include <grass/neta.h>
+
+int main(int argc, char *argv[])
+{
+    struct Map_info In, Out;
+    static struct line_pnts *Points;
+    struct line_cats *Cats;
+    char *mapset;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out;
+    struct Option *cat_opt, *field_opt, *where_opt, *accol;
+    struct Flag *geo_f;
+    int chcat, with_z;
+    int layer, mask_type;
+    VARRAY *varray;
+    dglGraph_s *graph;
+    int i, edges, geo;
+    struct ilist *tree_list;
+
+    /* initialize GIS environment */
+    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
+
+    /* initialize module */
+    module = G_define_module();
+    module->keywords = _("network, spanning tree");
+    module->description = _("Computes spanning.");
+
+    /* Define the different options as defined in gis.h */
+    map_in = G_define_standard_option(G_OPT_V_INPUT);
+    map_out = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    field_opt = G_define_standard_option(G_OPT_V_FIELD);
+    cat_opt = G_define_standard_option(G_OPT_V_CATS);
+    where_opt = G_define_standard_option(G_OPT_WHERE);
+
+    accol = G_define_option();
+    accol->key = "accol";
+    accol->type = TYPE_STRING;
+    accol->required = NO;
+    accol->description = _("Arc cost column");
+
+    geo_f = G_define_flag();
+    geo_f->key = 'g';
+    geo_f->description =
+	_("Use geodesic calculation for longitude-latitude locations");
+
+    /* options and flags parser */
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+    /* TODO: make an option for this */
+    mask_type = GV_LINE | GV_BOUNDARY;
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    Vect_check_input_output_name(map_in->answer, map_out->answer,
+				 GV_FATAL_EXIT);
+
+    if ((mapset = G_find_vector2(map_in->answer, "")) == NULL)
+	G_fatal_error(_("Vector map <%s> not found"), map_in->answer);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, mapset))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      G_fully_qualified_name(map_in->answer, mapset));
+
+    with_z = Vect_is_3d(&In);
+
+    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
+	Vect_close(&In);
+	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
+    }
+
+    if (geo_f->answer) {
+	geo = 1;
+	if (G_projection() != PROJECTION_LL)
+	    G_warning(_("The current projection is not longitude-latitude"));
+    }
+    else
+	geo = 0;
+
+    /* parse filter option and select appropriate lines */
+    layer = atoi(field_opt->answer);
+    if (where_opt->answer) {
+	if (layer < 1)
+	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "where");
+	if (cat_opt->answer)
+	    G_warning(_
+		      ("'where' and 'cats' parameters were supplied, cat will be ignored"));
+	chcat = 1;
+	varray = Vect_new_varray(Vect_get_num_lines(&In));
+	if (Vect_set_varray_from_db
+	    (&In, layer, where_opt->answer, mask_type, 1, varray) == -1) {
+	    G_warning(_("Unable to load data from database"));
+	}
+    }
+    else if (cat_opt->answer) {
+	if (layer < 1)
+	    G_fatal_error(_("'%s' must be > 0 for '%s'"), "layer", "cat");
+	varray = Vect_new_varray(Vect_get_num_lines(&In));
+	chcat = 1;
+	if (Vect_set_varray_from_cat_string
+	    (&In, layer, cat_opt->answer, mask_type, 1, varray) == -1) {
+	    G_warning(_("Problem loading category values"));
+	}
+    }
+    else {
+	chcat = 0;
+	varray = NULL;
+    }
+
+    Vect_net_build_graph(&In, mask_type, atoi(field_opt->answer), 0,
+			 accol->answer, NULL, NULL, geo, 0);
+    graph = &(In.graph);
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+    Vect_hist_command(&Out);
+
+    tree_list = Vect_new_list();
+    edges = neta_spanning_tree(graph, tree_list);
+    G_debug(3, "Edges: %d\n", edges);
+    for (i = 0; i < edges; i++) {
+	int type = Vect_read_line(&In, Points, Cats, abs(tree_list->value[i]));
+	Vect_write_line(&Out, type, Points, Cats);
+    }
+    Vect_destroy_list(tree_list);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/vector/net.analyze/v.net.spanningtree/main.c
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c	2009-05-22 22:43:38 UTC (rev 37383)
@@ -0,0 +1,133 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes strongly and weakly connected components
+ *
+ * COPYRIGHT:  (C) 2002-2005 by 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.
+ *
+ ****************************************************************/
+
+#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;
+};
+
+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;
+}
+
+void uf_release(struct union_find *uf)
+{
+    G_free(uf->parent);
+}
+
+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 */
+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;
+
+int cmp_edge(const void *pa, const void *pb)
+{
+    return ((edge_cost_pair *) pa)->cost - ((edge_cost_pair *) pb)->cost;
+}
+
+/* return the number of edges in the spanning forest */
+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;
+}


Property changes on: grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
___________________________________________________________________
Name: svn:executable
   + *



More information about the grass-commit mailing list