[GRASS-SVN] r70625 - grass/trunk/vector/v.distance
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Feb 19 13:19:28 PST 2017
Author: hcho
Date: 2017-02-19 13:19:28 -0800 (Sun, 19 Feb 2017)
New Revision: 70625
Modified:
grass/trunk/vector/v.distance/main.c
Log:
v.distance: create a new table for non -a runs; code cleanup
Modified: grass/trunk/vector/v.distance/main.c
===================================================================
--- grass/trunk/vector/v.distance/main.c 2017-02-19 18:59:26 UTC (rev 70624)
+++ grass/trunk/vector/v.distance/main.c 2017-02-19 21:19:28 UTC (rev 70625)
@@ -5,13 +5,15 @@
*
* AUTHOR(S): - J.Soimasuo 15.9.1994, University of Joensuu,
* Faculty of Forestry, Finland
- * - some additions 2002 Markus Neteler
- * - updated to 5.7 by Radim Blazek 2003
+ * - some additions by Markus Neteler (2002)
+ * - updated to 5.7 by Radim Blazek (2003)
* - OGR support by Martin Landa <landa.martin gmail.com> (2009)
- * - speed-up for dmax != 0 Markus Metz 2010
- * - support all features Markus Metz 2012
+ * - speed-up for dmax != 0 by Markus Metz (2010)
+ * - support all features by Markus Metz (2012)
+ * - create a new table for non -a runs by Huidae Cho (2017)
*
- * PURPOSE: Calculates distance from a point to nearest feature in vector layer.
+ * PURPOSE: Calculates distance from a point to nearest feature in vector
+ * layer.
*
* COPYRIGHT: (C) 2002-2017 by the GRASS Development Team
*
@@ -31,14 +33,37 @@
#include <grass/vector.h>
#include "local_proto.h"
+/* Supported command lines:
+ * from= to= upload= -p # print
+ * from= to= upload= column= # update the "from" table
+ * from= to= output= # create map
+ * from= to= output= upload= -p # create map & print
+ * from= to= output= upload= column= # create map & update the "from" table
+ * from= to= output= upload= column= table=
+ * # create map & table
+ * -a from= to= upload= -p # print for all
+ * -a from= to= output= # create map for all
+ * -a from= to= output= upload= -p # create map for all & print
+ * -a from= to= output= upload= column= table=
+ * # create map for all & create table
+ *
+ * Unsupported command lines:
+ * from= to= # nothing to do
+ * from= to= upload= column= table= # cannot create table without output
+ * -a from= to= # nothing to do
+ *X-a from= to= upload= column= # cannot update the "from" table
+ * # because #new != #"from"
+ * -a from= to= upload= column= table= # cannot create table without output
+ *X-a from= to= output= upload= column= # cannot update the "from" table
+ * # because #new != #"from"
+ *
+ * X: manual dependency checks
+ */
+
/* TODO: support all types (lines, boundaries, areas for 'from' (from_type) */
int main(int argc, char *argv[])
{
- int i, j;
- int print_as_matrix; /* only for do_all=TRUE */
- int do_all; /* calculate from each to each within the threshold */
- int upload;
struct GModule *module;
struct {
struct Option *from, *to, *from_type, *to_type,
@@ -50,6 +75,15 @@
struct {
struct Flag *print, *all;
} flag;
+
+ int print; /* -p: print to stdout */
+ int create_map; /* output=: create a new map */
+ int create_table; /* table=: create a new table */
+ int update_table; /* column= !table=: update the "from" table */
+ int do_all; /* -a: calculate from each to each within the threshold */
+ int print_as_matrix; /* only for do_all=TRUE */
+
+ int i, j;
char *desc;
struct Map_info From, To, Out, *Outp;
int from_type, to_type, from_field, to_field, with_z;
@@ -81,11 +115,6 @@
dbColumn *column;
char *sep;
- do_all = FALSE;
- upload = FALSE;
- print_as_matrix = FALSE;
- column = NULL;
-
G_gisinit(argv[0]);
module = G_define_module();
@@ -201,8 +230,7 @@
opt.table = G_define_standard_option(G_OPT_DB_TABLE);
opt.table->gisprompt = "new_dbtable,dbtable,dbtable";
- opt.table->description =
- _("Name of table created when the 'distance to all' flag is used");
+ opt.table->description = _("Name of table created");
opt.sep = G_define_standard_option(G_OPT_F_SEP);
opt.sep->label = _("Field separator for printing output to stdout");
@@ -219,7 +247,7 @@
flag.all->label =
_("Calculate distances to all features within the threshold");
flag.all->description =
- _("Output may be written to stdout using the 'print' flag "
+ _("Output may be written to stdout using the '-p' flag "
"or uploaded to a new table created by the 'table' option; "
"multiple 'upload' options may be used.");
@@ -229,42 +257,48 @@
opt.to->guidependency = G_store(buf1);
opt.to_field->guidependency = G_store(opt.to_column->key);
+ G_option_required(opt.upload, opt.out, NULL);
G_option_exclusive(opt.column, flag.print, NULL);
G_option_exclusive(opt.table, flag.print, NULL);
G_option_requires(opt.upload, flag.print, opt.column, NULL);
G_option_requires(opt.column, opt.upload, NULL);
G_option_requires(flag.print, opt.upload, NULL);
- G_option_requires_all(opt.table, flag.all, opt.upload, NULL);
+ G_option_requires_all(opt.table, opt.out, opt.upload, NULL);
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
+ geodesic = G_projection() == PROJECTION_LL;
+ if (geodesic)
+ line_distance = Vect_line_geodesic_distance;
+ else
+ line_distance = Vect_line_distance;
+
from_type = Vect_option_to_types(opt.from_type);
to_type = Vect_option_to_types(opt.to_type);
max = atof(opt.max->answer);
min = atof(opt.min->answer);
- if (flag.all->answer)
- do_all = TRUE;
- if (opt.column->answer || flag.print->answer)
- upload = TRUE;
+ print = flag.print->answer;
+ create_map = opt.out->answer != NULL;
+ create_table = opt.table->answer != NULL;
+ update_table = !create_table && opt.column->answer;
+ do_all = flag.all->answer;
- geodesic = G_projection() == PROJECTION_LL;
- if (geodesic)
- line_distance = Vect_line_geodesic_distance;
- else
- line_distance = Vect_line_distance;
+ if (do_all && update_table)
+ G_fatal_error(_("Updating the from= table is not supported with -a"));
/* Read upload and column options */
/* count */
i = 0;
while (opt.upload->answer && opt.upload->answers[i])
i++;
- if (strcmp(opt.from->answer, opt.to->answer) == 0 &&
- do_all && !opt.table->answer && i == 1)
- print_as_matrix = TRUE;
+ /* -a !table= upload=one_value from=map to=map: print as matrix */
+ print_as_matrix = do_all && !create_table && i == 1 &&
+ strcmp(opt.from->answer, opt.to->answer) == 0;
+
/* TODO: Known issue. Segmentation fault on print_as_matrix with dmin= or
* dmax= because count may not be nfrom^2. Needs to populate Near[] fully
* even if some near features are not found */
@@ -370,7 +404,7 @@
to_field = Vect_get_field_number(&To, opt.to_field->answer);
/* Open output vector */
- if (opt.out->answer) {
+ if (create_map) {
if (Vect_open_new(&Out, opt.out->answer, WITHOUT_Z) < 0)
G_fatal_error(_("Unable to create vector map <%s>"),
opt.out->answer);
@@ -471,8 +505,9 @@
db_init_string(&dbstr);
driver = NULL;
Fi = NULL;
- if (upload && !flag.print->answer && !do_all) {
+ column = NULL;
+ if (update_table) {
Fi = Vect_get_field(&From, from_field);
if (Fi == NULL)
G_fatal_error(_("Database connection not defined for layer <%s>"),
@@ -539,7 +574,7 @@
}
/* Check column types */
- if (upload && !flag.print->answer && !do_all) {
+ if (update_table) {
char *fcname = NULL;
int fctype, tctype;
@@ -1309,26 +1344,23 @@
}
/* open from driver */
- if (upload && !flag.print->answer) {
- if (!do_all) {
-
- 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);
- }
- else {
- driver = db_start_driver_open_database(NULL, NULL);
- if (driver == NULL)
- G_fatal_error(_("Unable to open default database"));
- }
+ if (update_table) {
+ 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);
}
+ else if (create_table) {
+ driver = db_start_driver_open_database(NULL, NULL);
+ if (driver == NULL)
+ G_fatal_error(_("Unable to open default database"));
+ }
update_ok = update_err = update_exist = update_notexist = update_dupl =
update_notfound = ncatexist = 0;
/* Update database / print to stdout / create output map */
- if (flag.print->answer) { /* print header */
+ if (print) { /* print header */
fprintf(stdout, "from_cat");
if (do_all)
fprintf(stdout, "%sto_cat", sep);
@@ -1339,7 +1371,7 @@
}
fprintf(stdout, "\n");
}
- else if (do_all && opt.table->answer) { /* create new table */
+ else if (create_table) { /* create new table */
db_set_string(&stmt, "create table ");
db_append_string(&stmt, opt.table->answer);
if (Outp)
@@ -1384,7 +1416,7 @@
opt.table->answer);
}
- else if (upload && !do_all) { /* read existing cats from table */
+ else if (update_table) { /* read existing cats from table */
ncatexist =
db_select_int(driver, Fi->table, Fi->key, NULL, &catexist);
G_debug(1, "%d cats selected from the table", ncatexist);
@@ -1400,13 +1432,13 @@
if (driver)
db_begin_transaction(driver);
- if (!flag.print->answer) /* no printing */
+ if (!print) /* no printing */
G_message("Update vector attributes...");
for (i = 0; i < count; i++) {
dbCatVal *catval = 0;
- if (!flag.print->answer) /* no printing */
+ if (!print) /* no printing */
G_percent(i, count, 1);
/* Write line connecting nearest points */
@@ -1437,7 +1469,7 @@
db_CatValArray_get_value(&cvarr, Near[i].to_cat, &catval);
}
- if (flag.print->answer) { /* print only */
+ if (print) { /* print only */
/*
input and output is the same &&
calculate distances &&
@@ -1469,7 +1501,10 @@
fprintf(stdout, "\n");
}
}
- else if (do_all && opt.table->answer) { /* insert new record */
+ else if (create_table) { /* insert new record */
+ if (Near[i].count == 0) /* no nearest found */
+ continue;
+
if (!Outp)
sprintf(buf1, "insert into %s values ( %d ", opt.table->answer,
Near[i].from_cat);
@@ -1552,7 +1587,7 @@
update_err++;
}
}
- else if (upload) { /* update table */
+ else if (update_table) { /* update table */
/* check if exists in table */
cex =
(int *)bsearch((void *)&(Near[i].from_cat), catexist,
@@ -1666,18 +1701,18 @@
G_message(_("%d categories - no nearest feature found"),
update_notfound);
- if (upload && !flag.print->answer) {
+ if (update_table || create_table) {
db_close_database_shutdown_driver(driver);
db_free_string(&stmt);
/* print stats */
- if (do_all && opt.table->answer) {
+ if (create_table) {
G_message(_("%d distances calculated"), count);
G_message(_("%d records inserted"), update_ok);
if (update_err > 0)
G_message(_("%d insert errors"), update_err);
}
- else if (!do_all) {
+ else {
if (nfcats > 0)
G_verbose_message(_("%d categories read from the map"), nfcats);
if (ncatexist > 0)
@@ -1701,7 +1736,7 @@
Vect_close(&From);
if (Outp != NULL) {
- if (do_all && opt.table->answer) {
+ if (create_table) {
dbConnection connection;
db_set_default_connection();
More information about the grass-commit
mailing list