Преглед изворни кода

added new modules by Daniel Bundala (Google Summer of Code 2009)
v.net.distance
v.net.bridge
v.net.spanningtree
v.net.flow
v.net.connectivity
v.net.timetable
v.net.components
v.net.allpairs
v.net.centrality


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@41780 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa пре 15 година
родитељ
комит
d18db75b81

+ 12 - 0
vector/v.net.allpairs/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.allpairs
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 250 - 0
vector/v.net.allpairs/main.c

@@ -0,0 +1,250 @@
+
+/****************************************************************
+ *
+ * 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/vector.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;
+    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;
+    struct varray *varray;
+    dglGraph_s *graph;
+    int i, j, geo, nnodes, nlines, max_cat, *cats;
+    dglInt32_t **dist;
+    char buf[2000], *output;
+
+    /* 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();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("shortest path"));
+    module->description =
+	_("Computes the shortest path between all pairs of nodes in the network.");
+
+    /* 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);
+    field_opt->guisection = _("Selection");
+    cat_opt = G_define_standard_option(G_OPT_V_CATS);
+    cat_opt->guisection = _("Selection");
+    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    where_opt->guisection = _("Selection");
+
+    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    afcol->key = "afcolumn";
+    afcol->required = NO;
+    afcol->description = _("Name of arc forward/both direction(s) cost column");
+    afcol->guisection = _("Cost");
+	
+    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    abcol->key = "abcolumn";
+    abcol->required = NO;
+    abcol->description = _("Name of arc backward direction cost column");
+    abcol->guisection = _("Cost");
+
+    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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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);
+    chcat =
+	(NetA_initialise_varray
+	 (&In, layer, GV_POINT, where_opt->answer, cat_opt->answer,
+	  &varray) == 1);
+
+    /* 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);
+    db_init_string(&sql);
+    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, 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 */
+    output = (char *)G_calloc(nnodes + 1, sizeof(char));
+
+    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;
+	output[i] = 0;
+    }
+
+    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);
+		if (!chcat || varray->c[i])
+		    output[node] = 'y';
+	    }
+	}
+
+    }
+    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 && output[i])	/*Process only selected nodes */
+	    for (j = 1; j <= nnodes; j++)
+		if (cats[j] != -1) {
+		    sprintf(buf, "insert into %s values (%d, %d, %f)",
+			    Fi->table, cats[i], cats[j],
+			    dist[i][j] / (double)In.cost_multip);
+		    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);
+}

Разлика између датотеке није приказан због своје велике величине
+ 34 - 0
vector/v.net.allpairs/v.net.allpairs.html


+ 12 - 0
vector/v.net.bridge/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.bridge
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 137 - 0
vector/v.net.bridge/main.c

@@ -0,0 +1,137 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.bridge
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes bridges and articulation points
+ *
+ * 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/vector.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;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out;
+    struct Option *field_opt, *method_opt;
+    int with_z;
+    int layer, mask_type;
+    dglGraph_s *graph;
+    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() */
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("articulation points"));
+    module->description = _("Computes bridges and articulation points in the network.");
+
+    /* 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);
+
+    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;Finds bridges;"
+				 "articulation;Finds articulation points;");
+    method_opt->description = _("Feature type");
+
+    /* 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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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);
+
+    Vect_net_build_graph(&In, mask_type, 0, 0, NULL, NULL, NULL, 0, 0);
+    graph = &(In.graph);
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+    Vect_hist_command(&Out);
+
+    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);
+    }
+    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);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}

+ 34 - 0
vector/v.net.bridge/v.net.bridge.html

@@ -0,0 +1,34 @@
+<h2>DESCRIPTION</h2>
+
+<em>v.net.bridge</em> finds bridges and articulation points in a network. 
+
+<h2>NOTES</h2>
+Bridge in a network is an edge/line whose removal would disconnect the (sub-)network. A node is an articulation point if its removal would disconnect the (sub-)network. For more information and formal definitions check the wikipedia entries: <a href="http://en.wikipedia.org/wiki/Bridge_%28graph_theory%29">bridge</a> and <a href="http://en.wikipedia.org/wiki/Cut_vertex">articulation point</a>.<br><br>
+The output of the module contains the selected features. If <b>method=bridge</b> then lines corresponding to bridges are copied from the input map to the output map. On the other hand, if <b>method=articulation</b> then point are created on the positions of articulation points.<br><br>
+
+
+<br>In GRASS, <em>line</em> is not always a single line segments. It might be, and often is, a sequence of line segments between two intersections. Also, articulation point is a standard graph theoretic terminology which is slightly  misleading in GRASS. An articulation point in graph theory is an articulation <em>node</em> in GRASS terminology. 
+
+<h2>EXAMPLES</h2>
+
+<div class="code"><pre>
+</pre></div>
+<P>
+
+<div class="code"><pre>
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="v.category.html">v.category</a>,
+</em>
+
+<h2>AUTHORS</h2>
+
+Daniel Bundala, Google Summer of Code 2009, Student<br>
+Wolf Bergenheim, Mentor
+
+<p>
+<i>Last changed: $Date$</i>

+ 12 - 0
vector/v.net.centrality/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.centrality
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 364 - 0
vector/v.net.centrality/main.c

@@ -0,0 +1,364 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.centrality
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    This module computes various cetrality measures
+ *
+ * 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/vector.h>
+#include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
+
+/*Global variables */
+struct Option *deg_opt, *close_opt, *betw_opt, *eigen_opt;
+double *deg, *close, *betw, *eigen;
+/* Attribute table */
+dbString sql, tmp;
+dbDriver *driver;
+struct field_info *Fi;
+
+void append_string(dbString * string, char *s)
+{
+    db_append_string(string, ", ");
+    db_append_string(string, s);
+    db_append_string(string, " double precision");
+}
+
+void append_double(dbString * string, double d)
+{
+    char buf[50];
+    sprintf(buf, ",%f", d);
+    db_append_string(string, buf);
+}
+
+void process_node(int node, int cat)
+{
+    char buf[2000];
+    sprintf(buf, "INSERT INTO %s VALUES(%d", Fi->table, cat);
+    db_set_string(&sql, buf);
+    if (deg_opt->answer)
+	append_double(&sql, deg[node]);
+    if (close_opt->answer)
+	append_double(&sql, close[node]);
+    if (betw_opt->answer)
+	append_double(&sql, betw[node]);
+    if (eigen_opt->answer)
+	append_double(&sql, eigen[node]);
+
+    db_append_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));
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    struct Map_info In, Out;
+    static struct line_pnts *Points;
+    struct line_cats *Cats;
+    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 Option *iter_opt, *error_opt;
+    struct Flag *geo_f, *add_f;
+    int chcat, with_z;
+    int layer, mask_type;
+    struct varray *varray;
+    dglGraph_s *graph;
+    int i, geo, nnodes, nlines, j, max_cat;
+    char buf[2000], *covered;
+
+    /* initialize GIS environment */
+    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("centrality measures"));
+    module->description = _("Computes degree, centrality, betweeness, closeness and eigenvector "
+			    "cetrality measures in the network.");
+
+    /* Define the different options as defined in gis.h */
+    map_in = G_define_standard_option(G_OPT_V_INPUT);
+    field_opt = G_define_standard_option(G_OPT_V_FIELD);
+
+    map_out = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    cat_opt = G_define_standard_option(G_OPT_V_CATS);
+    cat_opt->guisection = _("Selection");
+    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    where_opt->guisection = _("Selection");
+
+    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    afcol->key = "afcolumn";
+    afcol->required = NO;
+    afcol->description = _("Name of arc forward/both direction(s) cost column");
+    afcol->guisection = _("Cost");
+
+    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    abcol->key = "abcolumn";
+    abcol->required = NO;
+    abcol->description = _("Name of arc backward direction cost column");
+    abcol->guisection = _("Cost");
+    
+    deg_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    deg_opt->key = "degree";
+    deg_opt->required = NO;
+    deg_opt->description = _("Name of degree centrality column");
+    deg_opt->guisection = _("Columns");
+
+    close_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    close_opt->key = "closeness";
+    close_opt->required = NO;
+    close_opt->description = _("Name of closeness centrality column");
+    close_opt->guisection = _("Columns");
+
+    betw_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    betw_opt->key = "betweenness";
+    betw_opt->required = NO;
+    betw_opt->description = _("Name of betweenness centrality column");
+    betw_opt->guisection = _("Columns");
+
+    eigen_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    eigen_opt->key = "eigenvector";
+    eigen_opt->required = NO;
+    eigen_opt->description = _("Name of eigenvector centrality column");
+    eigen_opt->guisection = _("Columns");
+
+    iter_opt = G_define_option();
+    iter_opt->key = "iterations";
+    iter_opt->answer = "1000";
+    iter_opt->type = TYPE_INTEGER;
+    iter_opt->required = NO;
+    iter_opt->description =
+	_("Maximum number of iterations to compute eigenvector centrality");
+
+    error_opt = G_define_option();
+    error_opt->key = "error";
+    error_opt->answer = "0.1";
+    error_opt->type = TYPE_DOUBLE;
+    error_opt->required = NO;
+    error_opt->description =
+	_("Cummulative error tolerance for eigenvector centrality");
+
+    geo_f = G_define_flag();
+    geo_f->key = 'g';
+    geo_f->description =
+	_("Use geodesic calculation for longitude-latitude locations");
+
+    add_f = G_define_flag();
+    add_f->key = 'a';
+    add_f->description = _("Add points on nodes");
+
+    /* 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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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);
+    chcat =
+	(NetA_initialise_varray
+	 (&In, layer, mask_type, where_opt->answer, cat_opt->answer,
+	  &varray) == 1);
+
+    /* 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);
+    db_init_string(&sql);
+    driver = db_start_driver_open_database(Fi->driver, Fi->database);
+    if (driver == NULL)
+	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+		      Fi->database, Fi->driver);
+
+    db_init_string(&tmp);
+    if (deg_opt->answer)
+	append_string(&tmp, deg_opt->answer);
+    if (close_opt->answer)
+	append_string(&tmp, close_opt->answer);
+    if (betw_opt->answer)
+	append_string(&tmp, betw_opt->answer);
+    if (eigen_opt->answer)
+	append_string(&tmp, eigen_opt->answer);
+    sprintf(buf,
+	    "create table %s(cat integer%s)", Fi->table, db_get_string(&tmp));
+
+    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, geo, 0);
+    graph = &(In.graph);
+    nnodes = dglGet_NodeCount(graph);
+
+    deg = close = betw = eigen = NULL;
+
+    covered = (char *)G_calloc(nnodes + 1, sizeof(char));
+    if (!covered)
+	G_fatal_error(_("Out of memory"));
+
+    if (deg_opt->answer) {
+	deg = (double *)G_calloc(nnodes + 1, sizeof(double));
+	if (!deg)
+	    G_fatal_error(_("Out of memory"));
+    }
+
+    if (close_opt->answer) {
+	close = (double *)G_calloc(nnodes + 1, sizeof(double));
+	if (!close)
+	    G_fatal_error(_("Out of memory"));
+    }
+
+    if (betw_opt->answer) {
+	betw = (double *)G_calloc(nnodes + 1, sizeof(double));
+	if (!betw)
+	    G_fatal_error(_("Out of memory"));
+    }
+
+    if (eigen_opt->answer) {
+	eigen = (double *)G_calloc(nnodes + 1, sizeof(double));
+	if (!eigen)
+	    G_fatal_error(_("Out of memory"));
+    }
+
+
+    if (deg_opt->answer) {
+	G_message(_("Computing degree centrality measure"));
+	NetA_degree_centrality(graph, deg);
+    }
+    if (betw_opt->answer || close_opt->answer) {
+	G_message(_
+		  ("Computing betweenness and/or closeness centrality measure"));
+	NetA_betweenness_closeness(graph, betw, close);
+	if (close)
+	    for (i = 1; i <= nnodes; i++)
+		close[i] /= (double)In.cost_multip;
+    }
+    if (eigen_opt->answer) {
+	G_message(_("Computing eigenvector centrality measure"));
+	NetA_eigenvector_centrality(graph, atoi(iter_opt->answer),
+				    atof(error_opt->answer), eigen);
+    }
+
+
+    nlines = Vect_get_num_lines(&In);
+    G_message(_("Writing data into the table..."));
+    G_percent_reset();
+    for (i = 1; i <= nlines; i++) {
+	G_percent(i, nlines, 1);
+	int type = Vect_read_line(&In, Points, Cats, i);
+	if (type == GV_POINT && (!chcat || varray->c[i])) {
+	    int cat, node;
+	    if (!Vect_cat_get(Cats, layer, &cat))
+		continue;
+	    Vect_write_line(&Out, type, Points, Cats);
+	    Vect_get_line_nodes(&In, i, &node, NULL);
+	    process_node(node, cat);
+	    covered[node] = 1;
+	}
+    }
+
+    if (add_f->answer && !chcat) {
+	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++;
+	for (i = 1; i <= nnodes; i++)
+	    if (!covered[i]) {
+		Vect_reset_cats(Cats);
+		Vect_cat_set(Cats, 1, max_cat);
+		NetA_add_point_on_node(&In, &Out, i, Cats);
+		process_node(i, max_cat);
+		max_cat++;
+	    }
+
+    }
+
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    G_free(covered);
+    if (deg)
+	G_free(deg);
+    if (close)
+	G_free(close);
+    if (betw)
+	G_free(betw);
+    if (eigen)
+	G_free(eigen);
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}

Разлика између датотеке није приказан због своје велике величине
+ 33 - 0
vector/v.net.centrality/v.net.centrality.html


+ 12 - 0
vector/v.net.components/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.components
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 232 - 0
vector/v.net.components/main.c

@@ -0,0 +1,232 @@
+
+/****************************************************************
+ *
+ * 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/vector.h>
+#include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
+
+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;
+    static struct line_pnts *Points;
+    struct line_cats *Cats;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out;
+    struct Option *field_opt, *method_opt;
+    struct Flag *add_f;
+    int with_z;
+    int layer, mask_type;
+    dglGraph_s *graph;
+    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() */
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("components"));
+    module->description =
+	_("Computes strongly and weakly connected components in the network.");
+    
+    /* Define the different options as defined in gis.h */
+    map_in = G_define_standard_option(G_OPT_V_INPUT);
+    field_opt = G_define_standard_option(G_OPT_V_FIELD);
+
+    map_out = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    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 = "weak,strong";
+    method_opt->descriptions = _("weak;Weakly connected components;"
+				 "strong;Strongly connected components;");
+    method_opt->description = _("Type of components");
+
+    add_f = G_define_flag();
+    add_f->key = 'a';
+    add_f->description = _("Add points on nodes");
+
+    /* 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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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);
+
+    Vect_net_build_graph(&In, mask_type, 0, 0, NULL, NULL, NULL, 0, 0);
+    graph = &(In.graph);
+    nnodes = Vect_get_num_nodes(&In);
+    component = (int *)G_calloc(nnodes + 1, sizeof(int));
+    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, layer, NULL, GV_1TABLE);
+    Vect_map_add_dblink(&Out, layer, NULL, Fi->table, "cat", Fi->database,
+			Fi->driver);
+    db_init_string(&sql);
+    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 = NetA_weakly_connected_components(graph, component);
+    else
+	components = NetA_strongly_connected_components(graph, component);
+
+    G_debug(3, "Components: %d", components);
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+    Vect_hist_command(&Out);
+
+    nlines = Vect_get_num_lines(&In);
+    for (i = 1; i <= nlines; i++) {
+	int comp, cat;
+	type = Vect_read_line(&In, Points, Cats, i);
+	if (!Vect_cat_get(Cats, layer, &cat))
+	    continue;
+	if (type == GV_LINE || type == GV_BOUNDARY) {
+	    int node1, node2;
+	    Vect_get_line_nodes(&In, i, &node1, &node2);
+	    if (component[node1] == component[node2]) {
+		comp = component[node1];
+	    }
+	    else {
+		continue;
+	    }
+	}
+	else if (type == GV_POINT) {
+	    int node;
+	    Vect_get_line_nodes(&In, i, &node, NULL);
+	    comp = component[node];
+	    covered[node] = 1;
+	}
+	else
+	    continue;
+	Vect_write_line(&Out, type, Points, Cats);
+	insert_new_record(driver, Fi, &sql, cat, comp);
+	/*        for(j=0;j<Cats->n_cats;j++)
+	 * if(Cats->field[j] == layer)
+	 * 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 */
+    if (add_f->answer) {
+	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++;
+	for (i = 1; i <= nnodes; i++)
+	    if (!covered[i]) {
+		Vect_reset_cats(Cats);
+		Vect_cat_set(Cats, layer, max_cat);
+		NetA_add_point_on_node(&In, &Out, i, Cats);
+		insert_new_record(driver, Fi, &sql, max_cat++, component[i]);
+	    }
+    }
+
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}

Разлика између датотеке није приказан због своје велике величине
+ 35 - 0
vector/v.net.components/v.net.components.html


+ 12 - 0
vector/v.net.connectivity/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.connectivity
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 207 - 0
vector/v.net.connectivity/main.c

@@ -0,0 +1,207 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.connectivity
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Vertex connectivity between two sets of 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/vector.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;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out;
+    struct Option *field_opt, *ncol;
+    struct Option *catset1_opt, *fieldset1_opt, *whereset1_opt;
+    struct Option *catset2_opt, *fieldset2_opt, *whereset2_opt;
+    int with_z;
+    int layer, mask_type;
+    struct varray *varray_set1, *varray_set2;
+    dglGraph_s *graph;
+    int i, nnodes, nlines, *flow, total_flow, nedges;
+    struct ilist *set1_list, *set2_list, *cut;
+    int *node_costs;
+
+    dglGraph_s vg;
+
+    /* initialize GIS environment */
+    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("connectivity"));
+    module->description =
+	_("Computes vertex connectivity between two sets of nodes in the network.");
+
+    /* Define the different options as defined in gis.h */
+    map_in = G_define_standard_option(G_OPT_V_INPUT);
+    field_opt = G_define_standard_option(G_OPT_V_FIELD);
+
+    map_out = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
+    ncol->key = "ncolumn";
+    ncol->required = NO;
+    ncol->description = _("Name of node capacity column");
+
+    fieldset1_opt = G_define_standard_option(G_OPT_V_FIELD);
+    fieldset1_opt->key = "set1_layer";
+    fieldset1_opt->label = _("Set1 layer number or name");
+    fieldset1_opt->guisection = _("Set1");
+
+    catset1_opt = G_define_standard_option(G_OPT_V_CATS);
+    catset1_opt->key = "set1_cats";
+    catset1_opt->label = _("Set1 category values");
+    catset1_opt->guisection = _("Set1");
+    
+    whereset1_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    whereset1_opt->key = "set1_where";
+    whereset1_opt->label =
+	_("Set1 WHERE conditions of SQL statement without 'where' keyword");
+    whereset1_opt->guisection = _("Set1");
+
+    fieldset2_opt = G_define_standard_option(G_OPT_V_FIELD);
+    fieldset2_opt->key = "set2_layer";
+    fieldset2_opt->description = _("Set2 layer number or name");
+    fieldset2_opt->guisection = _("Set2");
+	
+    catset2_opt = G_define_standard_option(G_OPT_V_CATS);
+    catset2_opt->key = "set2_cats";
+    catset2_opt->description = _("Set2 category values");
+    catset2_opt->guisection = _("Set2");
+	
+    whereset2_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    whereset2_opt->key = "set2_where";
+    whereset2_opt->label =
+	_("Set2 WHERE conditions of SQL statement without 'where' keyword");
+    whereset2_opt->guisection = _("Set2");
+
+    /* 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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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 (NetA_initialise_varray
+	(&In, atoi(fieldset1_opt->answer), GV_POINT, whereset1_opt->answer,
+	 catset1_opt->answer, &varray_set1) == 2)
+	G_fatal_error(_("Neither %s nor %s was given"), catset1_opt->key,
+		      whereset1_opt->key);
+    if (NetA_initialise_varray
+	(&In, atoi(fieldset2_opt->answer), GV_POINT, whereset2_opt->answer,
+	 catset2_opt->answer, &varray_set2) == 2)
+	G_fatal_error(_("Neither %s nor %s was given"), catset2_opt->key,
+		      whereset2_opt->key);
+
+    set1_list = Vect_new_list();
+    set2_list = Vect_new_list();
+
+    NetA_varray_to_nodes(&In, varray_set1, set1_list, NULL);
+    NetA_varray_to_nodes(&In, varray_set2, set2_list, NULL);
+
+    nlines = Vect_get_num_lines(&In);
+    nnodes = Vect_get_num_nodes(&In);
+
+    if (set1_list->n_values == 0)
+	G_fatal_error(_("%s is empty"), "set1");
+
+    if (set2_list->n_values == 0)
+	G_fatal_error(_("%s is empty"), "set2");
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+    Vect_hist_command(&Out);
+
+    Vect_net_build_graph(&In, mask_type, 0, atoi(field_opt->answer),
+			 NULL, NULL, NULL, 0, 0);
+    graph = &(In.graph);
+
+    /*build new graph */
+    if (ncol->answer) {
+	node_costs = (int *)G_calloc(nnodes + 1, sizeof(int));
+	if (!node_costs)
+	    G_fatal_error(_("Out of memory"));
+	NetA_get_node_costs(&In, layer, ncol->answer, node_costs);
+	nedges = NetA_split_vertices(graph, &vg, node_costs);
+	G_free(node_costs);
+    }
+    else
+	nedges = NetA_split_vertices(graph, &vg, NULL);
+    graph = &vg;
+
+    for (i = 0; i < set1_list->n_values; i++)
+	set1_list->value[i] = set1_list->value[i] * 2;	/*out vertex */
+    for (i = 0; i < set2_list->n_values; i++)
+	set2_list->value[i] = set2_list->value[i] * 2 - 1;	/*in vertex */
+
+    flow = (int *)G_calloc(nedges + 1, sizeof(int));
+    if (!flow)
+	G_fatal_error(_("Out of memory"));
+
+    total_flow = NetA_flow(graph, set1_list, set2_list, flow);
+    G_debug(3, "Connectivity: %d", total_flow);
+    cut = Vect_new_list();
+    total_flow = NetA_min_cut(graph, set1_list, set2_list, flow, cut);
+
+    /*TODO: copy old points */
+    for (i = 0; i < cut->n_values; i++)
+	NetA_add_point_on_node(&In, &Out, cut->value[i], Cats);
+
+    Vect_destroy_list(cut);
+
+    G_free(flow);
+    Vect_destroy_list(set1_list);
+    Vect_destroy_list(set2_list);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}

+ 33 - 0
vector/v.net.connectivity/v.net.connectivity.html

@@ -0,0 +1,33 @@
+<h2>DESCRIPTION</h2>
+
+<em>v.net.connectivity</em> computes vertex connectivity between two sets. i.e., minimum number of vertices whose removal would separate two given sets. 
+
+<h2>NOTES</h2>
+Two sets (<em>set1</em> and <em>set2</em>) are specified by respective <b>layer</b>, <b>where</b> and <b>cats</b> parameters. Similarly to <a HREF="v.net.flow.html">v.net.flow</a> module, capacities of nodes can be given by <b>ncolumn</b> option. Module finds the set of nodes of minimum total capacitiy separating the two given sets and outputs map containing points on the positions of these nodes. Default capacity, which is used when no column is specified, is one.
+
+<h2>EXAMPLES</h2>
+The following command finds the minimum number of intersection separating roads on the left bank from roads on the right bank. 
+<div class="code"><pre>
+v.net.connectivity input=roads output=roads_conn set1_where="bank=left" set2_where="bank=right"
+</pre></div>
+<P>
+
+<div class="code"><pre>
+v.net.connectivity input=airtraffic output=connectivity set1_where="name=JFK" set2_where="name=Heathrow" ncolumn=capacity
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="v.net.flow.html">v.net.flow</a>,
+<a HREF="v.net.bridge.html">v.net.bridge</a>
+</em>
+
+<h2>AUTHORS</h2>
+
+Daniel Bundala, Google Summer of Code 2009, Student<br>
+Wolf Bergenheim, Mentor
+
+<p>
+<i>Last changed: $Date$</i>

+ 12 - 0
vector/v.net.distance/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.distance
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 284 - 0
vector/v.net.distance/main.c

@@ -0,0 +1,284 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.distance
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Computes shortest distance via the network between
+ *             the given sets of features.
+ *
+ * COPYRIGHT:  (C) 2009-2010 by Daniel Bundala, and the GRASS Development Team
+ *
+ *             This program is free software under the
+ *             GNU General Public License (>=v2).
+ *             Read the file COPYING that comes with GRASS
+ *             for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
+
+int main(int argc, char *argv[])
+{
+    struct Map_info In, Out;
+    static struct line_pnts *Points;
+    struct line_cats *Cats;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out, *abcol, *afcol;
+    struct Option *catf_opt, *fieldf_opt, *wheref_opt;
+    struct Option *catt_opt, *fieldt_opt, *wheret_opt, *to_type_opt;
+    struct Flag *geo_f;
+    int with_z, geo;
+    int mask_type;
+    struct varray *varrayf, *varrayt;
+    int flayer, tlayer;
+    dglGraph_s *graph;
+    struct ilist *nodest;
+    int i, nnodes, nlines;
+    int *dst, *nodes_to_features;
+    dglInt32_t **prev;
+    struct line_cats **on_path;
+    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();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("shortest path"));
+    module->label = _("Computes shortest distance via the network between "
+		      "the given sets of features.");
+    module->description = _("Finds the shortest paths from a feature 'to' to every feature 'from' "
+			    "and various information about this realtion are uploaded to the attribute table.");
+    
+    /* 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);
+
+    fieldf_opt = G_define_standard_option(G_OPT_V_FIELD);
+    fieldf_opt->key = "from_layer";
+    fieldf_opt->label = _("From layer number or name");
+    fieldf_opt->guisection = _("From");
+    
+    catf_opt = G_define_standard_option(G_OPT_V_CATS);
+    catf_opt->key = "from_cats";
+    catf_opt->label = _("From category values");
+    catf_opt->guisection = _("From");
+
+    wheref_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    wheref_opt->key = "from_where";
+    wheref_opt->label =
+	_("From WHERE conditions of SQL statement without 'where' keyword");
+    wheref_opt->guisection = _("From");
+
+    fieldt_opt = G_define_standard_option(G_OPT_V_FIELD);
+    fieldt_opt->key = "to_layer";
+    fieldt_opt->description = _("To layer number or name");
+    fieldt_opt->guisection = _("To");
+
+    catt_opt = G_define_standard_option(G_OPT_V_CATS);
+    catt_opt->key = "to_cats";
+    catt_opt->label = _("To category values");
+    catt_opt->guisection = _("To");
+
+    wheret_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    wheret_opt->key = "to_where";
+    wheret_opt->label =
+	_("To WHERE conditions of SQL statement without 'where' keyword");
+    wheret_opt->guisection = _("To");
+
+    to_type_opt = G_define_standard_option(G_OPT_V_TYPE);
+    to_type_opt->key = "to_type";
+    to_type_opt->options = "point,line,boundary";
+    to_type_opt->answer = "point";
+    to_type_opt->description = _("To feature type");
+    to_type_opt->guisection = _("To");
+    
+    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    afcol->key = "afcolumn";
+    afcol->required = YES;
+    afcol->description = _("Arc forward/both direction(s) cost column");
+
+    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    abcol->key = "abcolumn";
+    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");
+
+
+    /* options and flags parser */
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+    mask_type = Vect_option_to_types(to_type_opt);
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    Vect_check_input_output_name(map_in->answer, map_out->answer,
+				 GV_FATAL_EXIT);
+    
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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;
+
+
+    nnodes = Vect_get_num_nodes(&In);
+    nlines = Vect_get_num_lines(&In);
+
+    dst = (int *)G_calloc(nnodes + 1, sizeof(int));
+    prev = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
+    nodes_to_features = (int *)G_calloc(nnodes + 1, sizeof(int));
+    on_path =
+	(struct line_cats **)G_calloc(nlines + 1, sizeof(struct line_cats *));
+    if (!dst || !prev || !nodes_to_features || !on_path)
+	G_fatal_error(_("Out of memory"));
+
+    for (i = 1; i <= nlines; i++)
+	on_path[i] = Vect_new_cats_struct();
+
+    /*initialise varrays and nodes list appropriatelly */
+    flayer = atoi(fieldf_opt->answer);
+    tlayer = atoi(fieldt_opt->answer);
+    NetA_initialise_varray(&In, flayer, GV_POINT, wheref_opt->answer,
+			   catf_opt->answer, &varrayf);
+    NetA_initialise_varray(&In, tlayer, mask_type, wheret_opt->answer,
+			   catt_opt->answer, &varrayt);
+
+    nodest = Vect_new_list();
+    NetA_varray_to_nodes(&In, varrayt, nodest, nodes_to_features);
+
+    Vect_net_build_graph(&In, mask_type, 1, 0, afcol->answer, abcol->answer,
+			 NULL, geo, 0);
+    graph = &(In.graph);
+    NetA_distance_from_points(graph, nodest, dst, prev);
+
+    /* 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);
+    db_init_string(&sql);
+    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, tcat integer, dist 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_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+    Vect_hist_command(&Out);
+
+
+    for (i = 1; i <= nlines; i++)
+	if (varrayf->c[i]) {
+	    int type = Vect_read_line(&In, Points, Cats, i);
+	    int node, tcat, cat;
+	    double cost;
+	    dglInt32_t *vertex, vertex_id;
+	    if (!Vect_cat_get(Cats, flayer, &cat))
+		continue;
+	    Vect_get_line_nodes(&In, i, &node, NULL);
+	    Vect_write_line(&Out, type, Points, Cats);
+	    cost = dst[node] / (double)In.cost_multip;
+	    vertex = dglGetNode(graph, node);
+	    vertex_id = node;
+	    while (prev[vertex_id] != NULL) {
+		Vect_cat_set(on_path
+			     [abs(dglEdgeGet_Id(graph, prev[vertex_id]))], 1,
+			     cat);
+		vertex = dglEdgeGet_Head(graph, prev[vertex_id]);
+		vertex_id = dglNodeGet_Id(graph, vertex);
+	    }
+	    Vect_read_line(&In, NULL, Cats, nodes_to_features[vertex_id]);
+	    if (!Vect_cat_get(Cats, tlayer, &tcat))
+		continue;
+	    sprintf(buf, "insert into %s values (%d, %d, %f)", Fi->table, cat,
+		    tcat, cost);
+
+	    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));
+	    };
+	}
+
+    for (i = 1; i <= nlines; i++)
+	if (on_path[i]->n_cats > 0) {
+	    int type = Vect_read_line(&In, Points, NULL, i);
+	    Vect_write_line(&Out, type, Points, on_path[i]);
+	}
+
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    for (i = 1; i <= nlines; i++)
+	Vect_destroy_cats_struct(on_path[i]);
+    G_free(on_path);
+    G_free(nodes_to_features);
+    G_free(dst);
+    G_free(prev);
+
+    exit(EXIT_SUCCESS);
+}

Разлика између датотеке није приказан због своје велике величине
+ 33 - 0
vector/v.net.distance/v.net.distance.html


+ 12 - 0
vector/v.net.flow/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.flow
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 273 - 0
vector/v.net.flow/main.c

@@ -0,0 +1,273 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.flow
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Max flow and min cut between two sets of 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/vector.h>
+#include <grass/glocale.h>
+#include <grass/dbmi.h>
+#include <grass/neta.h>
+
+
+int main(int argc, char *argv[])
+{
+    struct Map_info In, Out, cut_map;
+    static struct line_pnts *Points;
+    struct line_cats *Cats;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out, *cut_out;
+    struct Option *field_opt, *abcol, *afcol;
+    struct Option *catsource_opt, *fieldsource_opt, *wheresource_opt;
+    struct Option *catsink_opt, *fieldsink_opt, *wheresink_opt;
+    int with_z;
+    int layer, mask_type;
+    struct varray *varray_source, *varray_sink;
+    dglGraph_s *graph;
+    int i, nlines, *flow, total_flow;
+    struct ilist *source_list, *sink_list, *cut;
+    int find_cut;
+
+    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();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("flow"));
+    module->description =
+	_("Computes the maximum flow between two sets of nodes in the network.");
+
+    /* Define the different options as defined in gis.h */
+    map_in = G_define_standard_option(G_OPT_V_INPUT);
+    field_opt = G_define_standard_option(G_OPT_V_FIELD);
+
+    map_out = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    cut_out = G_define_standard_option(G_OPT_V_OUTPUT);
+    cut_out->key = "cut";
+    cut_out->description = _("Name for output vector map containing a minimum cut");
+
+    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    afcol->key = "afcolumn";
+    afcol->required = NO;
+    afcol->description = _("Name of arc forward/both direction(s) capacity column");
+
+    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
+    abcol->key = "abcolumn";
+    abcol->required = NO;
+    abcol->description = _("Name of arc backward direction capacity column");
+
+    fieldsource_opt = G_define_standard_option(G_OPT_V_FIELD);
+    fieldsource_opt->key = "source_layer";
+    fieldsource_opt->label = _("Source layer number or name");
+    fieldsource_opt->guisection = _("Source");
+
+    catsource_opt = G_define_standard_option(G_OPT_V_CATS);
+    catsource_opt->key = "source_cats";
+    catsource_opt->label = _("Source category values");
+    catsource_opt->guisection = _("Source");
+
+    wheresource_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    wheresource_opt->key = "source_where";
+    wheresource_opt->label =
+	_("Source WHERE conditions of SQL statement without 'where' keyword");
+    wheresource_opt->guisection = _("Source");
+
+    fieldsink_opt = G_define_standard_option(G_OPT_V_FIELD);
+    fieldsink_opt->key = "sink_layer";
+    fieldsink_opt->label = _("Sink layer number or name");
+    fieldsink_opt->guisection = _("Sink");
+
+    catsink_opt = G_define_standard_option(G_OPT_V_CATS);
+    catsink_opt->key = "sink_cats";
+    catsink_opt->label = _("Sink category values");
+    catsink_opt->guisection = _("Sink");
+
+    wheresink_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    wheresink_opt->key = "sink_where";
+    wheresink_opt->label =
+	_("Sink WHERE conditions of SQL statement without 'where' keyword");
+    wheresink_opt->guisection = _("Sink");
+
+    /* options and flags parser */
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+    find_cut = (cut_out->answer[0]);
+    /* 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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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 (find_cut && 0 > Vect_open_new(&cut_map, cut_out->answer, with_z)) {
+	Vect_close(&In);
+	Vect_close(&Out);
+	G_fatal_error(_("Unable to create vector map <%s>"), cut_out->answer);
+    }
+
+    /* parse filter option and select appropriate lines */
+    layer = atoi(field_opt->answer);
+
+    /* 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);
+    db_init_string(&sql);
+    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 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);
+
+    source_list = Vect_new_list();
+    sink_list = Vect_new_list();
+
+    if (NetA_initialise_varray
+	(&In, atoi(fieldsource_opt->answer), GV_POINT, wheresource_opt->answer,
+	 catsource_opt->answer, &varray_source) == 2)
+	G_fatal_error(_("Neither %s nor %s was given"), catsource_opt->key,
+		      wheresource_opt->key);
+    if (NetA_initialise_varray
+	(&In, atoi(fieldsink_opt->answer), GV_POINT, wheresink_opt->answer,
+	 catsink_opt->answer, &varray_sink) == 2)
+	G_fatal_error(_("Neither %s nor %s was given"), catsink_opt->key,
+		      wheresink_opt->key);
+
+
+    NetA_varray_to_nodes(&In, varray_source, source_list, NULL);
+    NetA_varray_to_nodes(&In, varray_sink, sink_list, NULL);
+
+    if (source_list->n_values == 0)
+	G_fatal_error(_("No sources"));
+
+    if (sink_list->n_values == 0)
+	G_fatal_error(_("No sinks"));
+
+    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, source_list, sink_list, flow);
+    G_debug(3, "Max flow: %d", total_flow);
+    if (find_cut) {
+	cut = Vect_new_list();
+	total_flow = NetA_min_cut(graph, source_list, sink_list, flow, cut);
+	G_debug(3, "Min cut: %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, %f)", Fi->table, cat,
+		    flow[i] / (double)In.cost_multip);
+	    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));
+	    };
+	}
+    }
+
+    if (find_cut) {
+	for (i = 0; i < cut->n_values; i++) {
+	    int type = Vect_read_line(&In, Points, Cats, cut->value[i]);
+	    Vect_write_line(&cut_map, type, Points, Cats);
+	}
+	Vect_destroy_list(cut);
+
+	Vect_build(&cut_map);
+	Vect_close(&cut_map);
+    }
+
+    db_commit_transaction(driver);
+    db_close_database_shutdown_driver(driver);
+
+    G_free(flow);
+    Vect_destroy_list(source_list);
+    Vect_destroy_list(sink_list);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    exit(EXIT_SUCCESS);
+}

Разлика између датотеке није приказан због своје велике величине
+ 37 - 0
vector/v.net.flow/v.net.flow.html


+ 12 - 0
vector/v.net.spanningtree/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.spanningtree
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 126 - 0
vector/v.net.spanningtree/main.c

@@ -0,0 +1,126 @@
+
+/****************************************************************
+ *
+ * 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/vector.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;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out;
+    struct Option *field_opt, *accol;
+    struct Flag *geo_f;
+    int with_z;
+    int layer, mask_type;
+    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();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("spanning tree"));
+    module->description = _("Computes minimum spanning tree for the network.");
+
+    /* 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);
+
+    accol = G_define_standard_option(G_OPT_DB_COLUMN);
+    accol->key = "accol";
+    accol->required = NO;
+    accol->description = _("Name of 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);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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);
+
+    Vect_net_build_graph(&In, mask_type, layer, 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", 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);
+}

Разлика између датотеке није приказан због своје велике величине
+ 28 - 0
vector/v.net.spanningtree/v.net.spanningtree.html


+ 12 - 0
vector/v.net.timetable/Makefile

@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.net.timetable
+
+LIBES = $(VECTORLIB) $(GISLIB) $(NETALIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	

+ 549 - 0
vector/v.net.timetable/main.c

@@ -0,0 +1,549 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.net.timetable
+ *
+ * AUTHOR(S):  Daniel Bundala
+ *
+ * PURPOSE:    Routing with timetables
+ *
+ * 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/vector.h>
+#include <grass/glocale.h>
+#include <grass/neta.h>
+
+struct Map_info In, Out;
+neta_timetable_result result;
+neta_timetable timetable;
+
+struct segment
+{
+    int from_stop, to_stop;
+    int from_time, to_time;
+    int route;
+    struct segment *next;
+} head;
+
+double *stop_x, *stop_y, *stop_z;
+int *stop_ids, *route_ids;
+int *found, *stop_node, *edges, nnodes;
+struct ilist **lines;
+dglGraph_s *graph;
+
+void init_route(int connection, int stop)
+{
+    if (result.prev_stop[connection][stop] == -1)
+	return;
+    struct segment *seg = (struct segment *)G_calloc(1, sizeof(struct segment));
+    int prev_conn = result.prev_conn[connection][stop];
+    seg->next = head.next;
+    head.next = seg;
+    seg->route = result.prev_route[connection][stop];
+    seg->from_stop = result.prev_stop[connection][stop];
+    seg->to_stop = stop;
+    if (seg->route == -2)
+	seg->from_time = result.dst[prev_conn][seg->from_stop];
+    else
+	seg->from_time =
+	    NetA_timetable_get_route_time(&timetable, seg->from_stop,
+					  seg->route);
+    seg->to_time = result.dst[connection][stop];
+    init_route(prev_conn, seg->from_stop);
+}
+
+void release_route(struct segment *seg)
+{
+    if (!seg)
+	return;
+    release_route(seg->next);
+    G_free(seg->next);
+}
+
+static int int_cmp(const void *a, const void *b)
+{
+    return *(int *)a - *(int *)b;
+}
+
+void init_database(struct Map_info *Out, dbDriver ** driver,
+		   struct field_info **Fi, int layer, char *columns)
+{
+    dbString sql;
+    char buf[2000];
+    /* Create table */
+    *Fi = Vect_default_field_info(Out, layer, NULL, GV_MTABLE);
+    Vect_map_add_dblink(Out, layer, NULL, (*Fi)->table, "cat", (*Fi)->database,
+			(*Fi)->driver);
+    db_init_string(&sql);
+    *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 (%s)", (*Fi)->table, columns);
+
+    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_free_string(&sql);
+    db_begin_transaction(*driver);
+}
+
+void insert_point(dbDriver * driver, char *table, int cat, int path,
+		  int stop_id, int index, int arrival_time, int departure_time)
+{
+    char buf[2000];
+    dbString sql;
+    db_init_string(&sql);
+
+    sprintf(buf, "insert into %s values (%d, %d, %d, %d, %d, %d)", table, cat,
+	    path, stop_id, index, arrival_time, departure_time);
+    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_free_string(&sql);
+}
+
+void insert_line(dbDriver * driver, char *table, int cat, int path, int from_id,
+		 int to_id, int route_id, int index, int from_time, int to_time)
+{
+    char buf[2000];
+    dbString sql;
+    db_init_string(&sql);
+
+    sprintf(buf, "insert into %s values (%d, %d, %d, %d, %d, %d, %d, %d)",
+	    table, cat, path, from_id, to_id, route_id, index, from_time,
+	    to_time);
+    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_free_string(&sql);
+}
+
+int get_nearest_stop(double x, double y, double z, int with_z)
+{
+    int i, mini = -1;
+    double mind, d;
+    for (i = 0; i < timetable.stops; i++) {
+	if (!found[i])
+	    continue;
+	d = Vect_points_distance(x, y, z, stop_x[i], stop_y[i], stop_z[i],
+				 with_z);
+	if (mini == -1 || d < mind) {
+	    mind = d;
+	    mini = i;
+	}
+    }
+    return mini;
+}
+
+void write_subroute(struct segment *seg, struct line_pnts *line, int line_id)
+{
+    int i, j, r;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    struct ilist *list;
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+    list = Vect_new_list();
+    r = seg->route;
+
+    Vect_cat_set(Cats, 2, line_id);
+
+    if (r < 0) {
+	Vect_write_line(&Out, GV_LINE, line, Cats);
+	return;
+    }
+
+    for (i = 0; i < nnodes; i++)
+	edges[i] = 0;
+    for (i = 0; i < lines[r]->n_values; i++)
+	edges[lines[r]->value[i]] = 1;
+
+    for (i = 0; i < timetable.route_length[r]; i++)
+	if (timetable.route_stops[r][i] == seg->from_stop)
+	    break;
+    for (; timetable.route_stops[r][i] != seg->to_stop; i++)
+	if (NetA_find_path
+	    (graph, stop_node[timetable.route_stops[r][i]],
+	     stop_node[timetable.route_stops[r][i + 1]], edges, list) != -1) {
+	    for (j = 0; j < list->n_values; j++) {
+		int type = Vect_read_line(&In, Points, NULL, list->value[j]);
+		Vect_write_line(&Out, type, Points, Cats);
+	    }
+	}
+	else {
+	    G_warning(_("Could not find a path between stops %d and %d"),
+		      stop_ids[timetable.route_stops[r][i]],
+		      stop_ids[timetable.route_stops[r][i + 1]]);
+	}
+
+    Vect_destroy_list(list);
+    Vect_destroy_cats_struct(Cats);
+    Vect_destroy_line_struct(Points);
+}
+
+int main(int argc, char *argv[])
+{
+    static struct line_pnts *Points, *Cur, *Prev;
+    struct line_cats *Counter_Cats, *Cats;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *map_in, *map_out;
+    struct Option *field_opt, *walk_layer_opt, *path_layer_opt, *route_id_opt,
+	*stop_time_opt, *to_stop_opt, *walk_length_opt;
+    int with_z;
+    int layer, mask_type, path_layer;
+    int from_stop, to_stop, start_time, min_change, max_changes, walking_change,
+	ret;
+    int *stop_pnt, i, nlines, point_counter, *route_pnt;
+    int line_counter, index, j;
+    struct segment *cur;
+    char buf[2000];
+
+    /* Attribute table */
+    dbDriver *point_driver, *line_driver;
+    struct field_info *point_Fi, *line_Fi;
+
+    /* initialize GIS environment */
+    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("network"));
+    G_add_keyword(_("shortest path"));
+    module->description = _("Finds shortest path using timetables.");
+
+    /* Define the different options as defined in gis.h */
+    map_in = G_define_standard_option(G_OPT_V_INPUT);
+    field_opt = G_define_standard_option(G_OPT_V_FIELD);
+
+    map_out = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    walk_layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
+    walk_layer_opt->key = "walk_layer";
+    walk_layer_opt->answer = "-1";
+    walk_layer_opt->label = _("Layer number or name with walking connections or -1");
+
+    path_layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
+    path_layer_opt->key = "path_layer";
+    path_layer_opt->answer = "-1";
+    path_layer_opt->label = _("Layer number or name with route paths or -1");
+
+    route_id_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    route_id_opt->key = "route_id";
+    route_id_opt->required = YES;
+    route_id_opt->answer = "route_id";
+    route_id_opt->description = _("Name of column name with route ids");
+
+    stop_time_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    stop_time_opt->key = "stop_time";
+    stop_time_opt->required = YES;
+    stop_time_opt->answer = "stop_time";
+    stop_time_opt->description = _("Name of column name with stop timestamps");
+
+    to_stop_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    to_stop_opt->key = "to_stop";
+    to_stop_opt->required = YES;
+    to_stop_opt->answer = "to_stop";
+    to_stop_opt->description = _("Name of column name with stop ids");
+
+    walk_length_opt = G_define_standard_option(G_OPT_DB_COLUMN);
+    walk_length_opt->key = "walk_length";
+    walk_length_opt->required = YES;
+    walk_length_opt->answer = "length";
+    walk_length_opt->description = _("Name of column name with walk lengths");
+    
+    /* 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();
+    Counter_Cats = Vect_new_cats_struct();
+    Cur = Vect_new_line_struct();
+    Prev = Vect_new_line_struct();
+
+    Vect_check_input_output_name(map_in->answer, map_out->answer,
+				 GV_FATAL_EXIT);
+
+    Vect_set_open_level(2);
+
+    if (1 > Vect_open_old(&In, map_in->answer, ""))
+	G_fatal_error(_("Unable to open vector map <%s>"),
+		      map_in->answer);
+
+    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);
+    path_layer = atoi(path_layer_opt->answer);
+
+
+    init_database(&Out, &point_driver, &point_Fi, 1,
+		  "cat integer, path_id integer, stop_id integer, index integer, arr_time integer, dep_time integer");
+    init_database(&Out, &line_driver, &line_Fi, 2,
+		  "cat integer, path_id integer, from_id integer, to_id integer, route_id integer, index integer, from_time integer, to_time integer");
+
+    Vect_copy_head_data(&In, &Out);
+    Vect_hist_copy(&In, &Out);
+    Vect_hist_command(&Out);
+
+    if (NetA_init_timetable_from_db
+	(&In, layer, atoi(walk_layer_opt->answer), route_id_opt->answer,
+	 stop_time_opt->answer, to_stop_opt->answer, walk_length_opt->answer,
+	 &timetable, &route_ids, &stop_ids) != 0)
+	G_fatal_error(_("Could not initialize the timetables"));
+
+    stop_x = (double *)G_calloc(timetable.stops, sizeof(double));
+    stop_y = (double *)G_calloc(timetable.stops, sizeof(double));
+    stop_z = (double *)G_calloc(timetable.stops, sizeof(double));
+    found = (int *)G_calloc(timetable.stops, sizeof(int));
+
+    if (!stop_x || !stop_y || !stop_z || !found)
+	G_fatal_error(_("Out of memory"));
+
+    if (path_layer > 0) {
+	nnodes = Vect_get_num_nodes(&In);
+	stop_node = (int *)G_calloc(timetable.stops, sizeof(int));
+	lines =
+	    (struct ilist **)G_calloc(timetable.routes, sizeof(struct ilist *));
+	edges = (int *)G_calloc(nnodes + 1, sizeof(int));
+	if (!edges || !stop_node || !lines)
+	    G_fatal_error(_("Out of memory"));
+	for (i = 0; i < timetable.routes; i++)
+	    lines[i] = Vect_new_list();
+
+	Vect_net_build_graph(&In, mask_type, path_layer, 0, NULL, NULL, NULL, 0,
+			     0);
+	graph = &(In.graph);
+    }
+
+
+    nlines = Vect_get_num_lines(&In);
+    for (i = 1; i <= nlines; i++) {
+	int type = Vect_read_line(&In, Points, Cats, i);
+	if (type == GV_POINT) {
+	    int cat, stop, node;
+	    for (j = 0; j < Cats->n_cats; j++) {
+		if (Cats->field[j] != layer)
+		    continue;
+		cat = Cats->cat[j];
+		stop_pnt =
+		    (int *)bsearch(&cat, stop_ids, timetable.stops, sizeof(int),
+				   int_cmp);
+		if (!stop_pnt)
+		    continue;
+
+		stop = stop_pnt - stop_ids;
+		stop_x[stop] = Points->x[0];
+		stop_y[stop] = Points->y[0];
+		stop_z[stop] = Points->z[0];
+		if (path_layer > 0) {
+		    Vect_get_line_nodes(&In, i, &node, NULL);
+		    if (!stop_node[stop])
+			stop_node[stop] = node;
+		}
+		found[stop] = 1;
+	    }
+	}
+	else if (type == GV_LINE && path_layer > 0) {
+	    int cat;
+	    for (j = 0; j < Cats->n_cats; j++) {
+		if (Cats->field[j] != path_layer)
+		    continue;
+		cat = Cats->cat[j];
+		route_pnt =
+		    (int *)bsearch(&cat, route_ids, timetable.routes,
+				   sizeof(int), int_cmp);
+		if (!route_pnt)
+		    continue;
+		Vect_list_append(lines[route_pnt - route_ids], i);
+	    }
+	}
+    }
+
+    for (i = 0; i < timetable.stops; i++)
+	if (!found[i])
+	    G_warning(_("No stop with category: %d"), stop_ids[i]);
+
+    point_counter = line_counter = 1;
+    while (1) {
+	double fx, fy, tx, ty;
+	int path_id;
+	if (fgets(buf, sizeof(buf), stdin) == NULL)
+	    break;
+	ret =
+	    sscanf(buf, "%d %lf %lf %lf %lf %d %d %d %d", &path_id, &fx, &fy,
+		   &tx, &ty, &start_time, &min_change, &max_changes,
+		   &walking_change);
+	if (ret == 9) {
+	    from_stop = get_nearest_stop(fx, fy, 0, with_z);
+	    to_stop = get_nearest_stop(tx, ty, 0, with_z);
+	}
+	else {
+	    ret =
+		sscanf(buf, "%d %d %d %d %d %d %d", &path_id, &from_stop,
+		       &to_stop, &start_time, &min_change, &max_changes,
+		       &walking_change);
+	    if (ret < 7) {
+		G_warning(_("Wrong input format: %s"), buf);
+		continue;
+	    }
+
+	    stop_pnt =
+		(int *)bsearch(&from_stop, stop_ids, timetable.stops,
+			       sizeof(int), int_cmp);
+	    if (!stop_pnt) {
+		G_warning(_("No stop with category: %d"), from_stop);
+		continue;
+	    }
+	    from_stop = stop_pnt - stop_ids;
+	    stop_pnt =
+		(int *)bsearch(&to_stop, stop_ids, timetable.stops, sizeof(int),
+			       int_cmp);
+	    if (!stop_pnt) {
+		G_warning(_("No stop with category: %d"), to_stop);
+		continue;
+	    }
+	    to_stop = stop_pnt - stop_ids;
+	}
+
+	if (from_stop == to_stop) {
+	    G_warning(_("'From' and 'To' stops are the same"));
+	    continue;
+	}
+
+	ret =
+	    NetA_timetable_shortest_path(&timetable, from_stop, to_stop,
+					 start_time, min_change, max_changes,
+					 walking_change, &result);
+	if (ret == -1) {
+	    G_warning(_("No path between the stops"));
+	    continue;
+	}
+	head.next = NULL;
+	init_route(result.routes, to_stop);
+	NetA_timetable_result_release(&result);
+
+	Vect_reset_line(Points);
+	Vect_reset_line(Cur);
+	Vect_reset_line(Prev);
+	Vect_append_point(Cur, stop_x[from_stop], stop_y[from_stop],
+			  stop_z[from_stop]);
+
+	Vect_reset_cats(Cats);
+	Vect_cat_set(Cats, 1, point_counter);
+	Vect_write_line(&Out, GV_POINT, Cur, Cats);
+	insert_point(point_driver, point_Fi->table, point_counter, path_id,
+		     stop_ids[from_stop], 1, start_time, head.next->from_time);
+	point_counter++;
+	Vect_append_points(Prev, Cur, GV_FORWARD);
+	index = 1;
+	for (cur = head.next; cur; cur = cur->next) {
+	    int dept_time, route_id;
+	    if (cur->route == -2) {
+		printf("Walk ");
+		route_id = -1;
+	    }
+	    else {
+		printf("Route %d, ", route_ids[cur->route]);
+		route_id = route_ids[cur->route];
+	    }
+	    printf("from %d leaving at %d arriving to %d at %d\n",
+		   stop_ids[cur->from_stop], cur->from_time,
+		   stop_ids[cur->to_stop], cur->to_time);
+
+	    Vect_reset_line(Cur);
+	    Vect_reset_line(Points);
+	    Vect_reset_cats(Cats);
+
+	    Vect_append_point(Cur, stop_x[cur->to_stop], stop_y[cur->to_stop],
+			      stop_z[cur->to_stop]);
+
+	    Vect_cat_set(Cats, 1, point_counter);
+	    Vect_write_line(&Out, GV_POINT, Cur, Cats);
+	    if (cur->next)
+		dept_time = cur->next->from_time;
+	    else
+		dept_time = cur->to_time;
+	    insert_point(point_driver, point_Fi->table, point_counter,
+			 path_id, stop_ids[cur->to_stop], index + 1,
+			 cur->to_time, dept_time);
+
+	    Vect_append_points(Points, Prev, GV_FORWARD);
+	    Vect_append_points(Points, Cur, GV_FORWARD);
+	    Vect_reset_cats(Cats);
+	    Vect_cat_set(Cats, 2, line_counter);
+	    if (path_layer <= 0)
+		Vect_write_line(&Out, GV_LINE, Points, Cats);
+	    else
+		write_subroute(cur, Points, line_counter);
+	    insert_line(line_driver, line_Fi->table, line_counter, path_id,
+			stop_ids[cur->from_stop], stop_ids[cur->to_stop],
+			route_id, index, cur->from_time, cur->to_time);
+
+	    Vect_reset_line(Prev);
+	    Vect_append_points(Prev, Cur, GV_FORWARD);
+
+	    point_counter++;
+	    line_counter++;
+	    index++;
+	}
+	release_route(&head);
+    }
+    db_commit_transaction(line_driver);
+    db_commit_transaction(point_driver);
+    db_close_database_shutdown_driver(line_driver);
+    db_close_database_shutdown_driver(point_driver);
+
+    Vect_build(&Out);
+
+    Vect_close(&In);
+    Vect_close(&Out);
+
+    G_free(stop_x);
+    G_free(stop_y);
+    G_free(stop_z);
+    G_free(stop_node);
+
+    exit(EXIT_SUCCESS);
+}

Разлика између датотеке није приказан због своје велике величине
+ 86 - 0
vector/v.net.timetable/v.net.timetable.html