~ubuntu-branches/ubuntu/wily/grass/wily

« back to all changes in this revision

Viewing changes to vector/v.random/main.c

Tags: 7.0.0~rc1+ds1-1~exp1
* New upstream release candidate.
* Repack upstream tarball, remove precompiled Python objects.
* Add upstream metadata.
* Update gbp.conf and Vcs-Git URL to use the experimental branch.
* Update watch file for GRASS 7.0.
* Drop build dependencies for Tcl/Tk, add build dependencies:
  python-numpy, libnetcdf-dev, netcdf-bin, libblas-dev, liblapack-dev
* Update Vcs-Browser URL to use cgit instead of gitweb.
* Update paths to use grass70.
* Add configure options: --with-netcdf, --with-blas, --with-lapack,
  remove --with-tcltk-includes.
* Update patches for GRASS 7.
* Update copyright file, changes:
  - Update copyright years
  - Group files by license
  - Remove unused license sections
* Add patches for various typos.
* Fix desktop file with patch instead of d/rules.
* Use minimal dh rules.
* Bump Standards-Version to 3.9.6, no changes.
* Use dpkg-maintscript-helper to replace directories with symlinks.
  (closes: #776349)
* Update my email to use @debian.org address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * AUTHOR(S):    James Darrell McCauley darrell@mccauley-usa.com
7
7
 *               http://mccauley-usa.com/
 
8
 *               OGR support by Martin Landa <landa.martin gmail.com>
 
9
 *               Area support by Markus Metz
8
10
 *
9
11
 * PURPOSE:      Randomly generate a 2D/3D GRASS vector points map.
10
12
 *
11
 
 * COPYRIGHT:    (C) 2003-2007, 2010 by the GRASS Development Team
12
 
 *
13
 
 *               This program is free software under the
14
 
 *               GNU General Public License (>=v2).
15
 
 *               Read the file COPYING that comes with GRASS
16
 
 *               for details.
17
 
 *
18
 
**************************************************************/
19
 
/*
20
13
 * Modification History:
21
14
 *
22
15
 * s.rand v 0.5B <25 Jun 1995> Copyright (c) 1993-1995. James Darrell McCauley
28
21
 * <25 Feb 1995> - cleaned 'gcc -Wall' warnings (jdm)
29
22
 * <25 Jun 1995> - new site API (jdm)
30
23
 * <13 Sep 2000> - released under GPL
31
 
 */
 
24
 *
 
25
 * COPYRIGHT:    (C) 2003-2010 by the GRASS Development Team
 
26
 *
 
27
 *               This program is free software under the GNU General
 
28
 *               Public License (>=v2).  Read the file COPYING that
 
29
 *               comes with GRASS for details.
 
30
 *
 
31
**************************************************************/
32
32
 
33
33
#include <stdlib.h>
34
34
#include <math.h>
35
 
#include <sys/types.h>
36
 
#include <unistd.h>
37
35
#include <string.h>
 
36
 
38
37
#include <grass/gis.h>
39
 
#include <grass/Vect.h>
 
38
#include <grass/vector.h>
40
39
#include <grass/dbmi.h>
41
40
#include <grass/glocale.h>
42
41
 
43
 
#ifndef RAND_MAX
44
 
#define RAND_MAX (pow(2.0,31.0)-1)
45
 
#endif
46
 
double myrand(void);
47
 
 
48
 
#if defined(__CYGWIN__) || defined(__APPLE__) || defined(__MINGW32__)
49
 
double drand48()
 
42
/* for qsort */
 
43
 
 
44
typedef struct {
 
45
    int i;
 
46
    double size;
 
47
    struct bound_box box;
 
48
} BOX_SIZE;
 
49
 
 
50
static int sort_by_size(const void *a, const void *b)
50
51
{
51
 
    return (rand() / 32767.0);
 
52
    BOX_SIZE *as = (BOX_SIZE *)a;
 
53
    BOX_SIZE *bs = (BOX_SIZE *)b;
 
54
    
 
55
    if (as->size < bs->size)
 
56
        return -1;
 
57
 
 
58
    return (as->size > bs->size);
52
59
}
53
60
 
54
 
#define srand48(sv) (srand((unsigned)(sv)))
55
 
#endif
56
 
 
57
61
int main(int argc, char *argv[])
58
62
{
59
 
    char *output, buf[2000];
60
 
    double (*rng) ();
61
 
    double max, zmin, zmax;
62
 
    int i, n, b, type, usefloat;
63
 
    struct Map_info Out;
 
63
    char *output, buf[DB_SQL_MAX];
 
64
    double (*rng)(void) = G_drand48;
 
65
    double zmin, zmax;
 
66
    int seed;
 
67
    int i, j, k, n, type, usefloat;
 
68
    int area, nareas, field;
 
69
    struct boxlist *List = NULL;
 
70
    BOX_SIZE *size_list = NULL;
 
71
    int alloc_size_list = 0;
 
72
    struct Map_info In, Out;
64
73
    struct line_pnts *Points;
65
74
    struct line_cats *Cats;
 
75
    struct cat_list *cat_list;
 
76
    struct bound_box box;
66
77
    struct Cell_head window;
67
78
    struct GModule *module;
68
79
    struct
69
80
    {
70
 
        struct Option *output, *nsites, *zmin, *zmax, *zcol;
 
81
        struct Option *input, *field, *cats, *where, *output, *nsites,
 
82
                      *zmin, *zmax, *zcol, *ztype, *seed;
71
83
    } parm;
72
84
    struct
73
85
    {
74
 
        struct Flag *rand, *drand48, *z, *notopo;
 
86
        struct Flag *z, *notopo, *a;
75
87
    } flag;
76
88
    struct field_info *Fi;
77
89
    dbDriver *driver;
81
93
    G_gisinit(argv[0]);
82
94
 
83
95
    module = G_define_module();
84
 
    module->keywords = _("vector, statistics");
85
 
    module->description = _("Randomly generate a 2D/3D vector points map.");
 
96
    G_add_keyword(_("vector"));
 
97
    G_add_keyword(_("sampling"));
 
98
    G_add_keyword(_("statistics"));
 
99
    G_add_keyword(_("random"));
 
100
    G_add_keyword(_("point pattern"));
 
101
    module->description = _("Generates random 2D/3D vector points.");
86
102
 
87
103
    parm.output = G_define_standard_option(G_OPT_V_OUTPUT);
88
104
 
89
105
    parm.nsites = G_define_option();
90
 
    parm.nsites->key = "n";
 
106
    parm.nsites->key = "npoints";
91
107
    parm.nsites->type = TYPE_INTEGER;
92
108
    parm.nsites->required = YES;
93
109
    parm.nsites->description = _("Number of points to be created");
94
110
 
 
111
    parm.input = G_define_standard_option(G_OPT_V_INPUT);
 
112
    parm.input->key = "restrict";
 
113
    parm.input->required = NO;
 
114
    parm.input->description = _("Restrict points to areas in input vector");
 
115
    parm.input->guisection = _("Selection");
 
116
 
 
117
    parm.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
 
118
    parm.field->guisection = _("Selection");
 
119
 
 
120
    parm.cats = G_define_standard_option(G_OPT_V_CATS);
 
121
    parm.cats->guisection = _("Selection");
 
122
    
 
123
    parm.where = G_define_standard_option(G_OPT_DB_WHERE);
 
124
    parm.where->guisection = _("Selection");
 
125
 
95
126
    parm.zmin = G_define_option();
96
127
    parm.zmin->key = "zmin";
97
128
    parm.zmin->type = TYPE_DOUBLE;
109
140
        _("Maximum z height (needs -z flag or column name)");
110
141
    parm.zmax->answer = "0.0";
111
142
    parm.zmax->guisection = _("3D output");
112
 
    
113
 
    parm.zcol = G_define_option();
114
 
    parm.zcol->key = "column";
115
 
    parm.zcol->type = TYPE_STRING;
116
 
    parm.zcol->multiple = NO;
117
 
    parm.zcol->required = NO;
118
 
    parm.zcol->label =
119
 
        _("Column name and type (i.e. INTEGER, DOUBLE PRECISION) for z values");
 
143
 
 
144
    parm.seed = G_define_option();
 
145
    parm.seed->key = "seed";
 
146
    parm.seed->type = TYPE_INTEGER;
 
147
    parm.seed->required = NO;
 
148
    parm.seed->description =
 
149
        _("The seed to initialize the random generator. If not set the process ID is used");
 
150
 
 
151
    parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN);
 
152
    parm.zcol->label = _("Name of column for z values");
120
153
    parm.zcol->description =
121
 
        _("If type is not given then DOUBLE PRECISION is used. "
122
 
          "Writes Z data to column instead of 3D vector.");
 
154
        _("Writes z values to column");
123
155
    parm.zcol->guisection = _("3D output");
124
156
 
 
157
    parm.ztype = G_define_option();
 
158
    parm.ztype->key = "column_type";
 
159
    parm.ztype->type = TYPE_STRING;
 
160
    parm.ztype->required = NO;
 
161
    parm.ztype->multiple = NO;
 
162
    parm.ztype->description = _("Type of column for z values");
 
163
    parm.ztype->options = "integer,double precision";
 
164
    parm.ztype->answer = "double precision";
 
165
    parm.ztype->guisection = _("3D output");
 
166
 
125
167
    flag.z = G_define_flag();
126
168
    flag.z->key = 'z';
127
169
    flag.z->description = _("Create 3D output");
128
170
    flag.z->guisection = _("3D output");
129
171
 
130
 
    flag.drand48 = G_define_flag();
131
 
    flag.drand48->key = 'd';
132
 
    flag.drand48->description = _("Use drand48() function instead of rand()");
 
172
    flag.a = G_define_flag();
 
173
    flag.a->key = 'a';
 
174
    flag.a->description = _("Generate n points for each individual area");
133
175
 
134
 
    flag.notopo = G_define_flag();
135
 
    flag.notopo->key = 'b';
136
 
    flag.notopo->description = _("Do not build topology");
 
176
    flag.notopo = G_define_standard_flag(G_FLG_V_TOPO);
137
177
 
138
178
    if (G_parser(argc, argv))
139
179
        exit(EXIT_FAILURE);
140
180
 
141
 
    if (flag.z->answer && parm.zcol->answer) {
142
 
        G_fatal_error(_("v.random can't create 3D vector and attribute table at same time"));
143
 
    }
144
 
 
145
181
    output = parm.output->answer;
146
182
    n = atoi(parm.nsites->answer);
147
 
    b = (flag.drand48->answer == '\0') ? 0 : 1;
 
183
    
 
184
    if(parm.seed->answer)
 
185
        seed = atoi(parm.seed->answer);
148
186
 
149
187
    if (n <= 0) {
150
188
        G_fatal_error(_("Number of points must be > 0 (%d given)"), n);
151
189
    }
152
190
 
153
 
    if (flag.z->answer)
154
 
        Vect_open_new(&Out, output, WITH_Z);
155
 
    else
156
 
        Vect_open_new(&Out, output, WITHOUT_Z);
 
191
    nareas = 0;
 
192
    cat_list = NULL;
 
193
    field = -1;
 
194
    if (parm.input->answer) {
 
195
        Vect_set_open_level(2); /* topology required */
 
196
        if (2 > Vect_open_old2(&In, parm.input->answer, "", parm.field->answer))
 
197
            G_fatal_error(_("Unable to open vector map <%s>"),
 
198
                          parm.input->answer);
 
199
 
 
200
        if (parm.field->answer)
 
201
            field = Vect_get_field_number(&In, parm.field->answer);
 
202
 
 
203
        if ((parm.cats->answer || parm.where->answer) && field == -1) {
 
204
            G_warning(_("Invalid layer number (%d). Parameter '%s' or '%s' specified, assuming layer '1'."),
 
205
                      field, parm.cats->key, parm.where->key);
 
206
            field = 1;
 
207
        }
 
208
        if (field > 0)
 
209
            cat_list = Vect_cats_set_constraint(&In, field, parm.where->answer,
 
210
                                                parm.cats->answer);
 
211
        nareas = Vect_get_num_areas(&In);
 
212
        if (nareas == 0) {
 
213
            Vect_close(&In);
 
214
            G_fatal_error(_("No areas in vector map <%s>"), parm.input->answer);
 
215
        }
 
216
    }
 
217
    else {
 
218
        if (flag.a->answer)
 
219
            G_fatal_error(_("The <-%c> flag requires an input vector with areas"),
 
220
                          flag.a->key);
 
221
    }
 
222
 
 
223
    /* create new vector map */
 
224
    if (-1 == Vect_open_new(&Out, output, flag.z->answer ? WITH_Z : WITHOUT_Z))
 
225
        G_fatal_error(_("Unable to create vector map <%s>"), output);
 
226
    Vect_set_error_handler_io(NULL, &Out);
157
227
 
158
228
    /* Do we need to write random values into attribute table? */
 
229
    usefloat = -1;
159
230
    if (parm.zcol->answer) {
160
 
        char **token = G_tokenize(parm.zcol->answer, " ");
161
 
        
162
231
        Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
163
232
        driver =
164
233
            db_start_driver_open_database(Fi->driver,
165
234
                                          Vect_subst_var(Fi->database, &Out));
166
235
        if (driver == NULL) {
167
 
            Vect_delete(parm.output->answer);
168
236
            G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
169
237
                          Vect_subst_var(Fi->database, &Out), Fi->driver);
170
238
        }
 
239
        db_set_error_handler_driver(driver);
 
240
        
171
241
        db_begin_transaction(driver);
172
242
 
173
243
        db_init_string(&sql);
174
 
        if (G_number_of_tokens(token) > 1) {
175
 
            sprintf(buf, "create table %s (cat integer, %s)", Fi->table,
176
 
                    parm.zcol->answer);
177
 
        }
178
 
        else {
179
 
            G_verbose_message(_("Using 'double precision' for column <%s>"), parm.zcol->answer);
180
 
            sprintf(buf, "create table %s (cat integer, %s double precision)", Fi->table,
181
 
                    parm.zcol->answer);
182
 
        }
 
244
        sprintf(buf, "create table %s (%s integer, %s %s)", Fi->table, GV_KEY_COLUMN,
 
245
                parm.zcol->answer, parm.ztype->answer);
183
246
        db_set_string(&sql, buf);
184
 
        Vect_map_add_dblink(&Out, 1, NULL, Fi->table, "cat", Fi->database,
 
247
        Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
185
248
                            Fi->driver);
186
249
 
187
250
        /* Create table */
188
251
        G_debug(3, db_get_string(&sql));
189
252
        if (db_execute_immediate(driver, &sql) != DB_OK) {
190
 
            db_close_database(driver);
191
 
            db_shutdown_driver(driver);
192
 
            Vect_delete(parm.output->answer);
193
253
            G_fatal_error(_("Unable to create table: %s"),
194
254
                          db_get_string(&sql));
195
255
        }
196
256
 
 
257
        /* Create index */
 
258
        if (db_create_index2(driver, Fi->table, Fi->key) != DB_OK)
 
259
            G_warning(_("Unable to create index"));
 
260
 
197
261
        /* Grant */
198
262
        if (db_grant_on_table
199
263
            (driver, Fi->table, DB_PRIV_SELECT,
200
264
             DB_GROUP | DB_PUBLIC) != DB_OK) {
201
 
            db_close_database(driver);
202
 
            db_shutdown_driver(driver);
203
 
            Vect_delete(parm.output->answer);
204
265
            G_fatal_error(_("Unable to grant privileges on table <%s>"),
205
266
                          Fi->table);
206
267
        }
208
269
        /* OK. Let's check what type of column user has created */
209
270
        db_set_string(&sql, Fi->table);
210
271
        if (db_describe_table(driver, &sql, &table) != DB_OK) {
211
 
            db_close_database(driver);
212
 
            db_shutdown_driver(driver);
213
 
            Vect_delete(parm.output->answer);
214
272
            G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
215
273
        }
216
274
 
217
275
        if (db_get_table_number_of_columns(table) != 2) {
218
 
            db_close_database(driver);
219
 
            db_shutdown_driver(driver);
220
 
            Vect_delete(parm.output->answer);
221
276
            G_fatal_error(_("Table should contain only two columns"));
222
277
        }
223
278
 
224
279
        type = db_get_column_sqltype(db_get_table_column(table, 1));
225
 
        usefloat = -1;
226
280
        if (type == DB_SQL_TYPE_SMALLINT || type == DB_SQL_TYPE_INTEGER)
227
281
            usefloat = 0;
228
282
        if (type == DB_SQL_TYPE_REAL || type == DB_SQL_TYPE_DOUBLE_PRECISION)
229
283
            usefloat = 1;
230
284
        if (usefloat < 0) {
231
 
            db_close_database(driver);
232
 
            db_shutdown_driver(driver);
233
 
            Vect_delete(parm.output->answer);
234
285
            G_fatal_error(_("You have created unsupported column type. This module supports only INTEGER"
235
286
                           " and DOUBLE PRECISION column types."));
236
287
        }
237
 
        G_free_tokens(token);
238
288
    }
239
289
 
240
290
    Vect_hist_command(&Out);
241
291
 
242
 
    if (b) {
243
 
        rng = drand48;
244
 
        max = 1.0;
245
 
        srand48((long)getpid());
246
 
    }
247
 
    else {                      /* default is rand() */
248
 
 
249
 
        rng = myrand;
250
 
        max = RAND_MAX;
251
 
        srand(getpid());
252
 
    }
 
292
    /* Init the random seed */
 
293
    if(parm.seed->answer)
 
294
        G_srand48(seed);
 
295
    else
 
296
        G_srand48_auto();
253
297
 
254
298
    G_get_window(&window);
255
299
 
 
300
    Points = Vect_new_line_struct();
 
301
    Cats = Vect_new_cats_struct();
 
302
 
 
303
    if (nareas > 0) {
 
304
        int first = 1, count;
 
305
        struct bound_box abox, bbox;
 
306
 
 
307
        box.W = window.west;
 
308
        box.E = window.east;
 
309
        box.S = window.south;
 
310
        box.N = window.north;
 
311
        box.B = -PORT_DOUBLE_MAX;
 
312
        box.T = PORT_DOUBLE_MAX;
 
313
 
 
314
        count = 0;
 
315
 
 
316
        for (i = 1; i <= nareas; i++) {
 
317
            
 
318
            if (!Vect_get_area_centroid(&In, i))
 
319
                continue;
 
320
 
 
321
            if (field > 0) {
 
322
                if (Vect_get_area_cats(&In, i, Cats))
 
323
                    continue;
 
324
 
 
325
                if (!Vect_cats_in_constraint(Cats, field, cat_list))
 
326
                    continue;
 
327
            }
 
328
 
 
329
            Vect_get_area_box(&In, i, &abox);
 
330
            if (!Vect_box_overlap(&abox, &box))
 
331
                continue;
 
332
 
 
333
            if (first) {
 
334
                Vect_box_copy(&bbox, &abox);
 
335
                first = 0;
 
336
            }
 
337
            else
 
338
                Vect_box_extend(&bbox, &abox);
 
339
            count++;
 
340
        }
 
341
        if (count == 0) {
 
342
            Vect_close(&In);
 
343
            Vect_close(&Out);
 
344
            Vect_delete(output);
 
345
            G_fatal_error(_("Selected areas in input vector <%s> do not overlap with the current region"),
 
346
                          parm.input->answer);
 
347
        }
 
348
        Vect_box_copy(&box, &bbox);
 
349
 
 
350
        /* does the vector overlap with the current region ? */
 
351
        if (box.W >= window.east || box.E <= window.west ||
 
352
            box.S >= window.north || box.N <= window.south) {
 
353
 
 
354
            Vect_close(&In);
 
355
            Vect_close(&Out);
 
356
            Vect_delete(output);
 
357
            G_fatal_error(_("Input vector <%s> does not overlap with the current region"),
 
358
                          parm.input->answer);
 
359
        }
 
360
 
 
361
        /* try to reduce the current region */
 
362
        if (window.east > box.E)
 
363
            window.east = box.E;
 
364
        if (window.west < box.W)
 
365
            window.west = box.W;
 
366
        if (window.north > box.N)
 
367
            window.north = box.N;
 
368
        if (window.south < box.S)
 
369
            window.south = box.S;
 
370
 
 
371
        List = Vect_new_boxlist(1);
 
372
        alloc_size_list = 10;
 
373
        size_list = G_malloc(alloc_size_list * sizeof(BOX_SIZE));
 
374
    }
 
375
 
 
376
    zmin = zmax = 0;
256
377
    if (flag.z->answer || parm.zcol->answer) {
257
378
        zmax = atof(parm.zmax->answer);
258
379
        zmin = atof(parm.zmin->answer);
259
380
    }
260
381
 
261
 
    Points = Vect_new_line_struct();
262
 
    Cats = Vect_new_cats_struct();
263
 
 
264
382
    G_message(_("Generating points..."));
265
 
    for (i = 0; i < n; ++i) {
266
 
        double x, y, z;
267
 
 
268
 
        G_percent(i, n, 5);
269
 
 
270
 
        Vect_reset_line(Points);
271
 
        Vect_reset_cats(Cats);
272
 
 
273
 
        x = rng() / max * (window.west - window.east) + window.east;
274
 
        y = rng() / max * (window.north - window.south) + window.south;
275
 
 
276
 
        if (flag.z->answer) {
277
 
            z = rng() / max * (zmax - zmin) + zmin;
278
 
            Vect_append_point(Points, x, y, z);
 
383
    if (flag.a->answer && nareas > 0) {
 
384
        struct bound_box abox, bbox;
 
385
        int cat = 1;
 
386
 
 
387
        /* n points for each area */
 
388
        nareas = Vect_get_num_areas(&In);
 
389
        
 
390
        G_percent(0, nareas, 1);
 
391
        for (area = 1; area <= nareas; area++) {
 
392
 
 
393
            G_percent(area, nareas, 1);
 
394
 
 
395
            if (!Vect_get_area_centroid(&In, area))
 
396
                continue;
 
397
 
 
398
            if (field > 0) {
 
399
                if (Vect_get_area_cats(&In, area, Cats))
 
400
                    continue;
 
401
 
 
402
                if (!Vect_cats_in_constraint(Cats, field, cat_list)) {
 
403
                    continue;
 
404
                }
 
405
            }
 
406
 
 
407
            box.W = window.west;
 
408
            box.E = window.east;
 
409
            box.S = window.south;
 
410
            box.N = window.north;
 
411
            box.B = -PORT_DOUBLE_MAX;
 
412
            box.T = PORT_DOUBLE_MAX;
 
413
            
 
414
            Vect_get_area_box(&In, area, &abox);
 
415
            if (!Vect_box_overlap(&box, &abox))
 
416
                continue;
 
417
                
 
418
            bbox = abox;
 
419
            if (bbox.W < box.W)
 
420
                bbox.W = box.W;
 
421
            if (bbox.E > box.E)
 
422
                bbox.E = box.E;
 
423
            if (bbox.S < box.S)
 
424
                bbox.S = box.S;
 
425
            if (bbox.N > box.N)
 
426
                bbox.N = box.N;
 
427
 
 
428
            for (i = 0; i < n; ++i) {
 
429
                double x, y, z;
 
430
                int outside = 1;
 
431
                int ret;
 
432
 
 
433
                Vect_reset_line(Points);
 
434
                Vect_reset_cats(Cats);
 
435
 
 
436
                while (outside) {
 
437
                    x = rng() * (bbox.W - bbox.E) + bbox.E;
 
438
                    y = rng() * (bbox.N - bbox.S) + bbox.S;
 
439
                    z = rng() * (zmax - zmin) + zmin;
 
440
 
 
441
                    ret = Vect_point_in_area(x, y, &In, area, &abox);
 
442
 
 
443
                    G_debug(3, "    area = %d Vect_point_in_area() = %d", area, ret);
 
444
 
 
445
                    if (ret >= 1) {
 
446
                        outside = 0;
 
447
                    }
 
448
                }
 
449
 
 
450
                if (flag.z->answer)
 
451
                    Vect_append_point(Points, x, y, z);
 
452
                else
 
453
                    Vect_append_point(Points, x, y, 0.0);
 
454
 
 
455
                if (parm.zcol->answer) {
 
456
                    sprintf(buf, "insert into %s values ( %d, ", Fi->table, i + 1);
 
457
                    db_set_string(&sql, buf);
 
458
                    /* Round random value if column is integer type */
 
459
                    if (usefloat)
 
460
                        sprintf(buf, "%f )", z);
 
461
                    else
 
462
                        sprintf(buf, "%.0f )", z);
 
463
                    db_append_string(&sql, buf);
 
464
 
 
465
                    G_debug(3, db_get_string(&sql));
 
466
                    if (db_execute_immediate(driver, &sql) != DB_OK) {
 
467
                        G_fatal_error(_("Cannot insert new row: %s"),
 
468
                                      db_get_string(&sql));
 
469
                    }
 
470
                }
 
471
 
 
472
                Vect_cat_set(Cats, 1, cat++);
 
473
                Vect_write_line(&Out, GV_POINT, Points, Cats);
 
474
            }
279
475
        }
280
 
        else
281
 
            Vect_append_point(Points, x, y, 0.0);
282
 
 
283
 
        if (parm.zcol->answer) {
284
 
            z = rng() / max * (zmax - zmin) + zmin;
285
 
 
286
 
            sprintf(buf, "insert into %s values ( %d, ", Fi->table, i + 1);
287
 
            db_set_string(&sql, buf);
288
 
            /* Round random value if column is integer type */
289
 
            if (usefloat)
290
 
                sprintf(buf, "%f )", z);
 
476
    }
 
477
    else {
 
478
        /* n points in total */
 
479
        for (i = 0; i < n; ++i) {
 
480
            double x, y, z;
 
481
 
 
482
            G_percent(i, n, 4);
 
483
 
 
484
            Vect_reset_line(Points);
 
485
            Vect_reset_cats(Cats);
 
486
 
 
487
            x = rng() * (window.west - window.east) + window.east;
 
488
            y = rng() * (window.north - window.south) + window.south;
 
489
            z = rng() * (zmax - zmin) + zmin;
 
490
            
 
491
            if (nareas) {
 
492
                int outside = 1;
 
493
 
 
494
                do {
 
495
                    /* select areas by box */
 
496
                    box.E = x;
 
497
                    box.W = x;
 
498
                    box.N = y;
 
499
                    box.S = y;
 
500
                    box.T = PORT_DOUBLE_MAX;
 
501
                    box.B = -PORT_DOUBLE_MAX;
 
502
                    Vect_select_areas_by_box(&In, &box, List);
 
503
                    G_debug(3, "  %d areas selected by box", List->n_values);
 
504
 
 
505
                    /* sort areas by size, the smallest is likely to be the nearest */
 
506
                    if (alloc_size_list < List->n_values) {
 
507
                        alloc_size_list = List->n_values;
 
508
                        size_list = G_realloc(size_list, alloc_size_list * sizeof(BOX_SIZE));
 
509
                    }
 
510
 
 
511
                    k = 0;
 
512
                    for (j = 0; j < List->n_values; j++) {
 
513
                        area = List->id[j];
 
514
 
 
515
                        if (!Vect_get_area_centroid(&In, area))
 
516
                            continue;
 
517
 
 
518
                        if (field > 0) {
 
519
                            if (Vect_get_area_cats(&In, area, Cats))
 
520
                                continue;
 
521
 
 
522
                            if (!Vect_cats_in_constraint(Cats, field, cat_list)) {
 
523
                                continue;
 
524
                            }
 
525
                        }
 
526
 
 
527
                        List->id[k] = List->id[j];
 
528
                        List->box[k] = List->box[j];
 
529
                        size_list[k].i = List->id[k];
 
530
                        box = List->box[k];
 
531
                        size_list[k].box = List->box[k];
 
532
                        size_list[k].size = (box.N - box.S) * (box.E - box.W);
 
533
                        k++;
 
534
                    }
 
535
                    List->n_values = k;
 
536
                    
 
537
                    if (List->n_values == 2) {
 
538
                        /* simple swap */
 
539
                        if (size_list[1].size < size_list[0].size) {
 
540
                            size_list[0].i = List->id[1];
 
541
                            size_list[1].i = List->id[0];
 
542
                            size_list[0].box = List->box[1];
 
543
                            size_list[1].box = List->box[0];
 
544
                        }
 
545
                    }
 
546
                    else if (List->n_values > 2)
 
547
                        qsort(size_list, List->n_values, sizeof(BOX_SIZE), sort_by_size);
 
548
 
 
549
                    for (j = 0; j < List->n_values; j++) {
 
550
                        int ret;
 
551
 
 
552
                        area = size_list[j].i;
 
553
                        ret = Vect_point_in_area(x, y, &In, area, &size_list[j].box);
 
554
 
 
555
                        G_debug(3, "    area = %d Vect_point_in_area() = %d", area, ret);
 
556
 
 
557
                        if (ret >= 1) {
 
558
                            outside = 0;
 
559
                            break;
 
560
                        }
 
561
                    }
 
562
                    if (outside) {
 
563
                        x = rng() * (window.west - window.east) + window.east;
 
564
                        y = rng() * (window.north - window.south) + window.south;
 
565
                        z = rng() * (zmax - zmin) + zmin;
 
566
                    }
 
567
                } while (outside);
 
568
            }
 
569
 
 
570
            if (flag.z->answer)
 
571
                Vect_append_point(Points, x, y, z);
291
572
            else
292
 
                sprintf(buf, "%.0f )", z);
293
 
            db_append_string(&sql, buf);
294
 
 
295
 
            G_debug(3, db_get_string(&sql));
296
 
            if (db_execute_immediate(driver, &sql) != DB_OK) {
297
 
                db_close_database(driver);
298
 
                db_shutdown_driver(driver);
299
 
                Vect_delete(parm.output->answer);
300
 
                G_fatal_error(_("Cannot insert new row: %s"),
301
 
                              db_get_string(&sql));
 
573
                Vect_append_point(Points, x, y, 0.0);
 
574
 
 
575
            if (parm.zcol->answer) {
 
576
                sprintf(buf, "insert into %s values ( %d, ", Fi->table, i + 1);
 
577
                db_set_string(&sql, buf);
 
578
                /* Round random value if column is integer type */
 
579
                if (usefloat)
 
580
                    sprintf(buf, "%f )", z);
 
581
                else
 
582
                    sprintf(buf, "%.0f )", z);
 
583
                db_append_string(&sql, buf);
 
584
 
 
585
                G_debug(3, db_get_string(&sql));
 
586
                if (db_execute_immediate(driver, &sql) != DB_OK) {
 
587
                    G_fatal_error(_("Cannot insert new row: %s"),
 
588
                                  db_get_string(&sql));
 
589
                }
302
590
            }
 
591
 
 
592
            Vect_cat_set(Cats, 1, i + 1);
 
593
            Vect_write_line(&Out, GV_POINT, Points, Cats);
303
594
        }
304
 
 
305
 
        Vect_cat_set(Cats, 1, i + 1);
306
 
        Vect_write_line(&Out, GV_POINT, Points, Cats);
 
595
        G_percent(1, 1, 1);
307
596
    }
308
 
 
 
597
    
309
598
    if (parm.zcol->answer) {
310
599
        db_commit_transaction(driver);
311
600
        db_close_database_shutdown_driver(driver);
318
607
 
319
608
    exit(EXIT_SUCCESS);
320
609
}
321
 
 
322
 
double myrand()
323
 
{
324
 
    return (double)rand();
325
 
}