evaluate.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <grass/gis.h>
  5. #include <grass/raster.h>
  6. #include <grass/glocale.h>
  7. #include "mapcalc.h"
  8. #include "globals.h"
  9. #include "func_proto.h"
  10. /****************************************************************************/
  11. int current_depth, current_row;
  12. int depths, rows;
  13. /* Local variables for map management */
  14. static expression **map_list = NULL;
  15. static int num_maps = 0;
  16. static int max_maps = 0;
  17. /****************************************************************************/
  18. static void extract_maps(expression *e);
  19. static void initialize(expression *e);
  20. static void evaluate(expression *e);
  21. static int append_map(expression *e);
  22. /****************************************************************************/
  23. int append_map(expression *e)
  24. {
  25. /* \brief Append a map to the global map list and reallocate if necessary
  26. */
  27. if (num_maps >= max_maps) {
  28. max_maps += 10;
  29. map_list = G_realloc(map_list, max_maps * sizeof(struct expression*));
  30. }
  31. map_list[num_maps] = e;
  32. return num_maps++;
  33. }
  34. void extract_maps(expression * e)
  35. {
  36. /* \brief Search for map names in the expression and add them to the global map list */
  37. int i;
  38. switch (e->type) {
  39. case expr_type_map:
  40. G_debug(1, "Found map %s", e->data.map.name);
  41. append_map(e);
  42. break;
  43. case expr_type_function:
  44. for (i = 1; i <= e->data.func.argc; i++) {
  45. extract_maps(e->data.func.args[i]);
  46. }
  47. break;
  48. case expr_type_binding:
  49. extract_maps(e->data.bind.val);
  50. break;
  51. }
  52. }
  53. /****************************************************************************/
  54. static void allocate_buf(expression * e)
  55. {
  56. e->buf = G_malloc(columns * Rast_cell_size(e->res_type));
  57. }
  58. static void set_buf(expression * e, void *buf)
  59. {
  60. e->buf = buf;
  61. }
  62. /****************************************************************************/
  63. static void initialize_constant(expression * e)
  64. {
  65. allocate_buf(e);
  66. }
  67. static void initialize_variable(expression * e)
  68. {
  69. set_buf(e, e->data.var.bind->data.bind.val->buf);
  70. }
  71. static void initialize_map(expression * e)
  72. {
  73. allocate_buf(e);
  74. e->data.map.idx = open_map(e->data.map.name, e->data.map.mod,
  75. e->data.map.row, e->data.map.col);
  76. }
  77. static void initialize_function(expression * e)
  78. {
  79. int i;
  80. allocate_buf(e);
  81. e->data.func.argv = G_malloc((e->data.func.argc + 1) * sizeof(void *));
  82. e->data.func.argv[0] = e->buf;
  83. for (i = 1; i <= e->data.func.argc; i++) {
  84. initialize(e->data.func.args[i]);
  85. e->data.func.argv[i] = e->data.func.args[i]->buf;
  86. }
  87. }
  88. static void initialize_binding(expression * e)
  89. {
  90. initialize(e->data.bind.val);
  91. set_buf(e, e->data.bind.val->buf);
  92. }
  93. static void initialize(expression * e)
  94. {
  95. switch (e->type) {
  96. case expr_type_constant:
  97. initialize_constant(e);
  98. break;
  99. case expr_type_variable:
  100. initialize_variable(e);
  101. break;
  102. case expr_type_map:
  103. initialize_map(e);
  104. break;
  105. case expr_type_function:
  106. initialize_function(e);
  107. break;
  108. case expr_type_binding:
  109. initialize_binding(e);
  110. break;
  111. default:
  112. G_fatal_error(_("Unknown type: %d"), e->type);
  113. }
  114. }
  115. /****************************************************************************/
  116. static void do_evaluate(void *p)
  117. {
  118. evaluate((struct expression *) p);
  119. }
  120. static void begin_evaluate(struct expression *e)
  121. {
  122. G_begin_execute(do_evaluate, e, &e->worker, 0);
  123. }
  124. static void end_evaluate(struct expression *e)
  125. {
  126. G_end_execute(&e->worker);
  127. }
  128. /****************************************************************************/
  129. static void evaluate_constant(expression * e)
  130. {
  131. int *ibuf = e->buf;
  132. float *fbuf = e->buf;
  133. double *dbuf = e->buf;
  134. int i;
  135. switch (e->res_type) {
  136. case CELL_TYPE:
  137. for (i = 0; i < columns; i++)
  138. ibuf[i] = e->data.con.ival;
  139. break;
  140. case FCELL_TYPE:
  141. for (i = 0; i < columns; i++)
  142. fbuf[i] = e->data.con.fval;
  143. break;
  144. case DCELL_TYPE:
  145. for (i = 0; i < columns; i++)
  146. dbuf[i] = e->data.con.fval;
  147. break;
  148. default:
  149. G_fatal_error(_("Invalid type: %d"), e->res_type);
  150. }
  151. }
  152. static void evaluate_variable(expression * e)
  153. {
  154. /* this is a no-op */
  155. }
  156. static void evaluate_map(expression * e)
  157. {
  158. get_map_row(e->data.map.idx,
  159. e->data.map.mod,
  160. current_depth + e->data.map.depth,
  161. current_row + e->data.map.row,
  162. e->data.map.col, e->buf, e->res_type);
  163. }
  164. static void evaluate_function(expression * e)
  165. {
  166. int i;
  167. int res;
  168. if (e->data.func.argc > 1 && e->data.func.func != f_eval) {
  169. for (i = 1; i <= e->data.func.argc; i++)
  170. begin_evaluate(e->data.func.args[i]);
  171. for (i = 1; i <= e->data.func.argc; i++)
  172. end_evaluate(e->data.func.args[i]);
  173. }
  174. else
  175. for (i = 1; i <= e->data.func.argc; i++)
  176. evaluate(e->data.func.args[i]);
  177. res = (*e->data.func.func) (e->data.func.argc,
  178. e->data.func.argt, e->data.func.argv);
  179. switch (res) {
  180. case E_ARG_LO:
  181. G_fatal_error(_("Too few arguments for function '%s'"),
  182. e->data.func.name);
  183. break;
  184. case E_ARG_HI:
  185. G_fatal_error(_("Too many arguments for function '%s'"),
  186. e->data.func.name);
  187. break;
  188. case E_ARG_TYPE:
  189. G_fatal_error(_("Invalid argument type for function '%s'"),
  190. e->data.func.name);
  191. break;
  192. case E_RES_TYPE:
  193. G_fatal_error(_("Invalid return type for function '%s'"),
  194. e->data.func.name);
  195. break;
  196. case E_INV_TYPE:
  197. G_fatal_error(_("Unknown type for function '%s'"), e->data.func.name);
  198. break;
  199. case E_ARG_NUM:
  200. G_fatal_error(_("Number of arguments for function '%s'"),
  201. e->data.func.name);
  202. break;
  203. case E_WTF:
  204. G_fatal_error(_("Unknown error for function '%s'"),
  205. e->data.func.name);
  206. break;
  207. }
  208. }
  209. static void evaluate_binding(expression * e)
  210. {
  211. evaluate(e->data.bind.val);
  212. }
  213. /****************************************************************************/
  214. static void evaluate(expression * e)
  215. {
  216. switch (e->type) {
  217. case expr_type_constant:
  218. evaluate_constant(e);
  219. break;
  220. case expr_type_variable:
  221. evaluate_variable(e);
  222. break;
  223. case expr_type_map:
  224. evaluate_map(e);
  225. break;
  226. case expr_type_function:
  227. evaluate_function(e);
  228. break;
  229. case expr_type_binding:
  230. evaluate_binding(e);
  231. break;
  232. default:
  233. G_fatal_error(_("Unknown type: %d"), e->type);
  234. }
  235. }
  236. /****************************************************************************/
  237. static expr_list *exprs;
  238. /****************************************************************************/
  239. static void error_handler(void *p)
  240. {
  241. expr_list *l;
  242. for (l = exprs; l; l = l->next) {
  243. expression *e = l->exp;
  244. int fd = e->data.bind.fd;
  245. if (fd >= 0)
  246. unopen_output_map(fd);
  247. }
  248. }
  249. void execute(expr_list * ee)
  250. {
  251. int verbose = isatty(2);
  252. expr_list *l;
  253. int count, n;
  254. exprs = ee;
  255. G_add_error_handler(error_handler, NULL);
  256. for (l = ee; l; l = l->next) {
  257. expression *e = l->exp;
  258. const char *var;
  259. if (e->type != expr_type_binding && e->type != expr_type_function)
  260. G_fatal_error("internal error: execute: invalid type: %d",
  261. e->type);
  262. if (e->type != expr_type_binding)
  263. continue;
  264. var = e->data.bind.var;
  265. if (!overwrite_flag && check_output_map(var))
  266. G_fatal_error(_("output map <%s> exists. To overwrite, "
  267. "use the --overwrite flag"), var);
  268. }
  269. /* Parse each expression and extract all raster maps */
  270. for (l = ee; l; l = l->next) {
  271. expression *e = l->exp;
  272. extract_maps(e);
  273. }
  274. /* Set the region from the input maps*/
  275. if (region_approach == 2)
  276. prepare_region_from_maps_union(map_list, num_maps);
  277. if (region_approach == 3)
  278. prepare_region_from_maps_intersect(map_list, num_maps);
  279. setup_region();
  280. /* Parse each expression and initialize the maps, buffers and variables */
  281. for (l = ee; l; l = l->next) {
  282. expression *e = l->exp;
  283. const char *var;
  284. expression *val;
  285. initialize(e);
  286. if (e->type != expr_type_binding)
  287. continue;
  288. var = e->data.bind.var;
  289. val = e->data.bind.val;
  290. e->data.bind.fd = open_output_map(var, val->res_type);
  291. }
  292. setup_maps();
  293. count = rows * depths;
  294. n = 0;
  295. G_init_workers();
  296. for (current_depth = 0; current_depth < depths; current_depth++) {
  297. for (current_row = 0; current_row < rows; current_row++) {
  298. if (verbose)
  299. G_percent(n, count, 2);
  300. for (l = ee; l; l = l->next) {
  301. expression *e = l->exp;
  302. int fd;
  303. evaluate(e);
  304. if (e->type != expr_type_binding)
  305. continue;
  306. fd = e->data.bind.fd;
  307. put_map_row(fd, e->buf, e->res_type);
  308. }
  309. n++;
  310. }
  311. }
  312. G_finish_workers();
  313. if (verbose)
  314. G_percent(n, count, 2);
  315. close_maps();
  316. for (l = ee; l; l = l->next) {
  317. expression *e = l->exp;
  318. const char *var;
  319. expression *val;
  320. int fd;
  321. if (e->type != expr_type_binding)
  322. continue;
  323. var = e->data.bind.var;
  324. val = e->data.bind.val;
  325. fd = e->data.bind.fd;
  326. close_output_map(fd);
  327. e->data.bind.fd = -1;
  328. if (val->type == expr_type_map) {
  329. if (val->data.map.mod == 'M') {
  330. copy_cats(var, val->data.map.idx);
  331. copy_colors(var, val->data.map.idx);
  332. }
  333. copy_history(var, val->data.map.idx);
  334. }
  335. else
  336. create_history(var, val);
  337. }
  338. G_unset_error_routine();
  339. }
  340. void describe_maps(FILE *fp, expr_list *ee)
  341. {
  342. expr_list *l;
  343. fprintf(fp, "output=");
  344. for (l = ee; l; l = l->next) {
  345. expression *e = l->exp;
  346. const char *var;
  347. if (e->type != expr_type_binding && e->type != expr_type_function)
  348. G_fatal_error("internal error: execute: invalid type: %d",
  349. e->type);
  350. initialize(e);
  351. if (e->type != expr_type_binding)
  352. continue;
  353. var = e->data.bind.var;
  354. fprintf(fp, "%s%s", l != ee ? "," : "", var);
  355. }
  356. fprintf(fp, "\n");
  357. fprintf(fp, "input=");
  358. list_maps(fp, ",");
  359. fprintf(fp, "\n");
  360. }
  361. /****************************************************************************/