map3.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. #include <stdlib.h>
  2. #include <limits.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <grass/gis.h>
  6. #include <grass/raster.h>
  7. #include <grass/raster.h>
  8. #include <grass/raster3d.h>
  9. #include <grass/btree.h>
  10. #include <grass/glocale.h>
  11. #include <grass/calc.h>
  12. #include "mapcalc.h"
  13. #include "globals.h"
  14. #include "globals3.h"
  15. /****************************************************************************/
  16. static void prepare_region_from_maps(expression **, int, int);
  17. RASTER3D_Region current_region3;
  18. void setup_region(void)
  19. {
  20. Rast3d_init_defaults();
  21. Rast3d_get_window(&current_region3);
  22. rows = current_region3.rows;
  23. columns = current_region3.cols;
  24. depths = current_region3.depths;
  25. calc_init(columns);
  26. }
  27. /****************************************************************************/
  28. typedef struct map
  29. {
  30. const char *name;
  31. const char *mapset;
  32. int have_cats;
  33. int have_colors;
  34. int min_row, max_row;
  35. void *handle;
  36. int fd;
  37. struct Categories cats;
  38. struct Colors colors;
  39. BTREE btree;
  40. } map;
  41. /****************************************************************************/
  42. static map *maps;
  43. static int num_maps;
  44. static int max_maps;
  45. static void **omaps;
  46. static int num_omaps;
  47. static int max_omaps;
  48. static unsigned char *red, *grn, *blu;
  49. static unsigned char *set;
  50. static int min_row = INT_MAX;
  51. static int max_row = -INT_MAX;
  52. static int min_col = INT_MAX;
  53. static int max_col = -INT_MAX;
  54. /****************************************************************************/
  55. static void read_row(void *handle, char *buf, int type, int depth, int row)
  56. {
  57. int i;
  58. switch (type) {
  59. case CELL_TYPE:
  60. for (i = 0; i < columns; i++) {
  61. double x;
  62. Rast3d_get_value(handle, i, row, depth, (char *)&x, DCELL_TYPE);
  63. if (Rast3d_is_null_value_num(&x, DCELL_TYPE))
  64. SET_NULL_C(&((CELL *) buf)[i]);
  65. else
  66. ((CELL *) buf)[i] = (CELL) x;
  67. }
  68. break;
  69. case FCELL_TYPE:
  70. for (i = 0; i < columns; i++) {
  71. float x;
  72. Rast3d_get_value(handle, i, row, depth, (char *)&x, FCELL_TYPE);
  73. if (Rast3d_is_null_value_num(&x, FCELL_TYPE))
  74. SET_NULL_F(&((FCELL *) buf)[i]);
  75. else
  76. ((FCELL *) buf)[i] = x;
  77. }
  78. break;
  79. case DCELL_TYPE:
  80. for (i = 0; i < columns; i++) {
  81. double x;
  82. Rast3d_get_value(handle, i, row, depth, (char *)&x, DCELL_TYPE);
  83. if (Rast3d_is_null_value_num(&x, DCELL_TYPE))
  84. SET_NULL_D(&((DCELL *) buf)[i]);
  85. else
  86. ((DCELL *) buf)[i] = x;
  87. }
  88. break;
  89. }
  90. }
  91. static void write_row(void *handle, const char *buf, int type, int depth,
  92. int row)
  93. {
  94. int i;
  95. switch (type) {
  96. case CELL_TYPE:
  97. for (i = 0; i < columns; i++) {
  98. double x;
  99. if (IS_NULL_C(&((CELL *) buf)[i]))
  100. Rast3d_set_null_value(&x, 1, DCELL_TYPE);
  101. else
  102. x = ((CELL *) buf)[i];
  103. if (Rast3d_put_value(handle, i, row, depth, (char *)&x, DCELL_TYPE) <
  104. 0)
  105. G_fatal_error(_("Error writing data"));
  106. }
  107. break;
  108. case FCELL_TYPE:
  109. for (i = 0; i < columns; i++) {
  110. float x;
  111. if (IS_NULL_F(&((FCELL *) buf)[i]))
  112. Rast3d_set_null_value(&x, 1, FCELL_TYPE);
  113. else
  114. x = ((FCELL *) buf)[i];
  115. if (Rast3d_put_value(handle, i, row, depth, (char *)&x, FCELL_TYPE) <
  116. 0)
  117. G_fatal_error(_("Error writing data"));
  118. }
  119. break;
  120. case DCELL_TYPE:
  121. for (i = 0; i < columns; i++) {
  122. double x;
  123. if (IS_NULL_D(&((DCELL *) buf)[i]))
  124. Rast3d_set_null_value(&x, 1, DCELL_TYPE);
  125. else
  126. x = ((DCELL *) buf)[i];
  127. if (Rast3d_put_value(handle, i, row, depth, (char *)&x, DCELL_TYPE) <
  128. 0)
  129. G_fatal_error(_("Error writing data"));
  130. }
  131. break;
  132. }
  133. }
  134. /****************************************************************************/
  135. static int compare_ints(const void *a, const void *b)
  136. {
  137. return *(const int *)a - *(const int *)b;
  138. }
  139. static void init_colors(map * m)
  140. {
  141. if (!red)
  142. red = G_malloc(columns);
  143. if (!grn)
  144. grn = G_malloc(columns);
  145. if (!blu)
  146. blu = G_malloc(columns);
  147. if (!set)
  148. set = G_malloc(columns);
  149. if (Rast3d_read_colors((char *)m->name, (char *)m->mapset, &m->colors) < 0)
  150. G_fatal_error(_("Unable to read color file for raster map <%s@%s>"),
  151. m->name, m->mapset);
  152. m->have_colors = 1;
  153. }
  154. static void init_cats(map * m)
  155. {
  156. if (Rast3d_read_cats((char *)m->name, (char *)m->mapset, &m->cats) < 0)
  157. G_fatal_error(_("Unable to read category file of raster map <%s@%s>"),
  158. m->name, m->mapset);
  159. if (!btree_create(&m->btree, compare_ints, 1))
  160. G_fatal_error(_("Unable to create btree for raster map <%s@%s>"),
  161. m->name, m->mapset);
  162. m->have_cats = 1;
  163. }
  164. static void translate_from_colors(map * m, DCELL * rast, CELL * cell,
  165. int ncols, int mod)
  166. {
  167. int i;
  168. Rast_lookup_d_colors(rast, red, grn, blu, set, ncols, &m->colors);
  169. switch (mod) {
  170. case 'r':
  171. for (i = 0; i < ncols; i++)
  172. cell[i] = red[i];
  173. break;
  174. case 'g':
  175. for (i = 0; i < ncols; i++)
  176. cell[i] = grn[i];
  177. break;
  178. case 'b':
  179. for (i = 0; i < ncols; i++)
  180. cell[i] = blu[i];
  181. break;
  182. case '#': /* grey (backwards compatible) */
  183. /* old weightings: R=0.177, G=0.813, B=0.011 */
  184. for (i = 0; i < ncols; i++)
  185. cell[i] =
  186. (181 * red[i] + 833 * grn[i] + 11 * blu[i] + 512) / 1024;
  187. break;
  188. case 'y': /* grey (NTSC) */
  189. /* NTSC weightings: R=0.299, G=0.587, B=0.114 */
  190. for (i = 0; i < ncols; i++)
  191. cell[i] =
  192. (306 * red[i] + 601 * grn[i] + 117 * blu[i] + 512) / 1024;
  193. break;
  194. case 'i': /* grey (equal weight) */
  195. for (i = 0; i < ncols; i++)
  196. cell[i] = (red[i] + grn[i] + blu[i]) / 3;
  197. break;
  198. case 'M':
  199. case '@':
  200. default:
  201. G_fatal_error(_("Invalid map modifier: '%c'"), mod);
  202. break;
  203. }
  204. }
  205. /* convert cell values to double based on the values in the
  206. * category file.
  207. *
  208. * This requires performing sscanf() of the category label
  209. * and only do it it for new categories. Must maintain
  210. * some kind of maps of already scaned values.
  211. *
  212. * This maps is a hybrid tree, where the data in each node
  213. * of the tree is an array of, for example, 64 values, and
  214. * the key of the tree is the category represented by the
  215. * first index of the data
  216. *
  217. * To speed things up a little, use shifts instead of divide or multiply
  218. * to compute the key and the index
  219. *
  220. * This uses the BTREE library to manage the tree itself
  221. * btree structure must already be initialized
  222. * pcats structure must already contain category labels
  223. */
  224. #define SHIFT 6
  225. #define NCATS (1<<SHIFT)
  226. static void translate_from_cats(map * m, CELL * cell, DCELL * xcell,
  227. int ncols)
  228. {
  229. struct Categories *pcats;
  230. BTREE *btree;
  231. int i, idx;
  232. CELL cat, key;
  233. double vbuf[1 << SHIFT];
  234. double *values;
  235. void *ptr;
  236. char *label;
  237. btree = &m->btree;
  238. pcats = &m->cats;
  239. for (; ncols-- > 0; cell++, xcell++) {
  240. cat = *cell;
  241. if (IS_NULL_C(cell)) {
  242. SET_NULL_D(xcell);
  243. continue;
  244. }
  245. /* compute key as cat/NCATS * NCATS, adjusting down for negatives
  246. * and idx so that key+idx == cat
  247. */
  248. if (cat < 0)
  249. key = -(((-cat - 1) >> SHIFT) << SHIFT) - NCATS;
  250. else
  251. key = (cat >> SHIFT) << SHIFT;
  252. idx = cat - key;
  253. /* If key not already in the tree, sscanf() all cats for this key
  254. * and put them into the tree
  255. */
  256. if (!btree_find(btree, &key, &ptr)) {
  257. values = vbuf;
  258. int cat = i + key;
  259. for (i = 0; i < NCATS; i++) {
  260. if ((label = Rast_get_c_cat((CELL *) &cat, pcats)) == NULL
  261. || sscanf(label, "%lf", values) != 1)
  262. SET_NULL_D(values);
  263. values++;
  264. }
  265. values = vbuf;
  266. btree_update(btree, &key, sizeof(key), vbuf, sizeof(vbuf));
  267. }
  268. else
  269. values = ptr;
  270. /* and finally lookup the translated value */
  271. if (IS_NULL_D(&values[idx]))
  272. SET_NULL_D(xcell);
  273. else
  274. *xcell = values[idx];
  275. }
  276. }
  277. static void setup_map(map * m)
  278. {
  279. }
  280. static void read_map(map * m, void *buf, int res_type, int depth, int row,
  281. int col)
  282. {
  283. CELL *ibuf = buf;
  284. FCELL *fbuf = buf;
  285. DCELL *dbuf = buf;
  286. if (row < 0 || row >= rows || depth < 0 || depth >= depths) {
  287. int i;
  288. switch (res_type) {
  289. case CELL_TYPE:
  290. for (i = 0; i < columns; i++)
  291. SET_NULL_C(&ibuf[i]);
  292. break;
  293. case FCELL_TYPE:
  294. for (i = 0; i < columns; i++)
  295. SET_NULL_F(&fbuf[i]);
  296. break;
  297. case DCELL_TYPE:
  298. for (i = 0; i < columns; i++)
  299. SET_NULL_D(&dbuf[i]);
  300. break;
  301. default:
  302. G_fatal_error(_("Unknown type: %d"), res_type);
  303. break;
  304. }
  305. return;
  306. }
  307. read_row(m->handle, buf, res_type, depth, row);
  308. if (col)
  309. column_shift(buf, res_type, col);
  310. }
  311. static void close_map(map * m)
  312. {
  313. if (!m->handle)
  314. return;
  315. if (!Rast3d_close(m->handle))
  316. G_fatal_error(_("Unable to close raster map <%s@%s>"),
  317. m->name, m->mapset);
  318. if (m->have_cats) {
  319. btree_free(&m->btree);
  320. Rast_free_cats(&m->cats);
  321. m->have_cats = 0;
  322. }
  323. if (m->have_colors) {
  324. Rast_free_colors(&m->colors);
  325. m->have_colors = 0;
  326. }
  327. }
  328. /****************************************************************************/
  329. int map_type(const char *name, int mod)
  330. {
  331. const char *mapset;
  332. char *tmpname;
  333. int result;
  334. switch (mod) {
  335. case 'M':
  336. tmpname = G_store((char *)name);
  337. mapset = G_find_raster3d(tmpname, "");
  338. if (mapset) {
  339. void *handle;
  340. setup_region(); /* TODO: setup_region should be called by evaluate() ? */
  341. handle = Rast3d_open_cell_old(tmpname, mapset, &current_region3,
  342. RASTER3D_TILE_SAME_AS_FILE, RASTER3D_NO_CACHE);
  343. result = (Rast3d_file_type_map(handle) == FCELL_TYPE)
  344. ? FCELL_TYPE : DCELL_TYPE;
  345. Rast3d_close(handle);
  346. }
  347. else
  348. result = -1;
  349. G_free(tmpname);
  350. return result;
  351. case '@':
  352. return DCELL_TYPE;
  353. case 'r':
  354. case 'g':
  355. case 'b':
  356. case '#':
  357. case 'y':
  358. case 'i':
  359. return CELL_TYPE;
  360. default:
  361. G_fatal_error(_("Invalid map modifier: '%c'"), mod);
  362. return -1;
  363. }
  364. }
  365. int open_map(const char *name, int mod, int row, int col)
  366. {
  367. int i;
  368. const char *mapset;
  369. char *tmpname;
  370. int use_cats = 0;
  371. int use_colors = 0;
  372. map *m;
  373. if (row < min_row)
  374. min_row = row;
  375. if (row > max_row)
  376. max_row = row;
  377. if (col < min_col)
  378. min_col = col;
  379. if (col > max_col)
  380. max_col = col;
  381. tmpname = G_store((char *)name);
  382. mapset = G_find_raster3d(tmpname, "");
  383. G_free(tmpname);
  384. if (!mapset)
  385. G_fatal_error("open_map: map [%s] not found", name);
  386. switch (mod) {
  387. case 'M':
  388. break;
  389. case '@':
  390. use_cats = 1;
  391. break;
  392. case 'r':
  393. case 'g':
  394. case 'b':
  395. case '#':
  396. case 'y':
  397. case 'i':
  398. use_colors = 1;
  399. break;
  400. default:
  401. G_fatal_error(_("Invalid map modifier: '%c'"), mod);
  402. break;
  403. }
  404. for (i = 0; i < num_maps; i++) {
  405. m = &maps[i];
  406. if (strcmp(m->name, name) != 0 || strcmp(m->mapset, mapset) != 0)
  407. continue;
  408. if (row < m->min_row)
  409. m->min_row = row;
  410. if (row > m->max_row)
  411. m->max_row = row;
  412. if (use_cats && !m->have_cats)
  413. init_cats(m);
  414. if (use_colors && !m->have_colors)
  415. init_colors(m);
  416. return i;
  417. }
  418. if (num_maps >= max_maps) {
  419. max_maps += 10;
  420. maps = G_realloc(maps, max_maps * sizeof(map));
  421. }
  422. m = &maps[num_maps];
  423. m->name = name;
  424. m->mapset = mapset;
  425. m->have_cats = 0;
  426. m->have_colors = 0;
  427. m->min_row = row;
  428. m->max_row = row;
  429. if (use_cats)
  430. init_cats(m);
  431. if (use_colors)
  432. init_colors(m);
  433. m->handle = Rast3d_open_cell_old((char *)name, (char *)mapset,
  434. &current_region3, DCELL_TYPE,
  435. RASTER3D_USE_CACHE_DEFAULT);
  436. if (!m->handle)
  437. G_fatal_error(_("Unable to open raster map <%s>"), name);
  438. return num_maps++;
  439. }
  440. void setup_maps(void)
  441. {
  442. int i;
  443. /* We need to reduce the number of worker threads to one, to
  444. * avoid that several threads access a single map for reading
  445. * at the same time. The raster3d library is not thread safe.
  446. * */
  447. putenv("WORKERS=0");
  448. for (i = 0; i < num_maps; i++)
  449. setup_map(&maps[i]);
  450. }
  451. void get_map_row(int idx, int mod, int depth, int row, int col, void *buf,
  452. int res_type)
  453. {
  454. static CELL *ibuf;
  455. static DCELL *fbuf;
  456. map *m = &maps[idx];
  457. switch (mod) {
  458. case 'M':
  459. read_map(m, buf, res_type, depth, row, col);
  460. break;
  461. case '@':
  462. if (!ibuf)
  463. ibuf = G_malloc(columns * sizeof(CELL));
  464. read_map(m, ibuf, CELL_TYPE, depth, row, col);
  465. translate_from_cats(m, ibuf, buf, columns);
  466. break;
  467. case 'r':
  468. case 'g':
  469. case 'b':
  470. case '#':
  471. case 'y':
  472. case 'i':
  473. if (!fbuf)
  474. fbuf = G_malloc(columns * sizeof(DCELL));
  475. read_map(m, fbuf, DCELL_TYPE, depth, row, col);
  476. translate_from_colors(m, fbuf, buf, columns, mod);
  477. break;
  478. default:
  479. G_fatal_error(_("Invalid map modifier: '%c'"), mod);
  480. break;
  481. }
  482. }
  483. void close_maps(void)
  484. {
  485. int i;
  486. for (i = 0; i < num_maps; i++)
  487. close_map(&maps[i]);
  488. num_maps = 0;
  489. }
  490. void list_maps(FILE *fp, const char *sep)
  491. {
  492. int i;
  493. for (i = 0; i < num_maps; i++) {
  494. const struct map *m = &maps[i];
  495. fprintf(fp, "%s%s@%s", i ? sep : "", m->name, m->mapset);
  496. }
  497. }
  498. /****************************************************************************/
  499. int check_output_map(const char *name)
  500. {
  501. return !!G_find_raster3d(name, G_mapset());
  502. }
  503. int open_output_map(const char *name, int res_type)
  504. {
  505. void *handle;
  506. Rast3d_set_file_type(res_type == FCELL_TYPE ? FCELL_TYPE : DCELL_TYPE);
  507. handle = Rast3d_open_new_opt_tile_size((char *)name, RASTER3D_USE_CACHE_XYZ, &current_region3, res_type == FCELL_TYPE ? FCELL_TYPE : DCELL_TYPE, 32);
  508. if (!handle)
  509. G_fatal_error(_("Unable to create raster map <%s>"), name);
  510. if (num_omaps >= max_omaps) {
  511. max_omaps += 10;
  512. omaps = G_realloc(omaps, max_omaps * sizeof(void *));
  513. }
  514. omaps[num_omaps] = handle;
  515. return num_omaps++;
  516. }
  517. void put_map_row(int fd, void *buf, int res_type)
  518. {
  519. void *handle = omaps[fd];
  520. write_row(handle, buf, res_type, current_depth, current_row);
  521. }
  522. void close_output_map(int fd)
  523. {
  524. void *handle = omaps[fd];
  525. if (!Rast3d_close(handle))
  526. G_fatal_error(_("Unable to close output raster map"));
  527. }
  528. void unopen_output_map(int fd)
  529. {
  530. close_output_map(fd);
  531. }
  532. /****************************************************************************/
  533. void copy_cats(const char *dst, int idx)
  534. {
  535. const map *m = &maps[idx];
  536. struct Categories cats;
  537. if (Rast3d_read_cats((char *)m->name, (char *)m->mapset, &cats) < 0)
  538. return;
  539. Rast3d_write_cats((char *)dst, &cats);
  540. Rast_free_cats(&cats);
  541. }
  542. void copy_colors(const char *dst, int idx)
  543. {
  544. const map *m = &maps[idx];
  545. struct Colors colr;
  546. if (Rast3d_read_colors((char *)m->name, (char *)m->mapset, &colr) <= 0)
  547. return;
  548. Rast3d_write_colors((char *)dst, G_mapset(), &colr);
  549. Rast_free_colors(&colr);
  550. }
  551. void copy_history(const char *dst, int idx)
  552. {
  553. }
  554. void create_history(const char *dst, expression * e)
  555. {
  556. }
  557. /****************************************************************************/
  558. void prepare_region_from_maps_union(expression **map_list, int num_maps) {
  559. prepare_region_from_maps(map_list, 1, num_maps);
  560. }
  561. void prepare_region_from_maps_intersect(expression **map_list, int num_maps) {
  562. prepare_region_from_maps(map_list, 2, num_maps);
  563. }
  564. void prepare_region_from_maps(expression **map_list, int type, int num_maps) {
  565. /* \brief Setup the computational region from all 3d raster maps
  566. *
  567. * This function computes the disjoint union or intersection extent
  568. * that is covered by all 3d raster maps and sets the smallest
  569. * resolution that it can find.
  570. *
  571. * TODO: Must be implemented
  572. */
  573. G_fatal_error("Union or intersection of regions is not implemented");
  574. int first = 0;
  575. struct Cell_head window, temp_window;
  576. int i;
  577. const char *mapset;
  578. for (i = 0; i < num_maps; i++) {
  579. expression *e = map_list[i];
  580. char rast_name[GNAME_MAX];
  581. strcpy(rast_name, e->data.map.name);
  582. mapset = G_find_raster2(rast_name, "");
  583. if (!mapset)
  584. G_fatal_error(_("Raster map <%s> not found"), rast_name);
  585. G_debug(1, "Setting region from raster map: %s@%s", rast_name, mapset);
  586. Rast_get_cellhd(rast_name, mapset, &temp_window);
  587. if (!first) {
  588. window = temp_window;
  589. first = 1;
  590. }
  591. else {
  592. if (type == 1) {
  593. /* Union: find the largest extent */
  594. window.north = (window.north > temp_window.north) ?
  595. window.north : temp_window.north;
  596. window.south = (window.south < temp_window.south) ?
  597. window.south : temp_window.south;
  598. window.east = (window.east > temp_window.east) ?
  599. window.east : temp_window.east;
  600. window.west = (window.west < temp_window.west) ?
  601. window.west : temp_window.west;
  602. }
  603. else {
  604. /* Intersect: Find the smallest extent */
  605. window.north = (window.north < temp_window.north) ?
  606. window.north : temp_window.north;
  607. window.south = (window.south > temp_window.south) ?
  608. window.south : temp_window.south;
  609. window.east = (window.east < temp_window.east) ?
  610. window.east : temp_window.east;
  611. window.west = (window.west > temp_window.west) ?
  612. window.west : temp_window.west;
  613. }
  614. /* Find the smallest resolution */
  615. window.ns_res = (window.ns_res < temp_window.ns_res) ?
  616. window.ns_res : temp_window.ns_res;
  617. window.ew_res = (window.ew_res < temp_window.ew_res) ?
  618. window.ew_res : temp_window.ew_res;
  619. }
  620. }
  621. /* Set the region only if a map was found in the expression */
  622. if (first == 1) {
  623. G_adjust_Cell_head3(&window, 0, 0, 0);
  624. G_debug(1, "Region was set to n %g s %g e %g w %g ns_res %g ew_res %g", window.north,
  625. window.south, window.east, window.west, window.ns_res, window.ew_res);
  626. G_put_window(&window);
  627. }
  628. }
  629. /****************************************************************************/