[GRASS-SVN] r51428 - grass/trunk/vector/v.net.allpairs
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Apr 13 14:51:39 EDT 2012
Author: mmetz
Date: 2012-04-13 11:51:38 -0700 (Fri, 13 Apr 2012)
New Revision: 51428
Modified:
grass/trunk/vector/v.net.allpairs/main.c
Log:
fix and speed up shortest path calcuation
Modified: grass/trunk/vector/v.net.allpairs/main.c
===================================================================
--- grass/trunk/vector/v.net.allpairs/main.c 2012-04-13 18:50:59 UTC (rev 51427)
+++ grass/trunk/vector/v.net.allpairs/main.c 2012-04-13 18:51:38 UTC (rev 51428)
@@ -24,6 +24,10 @@
#include <grass/dbmi.h>
#include <grass/neta.h>
+struct _spnode {
+ int cat, node;
+};
+
int main(int argc, char *argv[])
{
struct Map_info In, Out;
@@ -33,15 +37,14 @@
struct Option *map_in, *map_out;
struct Option *cat_opt, *afield_opt, *nfield_opt, *where_opt, *abcol,
*afcol, *ncol;
- struct Flag *geo_f, *newpoints_f;
+ struct Flag *geo_f;
int afield, nfield;
int chcat, with_z;
int mask_type;
struct varray *varray;
- dglGraph_s *graph;
- int i, j, geo, nnodes, nlines, max_cat, *cats;
- dglInt32_t **dist;
- char buf[2000], *output;
+ struct _spnode *spnode;
+ int i, j, geo, nnodes, nlines;
+ char buf[2000];
/* Attribute table */
dbString sql;
@@ -105,10 +108,6 @@
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);
@@ -172,9 +171,11 @@
G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
}
/*
- * if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
- * G_warning(_("Cannot create index"));
- */
+ if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK) {
+ if (strcmp(Fi->driver, "dbf"))
+ 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);
@@ -184,83 +185,77 @@
Vect_net_build_graph(&In, mask_type, afield, nfield,
afcol->answer, abcol->answer, ncol->answer, 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)
+ nnodes = Vect_get_num_primitives(&In, GV_POINT);
+
+ G_debug(1, "%d nodes", nnodes);
+ spnode = (struct _spnode *)G_calloc(nnodes, sizeof(struct _spnode));
+
+ if (!spnode)
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;
+ for (i = 0; i < nnodes; i++) {
+ spnode[i].cat = -1;
+ spnode[i].node = -1;
}
nlines = Vect_get_num_lines(&In);
- max_cat = 0;
+ nnodes = 0;
for (i = 1; i <= nlines; i++) {
+ int node, cat;
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;
+ if (type != GV_POINT)
+ continue;
- /* Vect_get_line_nodes(&In, i, &node, NULL); */
- node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
- Vect_cat_get(Cats, nfield, &cats[node]);
- if (cats[node] != -1) {
+ /* Vect_get_line_nodes(&In, i, &node, NULL); */
+ node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
+ if (node) {
+ Vect_cat_get(Cats, nfield, &cat);
+ if (cat != -1) {
Vect_write_line(&Out, GV_POINT, Points, Cats);
- if (!chcat || varray->c[i])
- output[node] = 'y';
+ if (!chcat || varray->c[i]) {
+ spnode[nnodes].cat = cat;
+ spnode[nnodes].node = node;
+ nnodes++;
+ }
}
}
-
}
- 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);
- }
+ /* check for duplicate cats */
+
G_message(_("Writing data into the table..."));
G_percent_reset();
- for (i = 1; i <= nnodes; i++) {
+ for (i = 0; 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));
- };
- }
+ for (j = 0; j < nnodes; j++) {
+ double cost;
+ int ret;
+
+ ret = Vect_net_shortest_path(&In, spnode[i].node,
+ spnode[j].node, NULL, &cost);
+
+ if (ret == -1)
+ cost = -1;
+
+ sprintf(buf, "insert into %s values (%d, %d, %f)",
+ Fi->table, spnode[i].cat, spnode[j].cat, 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));
+ }
+ }
}
+ G_percent(1, 1, 1);
+
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);
More information about the grass-commit
mailing list