[GRASS-SVN] r32501 - grass/trunk/vector/v.random
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Aug 3 16:19:04 EDT 2008
Author: martinl
Date: 2008-08-03 16:19:04 -0400 (Sun, 03 Aug 2008)
New Revision: 32501
Modified:
grass/trunk/vector/v.random/description.html
grass/trunk/vector/v.random/main.c
Log:
marisn: Added random attribute value creation;
Updated documentation with examples
(merge from trunk, r32498)
Modified: grass/trunk/vector/v.random/description.html
===================================================================
--- grass/trunk/vector/v.random/description.html 2008-08-03 18:30:39 UTC (rev 32500)
+++ grass/trunk/vector/v.random/description.html 2008-08-03 20:19:04 UTC (rev 32501)
@@ -3,6 +3,35 @@
<EM>v.random</EM> randomly generates vector points within the
current region using the selected random number generator.
+<p><em>v.random</em> can generate also 3D vector points or
+write random value to attribute table. Point height range or
+attribute value range is controlled by specifying zmin and zmax values.
+Both z values are included in range (<em>zmin >= z <= zmax</em>).
+Generated random attribute value type can be controlled by column
+data type. Use <b>INTEGER</b> column type for integers and
+<b>DOUBLE PRECISION</b> for floating point numbers. Integer values are
+calculated by rounding random floating point number.
+
+<h2>EXAMPLES</h2>
+Generate 20 random points with binary attribute (only 0 or 1):
+<div class="code"><pre>
+v.random output=binary_random n=20 zmin=0 zmax=1 column='binary INTEGER'
+</pre></div>
+
+Get 20 random samples from raster map:
+<div class="code"><pre>
+v.random output=random_samples n=20
+v.db.addtable map=random_samples layer=1 columns='cat INTEGER, sample DOUBLE PRECISION'
+v.what.rast vector=random_samples raster=elevation.10m at PERMANENT layer=1 column=sample
+</pre></div>
+
+Generate 20 random points and sample attribute data from geology (vector) map:
+<div class="code"><pre>
+v.random output=random_samples n=20
+v.db.addtable map=random_samples layer=1 columns='cat integer, geology varchar(100)'
+v.what.vect vector=random_samples layer=1 column=geology qvector=geology at PERMANENT qlayer=1 qcolumn=label
+</pre></div>
+
<H2>SEE ALSO</H2>
UNIX man pages for <EM>rand(3)</EM> and <EM>drand48(3)</EM>.
@@ -11,7 +40,9 @@
<A HREF="g.region.html">g.region</a>,
<A HREF="r.random.html">r.random</a>,
<A HREF="v.perturb.html">v.perturb</A>,
-<A HREF="v.sample.html">v.sample</A></EM>
+<A HREF="v.sample.html">v.sample</A>
+<a href="v.what.rast.html">v.what.rast</a>
+<a href="v.what.vect.html">v.what.vect</a>
</EM>
<H2>BUGS</H2>
@@ -19,10 +50,7 @@
The RNG used by
<EM><A HREF="v.perturb.html">v.perturb</A></EM>
should probably be added to this program.<BR>
-Currently no attribute table is generated.
-Please send any bug fixes and comments to the GRASS development team.
-
<H2>AUTHOR</H2>
<A HREF="http://mccauley-usa.com/">James Darrell McCauley</A>
Modified: grass/trunk/vector/v.random/main.c
===================================================================
--- grass/trunk/vector/v.random/main.c 2008-08-03 18:30:39 UTC (rev 32500)
+++ grass/trunk/vector/v.random/main.c 2008-08-03 20:19:04 UTC (rev 32501)
@@ -36,6 +36,7 @@
#include <string.h>
#include <grass/gis.h>
#include <grass/Vect.h>
+#include <grass/dbmi.h>
#include <grass/glocale.h>
#ifndef RAND_MAX
@@ -54,9 +55,10 @@
int main(int argc, char *argv[])
{
- char *output;
- double (*rng) (), max;
- int i, n, b;
+ char *output, buf[2000];
+ double (*rng) ();
+ double max, zmin, zmax;
+ int i, n, b, type, usefloat;
struct Map_info Out;
struct line_pnts *Points;
struct line_cats *Cats;
@@ -64,12 +66,16 @@
struct GModule *module;
struct
{
- struct Option *output, *nsites, *zmin, *zmax;
+ struct Option *output, *nsites, *zmin, *zmax, *zcol;
} parm;
struct
{
struct Flag *rand, *drand48, *z, *notopo;
} flag;
+ struct field_info *Fi;
+ dbDriver *driver;
+ dbTable *table;
+ dbString sql;
G_gisinit(argv[0]);
@@ -90,15 +96,23 @@
parm.zmin->key = "zmin";
parm.zmin->type = TYPE_DOUBLE;
parm.zmin->required = NO;
- parm.zmin->description = _("Minimum z height (needs -z flag)");
+ parm.zmin->description = _("Minimum z height (needs -z flag or column name)");
parm.zmin->answer = "0.0";
parm.zmax = G_define_option();
parm.zmax->key = "zmax";
parm.zmax->type = TYPE_DOUBLE;
parm.zmax->required = NO;
- parm.zmax->description = _("Maximum z height (needs -z flag)");
+ parm.zmax->description = _("Maximum z height (needs -z flag or column name)");
parm.zmax->answer = "0.0";
+
+ parm.zcol = G_define_standard_option(G_OPT_COLUMN);
+ parm.zcol->key = "column";
+ parm.zcol->required = NO;
+ parm.zcol->multiple = NO;
+ parm.zcol->label = _("Column name and type (i.e. INTEGER, DOUBLE PRECISION) for z values");
+ parm.zcol->description =
+ _("Writes Z data to column instead of 3D vector");
flag.z = G_define_flag();
flag.z->key = 'z';
@@ -115,6 +129,10 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
+ if (flag.z->answer && parm.zcol->answer) {
+ G_fatal_error(_("v.random can't create 3D vector and attribute table at same time"));
+ }
+
output = parm.output->answer;
n = atoi(parm.nsites->answer);
b = (flag.drand48->answer == '\0') ? 0 : 1;
@@ -129,6 +147,74 @@
else
Vect_open_new(&Out, output, WITHOUT_Z);
+ /* Do we need to write random values into attribute table? */
+ if (parm.zcol->answer) {
+ Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
+ driver = db_start_driver_open_database(Fi->driver, Vect_subst_var(Fi->database, &Out));
+ if (driver == NULL) {
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+ Vect_subst_var(Fi->database, &Out), Fi->driver);
+ }
+ db_begin_transaction(driver);
+
+ db_init_string(&sql);
+ sprintf(buf, "create table %s (cat integer, %s)", Fi->table, parm.zcol->answer);
+ db_set_string(&sql, buf);
+ Vect_map_add_dblink(&Out, 1, NULL, Fi->table, "cat", Fi->database, Fi->driver);
+
+ /* Create table */
+ G_debug(3, db_get_string(&sql));
+ if (db_execute_immediate(driver, &sql) != DB_OK) {
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("Unable to create table: %s"),
+ db_get_string(&sql));
+ }
+
+ /* Grant */
+ if (db_grant_on_table
+ (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) {
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("Unable to grant privileges on table <%s>"),
+ Fi->table);
+ }
+
+ /* OK. Let's check what type of column user has created */
+ db_set_string(&sql, Fi->table);
+ if (db_describe_table(driver, &sql, &table) != DB_OK) {
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("Unable to describe table <%s>"),
+ Fi->table);
+ }
+
+ if (db_get_table_number_of_columns(table) != 2) {
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("Table should contain only two columns"));
+ }
+
+ type = db_get_column_sqltype(db_get_table_column(table, 1));
+ usefloat = -1;
+ if (type == DB_SQL_TYPE_SMALLINT || type == DB_SQL_TYPE_INTEGER)
+ usefloat = 0;
+ if (type == DB_SQL_TYPE_REAL || type == DB_SQL_TYPE_DOUBLE_PRECISION)
+ usefloat = 1;
+ if (usefloat < 0) {
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("You have created unsupported column type. This module supports only INTEGER"
+ " and DOUBLE PRECISION column types."));
+ }
+ }
+
Vect_hist_command(&Out);
if (b) {
@@ -145,10 +231,15 @@
G_get_window(&window);
+ if (flag.z->answer || parm.zcol->answer) {
+ zmax = atof(parm.zmax->answer);
+ zmin = atof(parm.zmin->answer);
+ }
+
Points = Vect_new_line_struct();
Cats = Vect_new_cats_struct();
- G_important_message(_("Generating points..."));
+ G_message(_("Generating points..."));
for (i = 0; i < n; ++i) {
double x, y, z;
@@ -157,22 +248,45 @@
Vect_reset_line(Points);
Vect_reset_cats(Cats);
- x = rng() / max * (window.west - window.east) + window.east;
- y = rng() / max * (window.north - window.south) + window.south;
+ x = rng() / max * (window.west - window.east) + window.east;
+ y = rng() / max * (window.north - window.south) + window.south;
-
if (flag.z->answer) {
- z = rng() / max * (atof(parm.zmax->answer) -
- atof(parm.zmin->answer)) +
- atof(parm.zmin->answer);
+ z = rng() / max * (zmax - zmin) + zmin;
Vect_append_point(Points, x, y, z);
}
else
Vect_append_point(Points, x, y, 0.0);
+ if (parm.zcol->answer) {
+ z = rng() / max * (zmax - zmin) + zmin;
+
+ sprintf(buf, "insert into %s values ( %d, ", Fi->table, i+1 );
+ db_set_string(&sql, buf);
+ /* Round random value if column is integer type */
+ if (usefloat)
+ sprintf(buf, "%f )", z);
+ else
+ sprintf(buf, "%.0f )", z);
+ db_append_string(&sql, buf);
+
+ G_debug(3, db_get_string ( &sql ));
+ if (db_execute_immediate (driver, &sql) != DB_OK) {
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+ Vect_delete(parm.output->answer);
+ G_fatal_error(_("Cannot insert new row: %s"), db_get_string ( &sql ));
+ }
+ }
+
Vect_cat_set(Cats, 1, i + 1);
Vect_write_line(&Out, GV_POINT, Points, Cats);
}
+
+ if (parm.zcol->answer) {
+ db_commit_transaction ( driver );
+ db_close_database_shutdown_driver ( driver );
+ }
if (!flag.notopo->answer) {
if (G_verbose() > G_verbose_min())
More information about the grass-commit
mailing list