map.c 15 KB

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