map.c 16 KB

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