main.c 23 KB

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