[GRASS-SVN] r59256 - grass/trunk/vector/v.in.db
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Mar 15 06:00:33 PDT 2014
Author: martinl
Date: 2014-03-15 06:00:33 -0700 (Sat, 15 Mar 2014)
New Revision: 59256
Modified:
grass/trunk/vector/v.in.db/main.c
grass/trunk/vector/v.in.db/v.in.db.html
Log:
v.in.db: allow key option to be optional (currenly only supported when output DB driver is SQLite)
update manual accordingly
Modified: grass/trunk/vector/v.in.db/main.c
===================================================================
--- grass/trunk/vector/v.in.db/main.c 2014-03-15 11:51:01 UTC (rev 59255)
+++ grass/trunk/vector/v.in.db/main.c 2014-03-15 13:00:33 UTC (rev 59256)
@@ -25,12 +25,11 @@
int main(int argc, char *argv[])
{
- int i, cat, with_z, more, ctype, ret, nrows;
- char buf[2000];
+ int i, cat, with_z, more, ctype, nrows;
+ char buf[DB_SQL_MAX];
int count;
double coor[3];
int ncoor;
- int coltype;
struct Option *driver_opt, *database_opt, *table_opt;
struct Option *xcol_opt, *ycol_opt, *zcol_opt, *keycol_opt, *where_opt,
*outvect;
@@ -64,11 +63,11 @@
driver_opt = G_define_standard_option(G_OPT_DB_DRIVER);
driver_opt->options = db_list_drivers();
driver_opt->answer = (char *)db_get_default_driver_name();
- driver_opt->guisection = _("Connection");
+ driver_opt->guisection = _("Input DB");
database_opt = G_define_standard_option(G_OPT_DB_DATABASE);
database_opt->answer = (char *)db_get_default_database_name();
- database_opt->guisection = _("Connection");
+ database_opt->guisection = _("Input DB");
xcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
xcol_opt->key = "x";
@@ -87,7 +86,7 @@
keycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
keycol_opt->key = "key";
- keycol_opt->required = YES;
+ keycol_opt->required = NO;
keycol_opt->label = _("Name of column containing category number");
keycol_opt->description = _("Must refer to an integer column");
@@ -131,7 +130,8 @@
G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
fi->database, fi->driver);
}
-
+ db_set_error_handler_driver(driver);
+
/* check if target table already exists */
G_debug(3, "Output vector table <%s>, driver: <%s>, database: <%s>",
outvect->answer, db_get_default_driver_name(),
@@ -144,27 +144,42 @@
db_get_default_driver_name(),
db_get_default_database_name());
- coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer);
+ if (keycol_opt->answer) {
+ int coltype;
+ coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer);
- if (coltype == -1)
- G_fatal_error(_("Missing column <%s> in table <%s>"),
- keycol_opt->answer, table_opt->answer);
- if (coltype != DB_C_TYPE_INT)
- G_fatal_error(_("Data type of key column must be integer"));
+ if (coltype == -1)
+ G_fatal_error(_("Missing column <%s> in table <%s>"),
+ keycol_opt->answer, table_opt->answer);
+ if (coltype != DB_C_TYPE_INT)
+ G_fatal_error(_("Data type of key column must be integer"));
+ }
+ else {
+ if (same_table_flag->answer) {
+ G_fatal_error(_("Option <%s> must be specified when -%c flag is given"),
+ keycol_opt->key, same_table_flag->key);
+ }
+ if (strcmp(db_get_default_driver_name(), "sqlite") != 0)
+ G_fatal_error(_("Unable to define key column. This operation is not supported "
+ "by <%s> driver. You need to define <%s> option."),
+ fi->driver, keycol_opt->key);
+ }
+
/* Open select cursor */
- sprintf(buf, "select %s, %s, %s", keycol_opt->answer, xcol_opt->answer,
- ycol_opt->answer);
+ sprintf(buf, "SELECT %s, %s", xcol_opt->answer, ycol_opt->answer);
db_set_string(&sql, buf);
-
if (with_z) {
sprintf(buf, ", %s", zcol_opt->answer);
db_append_string(&sql, buf);
}
-
- sprintf(buf, " from %s", table_opt->answer);
+ if (keycol_opt->answer) {
+ sprintf(buf, ", %s", keycol_opt->answer);
+ db_append_string(&sql, buf);
+ }
+ sprintf(buf, " FROM %s", table_opt->answer);
db_append_string(&sql, buf);
-
+
if (where_opt->answer) {
sprintf(buf, " WHERE %s", where_opt->answer);
db_append_string(&sql, buf);
@@ -181,20 +196,26 @@
G_debug(2, "%d points selected", nrows);
- count = 0;
+ count = cat = 0;
G_message(_("Writing features..."));
while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
G_percent(count, nrows, 2);
/* key column */
- column = db_get_table_column(table, 0);
- ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
- if (ctype != DB_C_TYPE_INT)
- G_fatal_error(_("Key column must be integer"));
- value = db_get_column_value(column);
- cat = db_get_value_int(value);
+ if (keycol_opt->answer) {
+ column = db_get_table_column(table, with_z ? 3 : 2);
+ ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
+ if (ctype != DB_C_TYPE_INT)
+ G_fatal_error(_("Key column must be integer"));
+ value = db_get_column_value(column);
+ cat = db_get_value_int(value);
+ }
+ else {
+ cat++;
+ }
+ /* coordinates */
for (i = 0; i < ncoor; i++) {
- column = db_get_table_column(table, i + 1);
+ column = db_get_table_column(table, i);
ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
G_fatal_error(_("x/y/z column must be integer or double"));
@@ -218,34 +239,63 @@
}
G_percent(1, 1, 1);
+ /* close connection to input DB before copying attributes */
db_close_database_shutdown_driver(driver);
/* Copy table */
- G_message(_("Copying attributes..."));
if (!same_table_flag->answer) {
- if (where_opt->answer)
- ret =
- db_copy_table_where(driver_opt->answer, database_opt->answer,
- table_opt->answer, fi->driver,
- fi->database, fi->table,
- where_opt->answer);
- else
- ret =
- db_copy_table(driver_opt->answer, database_opt->answer,
- table_opt->answer, fi->driver, fi->database,
- fi->table);
- if (ret == DB_FAILED) {
- G_warning(_("Unable to copy table"));
+ G_message(_("Copying attributes..."));
+
+ if (DB_FAILED == db_copy_table_where(driver_opt->answer, database_opt->answer,
+ table_opt->answer,
+ fi->driver, fi->database, fi->table,
+ where_opt->answer)) { /* where can be NULL */
+ G_warning(_("Unable to copy table"));
}
else {
- Vect_map_add_dblink(&Map, 1, NULL, fi->table, keycol_opt->answer,
+ Vect_map_add_dblink(&Map, 1, NULL, fi->table,
+ keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
fi->database, fi->driver);
}
+
+ if (!keycol_opt->answer) {
+ /* TODO: implement for all DB drivers in generic way if
+ * possible */
+
+ 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);
+ }
+
+ /* add key column */
+ sprintf(buf, "ALTER TABLE %s ADD COLUMN %s INTEGER",
+ fi->table, GV_KEY_COLUMN);
+ db_set_string(&sql, buf);
+
+ if (db_execute_immediate(driver, &sql) != DB_OK) {
+ G_fatal_error(_("Unable to add key column <%s>: "
+ "SERIAL type is not supported by <%s>"),
+ GV_KEY_COLUMN, fi->driver);
+ }
+
+ /* update key column */
+ sprintf(buf, "UPDATE %s SET %s = _ROWID_",
+ fi->table, GV_KEY_COLUMN);
+ db_set_string(&sql, buf);
+
+ if (db_execute_immediate(driver, &sql) != DB_OK) {
+ G_fatal_error(_("Failed to update key column <%s>"),
+ GV_KEY_COLUMN);
+ }
+
+ }
}
else {
+ /* do not copy attributes, link original table */
Vect_map_add_dblink(&Map, 1, NULL, table_opt->answer,
- keycol_opt->answer, database_opt->answer,
- driver_opt->answer);
+ keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
+ database_opt->answer, driver_opt->answer);
}
Vect_build(&Map);
Modified: grass/trunk/vector/v.in.db/v.in.db.html
===================================================================
--- grass/trunk/vector/v.in.db/v.in.db.html 2014-03-15 11:51:01 UTC (rev 59255)
+++ grass/trunk/vector/v.in.db/v.in.db.html 2014-03-15 13:00:33 UTC (rev 59256)
@@ -1,73 +1,118 @@
<h2>DESCRIPTION</h2>
-<em>v.in.db</em>
-creates new vector (points) map from database table containing coordinates.
+<em>v.in.db</em> creates a new vector point map from database table or file
+containing coordinates.
-<h2>EXAMPLE</h2>
+<h2>NOTES</h2>
-<h3>1) Creating a map from PostgreSQL table:</h3>
+If GRASS comes with <a href="grass-ogr.html">OGR</a> support
+than <em>v.in.db</em> allows to import data from different input
+files, eg. CSV or MS Excel (assuming that GDAL/OGR library is compiled
+with this support).
+<p>
+<em>v.in.db</em> creates key column "cat" automatically
+when <b>key</b> option is not given. Note that this operation is
+possible to perform only when <b>-t</b> flag is not given. Currently,
+automated creation of key column is supported only when default DB
+driver for output vector map is <a href="grass-sqlite.html">SQLite
+driver</a> otherwise <b>key</b> option must be specified by the
+user. Default DB driver is defined
+by <em><a href="db.connect.html">db.connect</a></em>.
+
+<h2>EXAMPLES</h2>
+
+<h3>Creating a map from PostgreSQL table</h3>
+
<div class="code"><pre>
v.in.db driver=pg database="host=myserver.itc.it,dbname=mydb" \
table=pat_stazioni x=east y=north z=quota key=id output=pat_stazioni
</pre></div>
-<p>If an ID column is not not present in the PostgreSQL table,
-a new column should be added. See <a href="grass-pg.html">PostgreSQL DB driver</a>
-page for details.
-<h3>2) Creating a map from PostGIS:</h3>
+<p>If an ID column is not not present in the PostgreSQL table, a new
+column should be added. See <a href="grass-pg.html">PostgreSQL DB
+driver</a> page for details.
+<h3>Creating a map from PostGIS</h3>
+
To extract coordinate values from PostGIS, functions have to be used:
+
<div class="code"><pre>
v.in.db driver=pg database="host=myserver.itc.it,dbname=mydb" \
table=station x="x(geom)" y="y(geom)" z="z(geom)" key=id out=meteostations
</pre></div>
-<p>If an ID column is not not present in the PostgreSQL table,
-a new column should be added. See <a href="grass-pg.html">PostgreSQL DB driver</a>
-page for details.
-<p>Alternatively a point vector map can be imported from PostGIS
+<p>If an ID column is not not present in the PostgreSQL table, a new
+column should be added. See <a href="grass-pg.html">PostgreSQL DB
+driver</a> page for details.
+
+<p>Alternatively a vector point map can be imported from PostGIS
database using <em><a href="v.in.ogr.html">v.in.ogr</a></em>.
-<h3>3) Import of a points table (x, y, z) from DBF file to vector points map:</h3>
+<h3>Creating a map from MS Excel file</h3>
+A new vector point map is created from given list in MS Excel file
+file. The
+<b>database</b> option points to the file in MS Excel
+format. Option <b>table</b> is name of selected spreadsheet list.
+
<div class="code"><pre>
-#create vector map from DBF table (here, 'idcol' contains unique row IDs, 'z' is optional):
-#the 'database' parameter is the directory where the DBF file is stored:
+v.in.db table=List1 x=long y=lat z=height output=meteodata \
+ driver=ogr datatabase=meteodata.xls
+</pre></div>
+
+Note that <b>key</b> option is omitted. In this case <em>v.in.db</em>
+tries to add key column automatically. This
+requires <a href="grass-sqlite.html">SQLite</a> to be a default DB
+driver.
+
+<h3>Creating a map from DBF table</h3>
+
+A new 3D point vector map is created from DBF table. Column 'idcol'
+contains unique row IDs. The <b>database</b> option is the
+directory where the DBF file is stored.
+
+<div class="code"><pre>
v.in.db driver=dbf database=/home/user/tables/ table=pointsfile x=x y=y z=z \
key=idcol out=dtmpoints
-
-#check result:
-v.info dtmpoints
-v.info -c dtmpoints
</pre></div>
-<p>If an ID column is missing in the DBF file, it has to be added beforehand, e.g. with OpenOffice.
-Alternatively, import the table with <em>db.in.ogr</em> into GRASS and then with <em>v.in.db</em>
-from the imported table (<em>db.in.ogr</em> optionally adds an unique ID column).
-<h3>4) Import of a points table (x, y, z) from SQLite file to vector points map:</h3>
+To check result:
<div class="code"><pre>
-#create vector map from table in SQLITE database file (here, 'idcol' contains unique row IDs, 'z' is optional):
-#the 'database' parameter is the the SQLite database file with path:
-v.in.db driver=sqlite database=/home/user/tables/mysqlite.db table=pointsfile x=x y=y z=z \
- key=idcol out=dtmpoints
-
-#check result:
v.info dtmpoints
v.info -c dtmpoints
</pre></div>
-<p>If an ID column is missing in the table, it has to be added beforehand with 'sqlite3' or
-<em>db.execute</em>.
+<p>If DB driver for output vector map is different from SQLite driver
+and an ID column is missing in the DBF file, it has to be added
+beforehand, e.g. with OpenOffice. Alternatively, import the table
+with <em><a href="db.in.ogr.html">db.in.ogr</a></em> into GRASS and
+then with <em>v.in.db</em> from the imported table
+(<em><a href="db.in.ogr.html">db.in.ogr</a></em> optionally adds an
+unique ID column).
-<h3>5) Import of a points table (x, y, z) from DBF file to vector points map for selected points only:</h3>
-<p>The user can import only selected vector points from a table using the <em>where</em> parameter
-(see above for general DBF handling):<p><div class="code"><pre>
+<h3>Creating a point map from DBF table for selected records only</h3>
+
+<p>The user can import only selected vector points from a table using
+the <b>where</b> parameter (see above for general DBF handling):
+
+<div class="code"><pre>
v.in.db driver=dbf database=/home/user/tables/ table=pointsfile x=x y=y z=z \
key=idcol out=dtmpoints where="x NOT NULL and z > 100"
</pre></div>
+<h3>Creating a map from SQLite table</h3>
+
+A new vector point map is created from table in SQLite database
+file. Column 'idcol' contains unique row IDs. The
+<b>database</b> option is the the SQLite database file.
+
+<div class="code"><pre>
+v.in.db driver=sqlite database=/home/user/tables/mysqlite.db table=pointsfile x=x y=y z=z \
+ key=idcol out=dtmpoints
+</pre></div>
+
<h2>SEE ALSO</h2>
<em>
@@ -75,13 +120,17 @@
<a href="db.in.ogr.html">db.in.ogr</a>,
<a href="v.info.html">v.info</a>,
<a href="v.in.ogr.html">v.in.ogr</a>,
-<a href="v.to.db.html">v.to.db</a>,<br>
-<a href="sql.html">SQL support in GRASS GIS</a>
+<a href="v.to.db.html">v.to.db</a>
</em>
+<p>
+<a href="sql.html">SQL support in GRASS GIS</a>
-<h2>AUTHOR</h2>
-Radim Blazek
+<h2>AUTHORS</h2>
-<p><i>Last changed: $Date$</i>
+Radim Blazek<br>
+Various updates for GRASS 7 by Martin Landa, Czech Technical University in Prague, Czech Republic
+
+<p>
+<i>Last changed: $Date$</i>
More information about the grass-commit
mailing list