random.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include <grass/dbmi.h>
  5. #include <grass/vector.h>
  6. #include <grass/glocale.h>
  7. #include "local_proto.h"
  8. /* function prototypes */
  9. static void cpvalue(struct RASTER_MAP_PTR *, int, struct RASTER_MAP_PTR *,
  10. int);
  11. static double cell_as_dbl(struct RASTER_MAP_PTR *, int);
  12. static void set_to_null(struct RASTER_MAP_PTR *, int);
  13. int execute_random(struct rr_state *theState)
  14. {
  15. long nt;
  16. long nc;
  17. struct Cell_head window;
  18. int nrows, ncols, row, col;
  19. int infd, cinfd, outfd;
  20. struct Map_info Out;
  21. struct field_info *fi;
  22. dbTable *table;
  23. dbColumn *column;
  24. dbString sql;
  25. dbDriver *driver;
  26. struct line_pnts *Points;
  27. struct line_cats *Cats;
  28. int cat;
  29. RASTER_MAP_TYPE type;
  30. int do_check;
  31. G_get_window(&window);
  32. nrows = Rast_window_rows();
  33. ncols = Rast_window_cols();
  34. /* open the data files, input raster should be set-up already */
  35. if ((infd = theState->fd_old) < 0)
  36. G_fatal_error(_("Unable to open raster map <%s>"),
  37. theState->inraster);
  38. if (theState->docover == TRUE) {
  39. if ((cinfd = theState->fd_cold) < 0)
  40. G_fatal_error(_("Unable to open raster map <%s>"),
  41. theState->inrcover);
  42. }
  43. if (theState->outraster != NULL) {
  44. if (theState->docover == TRUE)
  45. type = theState->cover.type;
  46. else
  47. type = theState->buf.type;
  48. outfd = Rast_open_new(theState->outraster, type);
  49. theState->fd_new = outfd;
  50. }
  51. if (theState->outvector) {
  52. if (Vect_open_new(&Out, theState->outvector, theState->z_geometry) < 0)
  53. G_fatal_error(_("Unable to create vector map <%s>"),
  54. theState->outvector);
  55. Vect_hist_command(&Out);
  56. fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
  57. driver =
  58. db_start_driver_open_database(fi->driver,
  59. Vect_subst_var(fi->database, &Out));
  60. if (!driver)
  61. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  62. Vect_subst_var(fi->database, &Out), fi->driver);
  63. db_set_error_handler_driver(driver);
  64. Vect_map_add_dblink(&Out, 1, NULL, fi->table, GV_KEY_COLUMN, fi->database,
  65. fi->driver);
  66. if (theState->docover == TRUE)
  67. table = db_alloc_table(3);
  68. else
  69. table = db_alloc_table(2);
  70. db_set_table_name(table, fi->table);
  71. column = db_get_table_column(table, 0);
  72. db_set_column_name(column, GV_KEY_COLUMN);
  73. db_set_column_sqltype(column, DB_SQL_TYPE_INTEGER);
  74. column = db_get_table_column(table, 1);
  75. db_set_column_name(column, "value");
  76. db_set_column_sqltype(column, DB_SQL_TYPE_DOUBLE_PRECISION);
  77. if (theState->docover == TRUE) {
  78. column = db_get_table_column(table, 2);
  79. db_set_column_name(column, "covervalue");
  80. db_set_column_sqltype(column, DB_SQL_TYPE_DOUBLE_PRECISION);
  81. }
  82. if (db_create_table(driver, table) != DB_OK)
  83. G_warning(_("Cannot create new table"));
  84. db_begin_transaction(driver);
  85. Points = Vect_new_line_struct();
  86. Cats = Vect_new_cats_struct();
  87. db_init_string(&sql);
  88. }
  89. if (theState->outvector && theState->outraster)
  90. G_message(_("Writing raster map <%s> and vector map <%s> ..."),
  91. theState->outraster, theState->outvector);
  92. else if (theState->outraster)
  93. G_message(_("Writing raster map <%s> ..."), theState->outraster);
  94. else if (theState->outvector)
  95. G_message(_("Writing vector map <%s> ..."), theState->outvector);
  96. G_percent(0, theState->nRand, 2);
  97. init_rand();
  98. nc = (theState->use_nulls) ? theState->nCells :
  99. theState->nCells - theState->nNulls;
  100. nt = theState->nRand; /* Number of points to generate */
  101. cat = 1;
  102. /* Execute for loop for every row if nt>1 */
  103. for (row = 0; row < nrows && nt; row++) {
  104. Rast_get_row(infd, theState->buf.data.v, row, theState->buf.type);
  105. if (theState->docover == TRUE) {
  106. Rast_get_row(cinfd, theState->cover.data.v, row,
  107. theState->cover.type);
  108. }
  109. for (col = 0; col < ncols && nt; col++) {
  110. do_check = 0;
  111. if (theState->use_nulls || !is_null_value(theState->buf, col))
  112. do_check = 1;
  113. if (do_check && theState->docover == TRUE) { /* skip no data cover points */
  114. if (!theState->use_nulls &&
  115. is_null_value(theState->cover, col))
  116. do_check = 0;
  117. }
  118. if (do_check && make_rand() % nc < nt) {
  119. nt--;
  120. if (is_null_value(theState->buf, col))
  121. cpvalue(&theState->nulls, 0, &theState->buf, col);
  122. if (theState->docover == TRUE) {
  123. if (is_null_value(theState->cover, col))
  124. cpvalue(&theState->cnulls, 0, &theState->cover, col);
  125. }
  126. if (theState->outvector) {
  127. double x, y, val, coverval;
  128. char buf[500];
  129. Vect_reset_line(Points);
  130. Vect_reset_cats(Cats);
  131. x = window.west + (col + .5) * window.ew_res;
  132. y = window.north - (row + .5) * window.ns_res;
  133. val = cell_as_dbl(&theState->buf, col);
  134. if (theState->docover == 1)
  135. coverval = cell_as_dbl(&theState->cover, col);
  136. if (theState->z_geometry)
  137. Vect_append_point(Points, x, y, val);
  138. else
  139. Vect_append_point(Points, x, y, 0.0);
  140. Vect_cat_set(Cats, 1, cat);
  141. Vect_write_line(&Out, GV_POINT, Points, Cats);
  142. if (theState->docover == 1)
  143. if (is_null_value(theState->cover, col))
  144. sprintf(buf,
  145. "insert into %s values ( %d, %f, NULL )",
  146. fi->table, cat, val);
  147. else
  148. sprintf(buf,
  149. "insert into %s values ( %d, %f, %f )",
  150. fi->table, cat, val, coverval);
  151. else
  152. sprintf(buf, "insert into %s values ( %d, %f )",
  153. fi->table, cat, val);
  154. db_set_string(&sql, buf);
  155. if (db_execute_immediate(driver, &sql) != DB_OK)
  156. G_fatal_error(_("Cannot insert new record: %s"),
  157. db_get_string(&sql));
  158. cat++;
  159. }
  160. G_percent((theState->nRand - nt), theState->nRand, 2);
  161. }
  162. else {
  163. set_to_null(&theState->buf, col);
  164. if (theState->docover == 1)
  165. set_to_null(&theState->cover, col);
  166. }
  167. if (do_check)
  168. nc--;
  169. }
  170. while (col < ncols) {
  171. set_to_null(&theState->buf, col);
  172. if (theState->docover == 1)
  173. set_to_null(&theState->cover, col);
  174. col++;
  175. }
  176. if (theState->outraster) {
  177. if (theState->docover == 1)
  178. Rast_put_row(outfd, theState->cover.data.v,
  179. theState->cover.type);
  180. else
  181. Rast_put_row(outfd, theState->buf.data.v,
  182. theState->buf.type);
  183. }
  184. }
  185. /* Catch any remaining rows in the window */
  186. if (theState->outraster && row < nrows) {
  187. for (col = 0; col < ncols; col++) {
  188. if (theState->docover == 1)
  189. set_to_null(&theState->cover, col);
  190. else
  191. set_to_null(&theState->buf, col);
  192. }
  193. for (; row < nrows; row++) {
  194. if (theState->docover == 1)
  195. Rast_put_row(outfd, theState->cover.data.v,
  196. theState->cover.type);
  197. else
  198. Rast_put_row(outfd, theState->buf.data.v,
  199. theState->buf.type);
  200. }
  201. }
  202. if (nt > 0)
  203. G_warning(_("Only [%ld] random points created"),
  204. theState->nRand - nt);
  205. /* close files */
  206. Rast_close(infd);
  207. if (theState->docover == TRUE)
  208. Rast_close(cinfd);
  209. if (theState->outvector) {
  210. db_commit_transaction(driver);
  211. if (db_create_index2(driver, fi->table, GV_KEY_COLUMN) != DB_OK)
  212. G_warning(_("Unable to create index"));
  213. if (db_grant_on_table
  214. (driver, fi->table, DB_PRIV_SELECT,
  215. DB_GROUP | DB_PUBLIC) != DB_OK) {
  216. G_fatal_error(_("Unable to grant privileges on table <%s>"),
  217. fi->table);
  218. }
  219. db_close_database_shutdown_driver(driver);
  220. if (theState->notopol != 1)
  221. Vect_build(&Out);
  222. Vect_close(&Out);
  223. }
  224. if (theState->outraster)
  225. Rast_close(outfd);
  226. return 0;
  227. } /* execute_random() */
  228. static void cpvalue(struct RASTER_MAP_PTR *from, int fcol,
  229. struct RASTER_MAP_PTR *to, int tcol)
  230. {
  231. switch (from->type) {
  232. case CELL_TYPE:
  233. to->data.c[tcol] = from->data.c[fcol];
  234. break;
  235. case FCELL_TYPE:
  236. to->data.f[tcol] = from->data.f[fcol];
  237. break;
  238. case DCELL_TYPE:
  239. to->data.d[tcol] = from->data.d[fcol];
  240. break;
  241. }
  242. }
  243. static double cell_as_dbl(struct RASTER_MAP_PTR *buf, int col)
  244. {
  245. switch (buf->type) {
  246. case CELL_TYPE:
  247. return (double)buf->data.c[col];
  248. case FCELL_TYPE:
  249. return (double)buf->data.f[col];
  250. case DCELL_TYPE:
  251. return (double)buf->data.d[col];
  252. }
  253. return 0.;
  254. }
  255. static void set_to_null(struct RASTER_MAP_PTR *buf, int col)
  256. {
  257. switch (buf->type) {
  258. case CELL_TYPE:
  259. Rast_set_c_null_value(&(buf->data.c[col]), 1);
  260. break;
  261. case FCELL_TYPE:
  262. Rast_set_f_null_value(&(buf->data.f[col]), 1);
  263. break;
  264. case DCELL_TYPE:
  265. Rast_set_d_null_value(&(buf->data.d[col]), 1);
  266. break;
  267. }
  268. }
  269. int is_null_value(struct RASTER_MAP_PTR buf, int col)
  270. {
  271. switch (buf.type) {
  272. case CELL_TYPE:
  273. return Rast_is_c_null_value(&buf.data.c[col]);
  274. break;
  275. case FCELL_TYPE:
  276. return Rast_is_f_null_value(&buf.data.f[col]);
  277. break;
  278. case DCELL_TYPE:
  279. return Rast_is_d_null_value(&buf.data.d[col]);
  280. break;
  281. }
  282. return -1;
  283. }