[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