[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(¤t[i], graph,
- dglNodeGet_OutEdgeset(graph,
- dglGetNode(graph, i)));
- current_edge[i] = dglEdgeset_T_First(¤t[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(¤t[node_id]); /*proceed to the next edge */
- }
- for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[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(¤t[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(¤t[i], graph,
+ dglNodeGet_OutEdgeset(graph,
+ dglGetNode(graph, i)));
+ current_edge[i] = dglEdgeset_T_First(¤t[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(¤t[node_id]); /*proceed to the next edge */
+ }
+ for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[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(¤t[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(¤t[i], graph,
+ dglNodeGet_OutEdgeset(graph,
+ dglGetNode(graph, i)));
+ current_edge[i] = dglEdgeset_T_First(¤t[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(¤t[node_id]); /*proceed to the next edge */
+ }
+ for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(¤t[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(¤t[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