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

svn_grass at osgeo.org svn_grass at osgeo.org
Thu May 28 10:06:36 EDT 2009


Author: dano
Date: 2009-05-28 10:06:36 -0400 (Thu, 28 May 2009)
New Revision: 37571

Added:
   grass-addons/vector/net.analyze/v.net.allpairs/
   grass-addons/vector/net.analyze/v.net.allpairs/Makefile
   grass-addons/vector/net.analyze/v.net.allpairs/main.c
   grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c
   grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c
   grass-addons/vector/net.analyze/v.net.flow/
   grass-addons/vector/net.analyze/v.net.flow/Makefile
   grass-addons/vector/net.analyze/v.net.flow/main.c
   grass-addons/vector/net.analyze/v.net.flow/neta_flow.c
   grass-addons/vector/net.analyze/v.net.flow/neta_utils.c
Modified:
   grass-addons/vector/net.analyze/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/main.c
   grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
Log:
New modules: v.net.allpairs, v.net.flow

Modified: grass-addons/vector/net.analyze/Makefile
===================================================================
--- grass-addons/vector/net.analyze/Makefile	2009-05-28 13:44:03 UTC (rev 37570)
+++ grass-addons/vector/net.analyze/Makefile	2009-05-28 14:06:36 UTC (rev 37571)
@@ -3,7 +3,9 @@
 SUBDIRS1 = \
 	v.net.components \
         v.net.bridge \
-        v.net.spanningtree
+        v.net.spanningtree \
+        v.net.allpairs \
+        v.net.flow
 
 SUBDIRS = netalib $(SUBDIRS1)
 

Modified: grass-addons/vector/net.analyze/netalib/neta.h
===================================================================
--- grass-addons/vector/net.analyze/netalib/neta.h	2009-05-28 13:44:03 UTC (rev 37570)
+++ grass-addons/vector/net.analyze/netalib/neta.h	2009-05-28 14:06:36 UTC (rev 37571)
@@ -27,13 +27,22 @@
 #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);
+int neta_compute_bridges(dglGraph_s *graph, struct ilist *bridge_list);
+int neta_articulation_points(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);
+int neta_weakly_connected_components(dglGraph_s *graph, int *component);
+int neta_strongly_connected_components(dglGraph_s *graph, int *component);
 
 /*neta_spanningtree.c*/
-int neta_spanning_tree(struct dglGraph_s *graph, struct ilist *tree_list);
+int neta_spanning_tree(dglGraph_s *graph, struct ilist *tree_list);
+
+/*neta_allpairs.c*/
+int neta_allpairs(dglGraph_s *graph, dglInt32_t **dist);
+
+/*neta_utils.c*/
+void neta_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node, struct line_cats *Cats);
+
+/*neta_flow.c*/
+int neta_flow(dglGraph_s *graph, int source, int sink, int *flow);
 #endif

Added: grass-addons/vector/net.analyze/v.net.allpairs/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/Makefile	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.allpairs/Makefile	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,13 @@
+MODULE_TOPDIR = ../../..
+
+PGM=v.net.allpairs
+
+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.allpairs/Makefile
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/v.net.allpairs/main.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/main.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.allpairs/main.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,266 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.allpairs
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Shortest paths between all nodes
+ *
+ * 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/dbmi.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, *abcol, *afcol;
+    struct Flag *geo_f, *newpoints_f;
+    int chcat, with_z;
+    int layer, mask_type;
+    VARRAY *varray;
+    dglGraph_s *graph;
+    int i, j, geo, nnodes, nlines, max_cat, *cats;
+    dglInt32_t **dist;
+    char buf[2000];
+
+    /* 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() */
+
+    /* initialize module */
+    module = G_define_module();
+    module->keywords = _("network, shortest path, all pairs");
+    module->description =
+	_("Computes the shortest path between all pairs of nodes.");
+
+    /* 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);
+
+    afcol = G_define_option();
+    afcol->key = "afcolumn";
+    afcol->type = TYPE_STRING;
+    afcol->required = NO;
+    afcol->description = _("Arc forward/both direction(s) cost column");
+
+    abcol = G_define_option();
+    abcol->key = "abcolumn";
+    abcol->type = TYPE_STRING;
+    abcol->required = NO;
+    abcol->description = _("Arc backward direction cost column");
+
+    geo_f = G_define_flag();
+    geo_f->key = 'g';
+    geo_f->description =
+	_("Use geodesic calculation for longitude-latitude locations");
+
+    newpoints_f = G_define_flag();
+    newpoints_f->key = 'a';
+    newpoints_f->description = _("Add points on nodes without points");
+
+    /* 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;
+    }
+
+    /* 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 ( from_cat integer, to_cat integer, cost double precision)",
+	    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);
+
+
+    Vect_net_build_graph(&In, mask_type, atoi(field_opt->answer), 0,
+			 afcol->answer, abcol->answer, NULL, geo, 0);
+    graph = &(In.graph);
+    nnodes = dglGet_NodeCount(graph);
+    dist = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    cats = (int *)G_calloc(nnodes + 1, sizeof(int));	/*id of each node. -1 if not used */
+
+    if (!dist || !cats)
+	G_fatal_error(_("Out of memory"));
+    for (i = 0; i <= nnodes; i++) {
+	dist[i] = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
+	if (!dist[i])
+	    G_fatal_error(_("Out of memory"));
+    }
+    neta_allpairs(graph, dist);
+
+    for (i = 1; i <= nnodes; i++)
+	cats[i] = -1;
+
+    nlines = Vect_get_num_lines(&In);
+    max_cat = 0;
+    for (i = 1; i <= nlines; i++) {
+	int type = Vect_read_line(&In, Points, Cats, i);
+	for (j = 0; j < Cats->n_cats; j++)
+	    if (Cats->cat[j] > max_cat)
+		max_cat = Cats->cat[j];
+	if (type == GV_POINT) {
+	    int node;
+	    Vect_get_line_nodes(&In, i, &node, NULL);
+	    Vect_cat_get(Cats, layer, &cats[node]);
+	    if (cats[node] != -1)
+		Vect_write_line(&Out, GV_POINT, Points, Cats);
+	}
+
+    }
+    max_cat++;
+    for (i = 1; i <= nnodes; i++)
+	if (newpoints_f->answer && cats[i] == -1) {
+	    Vect_reset_cats(Cats);
+	    Vect_cat_set(Cats, 1, max_cat);
+	    cats[i] = max_cat++;
+	    neta_add_point_on_node(&In, &Out, i, Cats);
+	}
+    G_message(_("Writing data into the table..."));
+    G_percent_reset();
+    for (i = 1; i <= nnodes; i++) {
+	G_percent(i, nnodes, 1);
+	if (cats[i] != -1)
+	    for (j = 1; j <= nnodes; j++)
+		if (cats[j] != -1) {
+		    sprintf(buf, "insert into %s values (%d, %d, %f)",
+			    Fi->table, i, j, dist[i][j] / 1000.0);
+		    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));
+		    };
+		}
+    }
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    for (i = 0; i <= nnodes; i++)
+	G_free(dist[i]);
+    G_free(dist);
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+
+    Vect_hist_command(&Out);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}


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

Added: grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.allpairs/neta_allpairs.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,87 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes the legngth of the shortest path between
+ *             all pairs of nodes 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/dgl/graph.h>
+
+/*
+ * Upon the completion, dist stores the directed distance between every pair (i,j)
+ * or -1 if the nodes are unreachable. It must be an array of dimension [nodes+1]*[nodes+1]
+ * TODO: use only O(W*W) memory where W is the number of nodes present in the graph
+ */
+int neta_allpairs(dglGraph_s * graph, dglInt32_t ** dist)
+{
+    int nnodes, i, j, k, indices;
+    dglEdgesetTraverser_s et;
+    dglNodeTraverser_s nt;
+    dglInt32_t *node;
+    nnodes = dglGet_NodeCount(graph);
+    dglInt32_t *node_indices;
+    node_indices = (dglInt32_t *) G_calloc(nnodes, sizeof(dglInt32_t));
+    if (!node_indices) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+    G_message(_("Computing all pairs shortest paths..."));
+    G_percent_reset();
+    for (i = 0; i <= nnodes; i++)
+	for (j = 0; j <= nnodes; j++)
+	    dist[i][j] = -1;
+    dglNode_T_Initialize(&nt, graph);
+    indices = 0;
+    for (node = dglNode_T_First(&nt); node; node = dglNode_T_Next(&nt)) {
+	dglInt32_t node_id = dglNodeGet_Id(graph, node);
+	node_indices[indices++] = node_id;
+	dglInt32_t *edge;
+	dglEdgeset_T_Initialize(&et, graph, dglNodeGet_OutEdgeset(graph, node));
+	for (edge = dglEdgeset_T_First(&et); edge;
+	     edge = dglEdgeset_T_Next(&et))
+	    if (dglEdgeGet_Id(graph, edge) < 0)	/*ignore backward edges */
+		dist[node_id][dglNodeGet_Id
+			      (graph, dglEdgeGet_Tail(graph, edge))] =
+		    dglEdgeGet_Cost(graph, edge);
+	dglEdgeset_T_Release(&et);
+    }
+    dglNode_T_Release(&nt);
+    for (k = 0; k < indices; k++) {
+	dglInt32_t k_index = node_indices[k];
+	G_percent(k + 1, indices, 1);
+	for (i = 0; i < indices; i++) {
+	    dglInt32_t i_index = node_indices[i];
+	    if (dist[i_index][k_index] == -1)
+		continue;	/*no reason to proceed along infinite path */
+	    for (j = 0; j < indices; j++) {
+		dglInt32_t j_index = node_indices[j];
+		if (dist[k_index][j_index] != -1 &&
+		    (dist[i_index][k_index] + dist[k_index][j_index] <
+		     dist[i_index][j_index] || dist[i_index][j_index] == -1)) {
+		    dist[i_index][j_index] =
+			dist[i_index][k_index] + dist[k_index][j_index];
+		}
+	    }
+	}
+    }
+
+    G_free(node_indices);
+    return 0;
+}


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

Added: grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.allpairs/neta_utils.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,39 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    netalib utility functions
+ *
+ * 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/dbmi.h>
+#include <grass/neta.h>
+
+
+void neta_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
+			    struct line_cats *Cats)
+{
+    static struct line_pnts *Points;
+    double x, y, z;
+    Points = Vect_new_line_struct();
+    Vect_get_node_coor(In, node, &x, &y, &z);
+    Vect_reset_line(Points);
+    Vect_append_point(Points, x, y, z);
+    Vect_write_line(Out, GV_POINT, Points, Cats);
+    Vect_destroy_line_struct(Points);
+}


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

Modified: grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c	2009-05-28 13:44:03 UTC (rev 37570)
+++ grass-addons/vector/net.analyze/v.net.bridge/neta_articulation_point.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -81,10 +81,10 @@
 		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]));
+		    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 */
 

Modified: grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c	2009-05-28 13:44:03 UTC (rev 37570)
+++ grass-addons/vector/net.analyze/v.net.bridge/neta_bridge.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -78,10 +78,10 @@
 		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]));
+		    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++;

Modified: grass-addons/vector/net.analyze/v.net.components/main.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.components/main.c	2009-05-28 13:44:03 UTC (rev 37570)
+++ grass-addons/vector/net.analyze/v.net.components/main.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -40,7 +40,6 @@
     return 1;
 }
 
-
 int main(int argc, char *argv[])
 {
     struct Map_info In, Out;
@@ -234,7 +233,6 @@
 		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;

Added: grass-addons/vector/net.analyze/v.net.flow/Makefile
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/Makefile	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.flow/Makefile	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,13 @@
+MODULE_TOPDIR = ../../..
+
+PGM=v.net.flow
+
+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.flow/Makefile
___________________________________________________________________
Name: svn:executable
   + *

Added: grass-addons/vector/net.analyze/v.net.flow/main.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/main.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.flow/main.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,217 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.flow
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Max flow between two nodes
+ *
+ * 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/dbmi.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, *abcol, *afcol;
+    int chcat, with_z;
+    int layer, mask_type;
+    VARRAY *varray;
+    dglGraph_s *graph;
+    int i, nlines, *flow, total_flow;
+    char buf[2000];
+
+    /* 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() */
+
+    /* initialize module */
+    module = G_define_module();
+    module->keywords = _("network, max flow");
+    module->description = _("Computes the maximum flow between two nodes.");
+
+    /* 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);
+
+    afcol = G_define_option();
+    afcol->key = "afcolumn";
+    afcol->type = TYPE_STRING;
+    afcol->required = NO;
+    afcol->description = _("Arc forward/both direction(s) capacity column");
+
+    abcol = G_define_option();
+    abcol->key = "abcolumn";
+    abcol->type = TYPE_STRING;
+    abcol->required = NO;
+    abcol->description = _("Arc backward direction capacity column");
+
+    /* 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);
+    }
+
+    /* 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;
+    }
+
+    /* 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, flow 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);
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+
+    Vect_hist_command(&Out);
+
+    Vect_net_build_graph(&In, mask_type, atoi(field_opt->answer), 0,
+			 afcol->answer, abcol->answer, NULL, 0, 0);
+    graph = &(In.graph);
+    nlines = Vect_get_num_lines(&In);
+
+    flow = (int *)G_calloc(nlines + 1, sizeof(int));
+    if (!flow)
+	G_fatal_error(_("Out of memory"));
+
+    total_flow = neta_flow(graph, 215, 219, flow);
+    G_debug(3, "Max flow: %d", total_flow);
+
+    G_message(_("Writing the output..."));
+    G_percent_reset();
+    for (i = 1; i <= nlines; i++) {
+	G_percent(i, nlines, 1);
+	int type = Vect_read_line(&In, Points, Cats, i);
+	Vect_write_line(&Out, type, Points, Cats);
+	if (type == GV_LINE) {
+	    int cat;
+	    Vect_cat_get(Cats, layer, &cat);
+	    if (cat == -1)
+		continue;	/*TODO: warning? */
+	    sprintf(buf, "insert into %s values (%d, %d)", Fi->table, cat,
+		    flow[i] / 1000);
+	    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));
+	    };
+	}
+    }
+    neta_add_point_on_node(&In, &Out, 215, Cats);
+    neta_add_point_on_node(&In, &Out, 219, Cats);
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    G_free(flow);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}


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

Added: grass-addons/vector/net.analyze/v.net.flow/neta_flow.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/neta_flow.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.flow/neta_flow.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,123 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes the legngth of the shortest path between
+ *             all pairs of nodes 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/dgl/graph.h>
+
+dglInt32_t sign(dglInt32_t x)
+{
+    if (x >= 0)
+	return 1;
+    return -1;
+}
+
+/*
+ * returns max flow from source to sink. Array flow stores flow for
+ * each edge. Negative flow corresponds to a flow in opposite direction
+ * The function assumes that the edge costs correspond to edge capacities.
+ */
+int neta_flow(dglGraph_s * graph, int source, int sink, int *flow)
+{
+    int nnodes, nlines, i;
+    dglEdgesetTraverser_s et;
+    dglInt32_t *queue;
+    dglInt32_t **prev;
+    int begin, end, total_flow;
+
+    nnodes = dglGet_NodeCount(graph);
+    nlines = dglGet_EdgeCount(graph) / 2;	/*each line corresponds to two edges. One in each direction */
+    queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
+    prev = (dglInt32_t **) G_calloc(nnodes + 3, sizeof(dglInt32_t *));
+    if (!queue || !prev) {
+	G_fatal_error(_("Out of memory"));
+	return -1;
+    }
+    for (i = 0; i <= nlines; i++)
+	flow[i] = 0;
+    total_flow = 0;
+    while (1) {
+	dglInt32_t node, edge_id, min_residue;
+	int found = 0;
+	begin = 0;
+	end = 1;
+	queue[0] = source;
+	for (i = 1; i <= nnodes; i++) {
+	    prev[i] = NULL;
+	}
+	while (begin != end && !found) {
+	    dglInt32_t vertex = queue[begin++];
+	    dglInt32_t *edge, *node = dglGetNode(graph, vertex);
+	    dglEdgeset_T_Initialize(&et, graph,
+				    dglNodeGet_OutEdgeset(graph, node));
+	    for (edge = dglEdgeset_T_First(&et); edge;
+		 edge = dglEdgeset_T_Next(&et)) {
+		dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
+		dglInt32_t id = dglEdgeGet_Id(graph, edge);
+		dglInt32_t to =
+		    dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
+		if (to != source && prev[to] == NULL &&
+		    cap > sign(id) * flow[abs(id)]) {
+		    prev[to] = edge;
+		    if (to == sink) {
+			found = 1;
+			break;
+		    }
+		    queue[end++] = to;
+		}
+	    }
+	    dglEdgeset_T_Release(&et);
+	}
+	if (!found)
+	    break;		/*no augmenting path */
+	/*find minimum residual capacity along the augmenting path */
+	node = sink;
+	edge_id = dglEdgeGet_Id(graph, prev[node]);
+	min_residue =
+	    dglEdgeGet_Cost(graph,
+			    prev[node]) - sign(edge_id) * flow[abs(edge_id)];
+	while (node != source) {
+	    dglInt32_t residue;
+	    edge_id = dglEdgeGet_Id(graph, prev[node]);
+	    residue =
+		dglEdgeGet_Cost(graph,
+				prev[node]) -
+		sign(edge_id) * flow[abs(edge_id)];
+	    if (residue < min_residue)
+		min_residue = residue;
+	    node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
+	}
+	total_flow += min_residue;
+	/*update flow along the augmenting path */
+	node = sink;
+	while (node != source) {
+	    edge_id = dglEdgeGet_Id(graph, prev[node]);
+	    flow[abs(edge_id)] += sign(edge_id) * min_residue;
+	    node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
+	}
+    }
+
+    G_free(queue);
+    G_free(prev);
+
+    return total_flow;
+}


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

Added: grass-addons/vector/net.analyze/v.net.flow/neta_utils.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.flow/neta_utils.c	                        (rev 0)
+++ grass-addons/vector/net.analyze/v.net.flow/neta_utils.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -0,0 +1,39 @@
+
+/****************************************************************
+ *
+ * MODULE:     netalib
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    netalib utility functions
+ *
+ * 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/dbmi.h>
+#include <grass/neta.h>
+
+
+void neta_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
+			    struct line_cats *Cats)
+{
+    static struct line_pnts *Points;
+    double x, y, z;
+    Points = Vect_new_line_struct();
+    Vect_get_node_coor(In, node, &x, &y, &z);
+    Vect_reset_line(Points);
+    Vect_append_point(Points, x, y, z);
+    Vect_write_line(Out, GV_POINT, Points, Cats);
+    Vect_destroy_line_struct(Points);
+}


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

Modified: grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c
===================================================================
--- grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c	2009-05-28 13:44:03 UTC (rev 37570)
+++ grass-addons/vector/net.analyze/v.net.spanningtree/neta_spannigtree.c	2009-05-28 14:06:36 UTC (rev 37571)
@@ -5,7 +5,7 @@
  *
  * AUTHOR(S):  Daniel Bundala
  *
- * PURPOSE:    Computes strongly and weakly connected components
+ * PURPOSE:    Computes minimum spanning tree in the network
  *
  * COPYRIGHT:  (C) 2002-2005 by the GRASS Development Team
  *



More information about the grass-commit mailing list