grass2str.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /****************************************************************************
  2. *
  3. * MODULE: r.terraflow
  4. *
  5. * COPYRIGHT (C) 2007 Laura Toma
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. *****************************************************************************/
  18. #ifndef _gras2str_H
  19. #define _gras2str_H
  20. #include <grass/iostream/ami.h>
  21. #include <grass/glocale.h>
  22. #include "option.h"
  23. #include "types.h"
  24. #include "common.h"
  25. #include "nodata.h" /* for TERRAFLOW_INTERNAL_NODATA_VALUE */
  26. /* ---------------------------------------------------------------------- */
  27. /* create and return a STREAM containing the given cell; nodata_count
  28. is set to the number of cells that contain nodata */
  29. template<class T>
  30. AMI_STREAM<T>*
  31. cell2stream(char* cellname, elevation_type T_max_value, long* nodata_count) {
  32. Rtimer rt;
  33. AMI_err ae;
  34. elevation_type T_min_value = -T_max_value;
  35. rt_start(rt);
  36. assert(cellname && nodata_count);
  37. *nodata_count = 0;
  38. /* create output stream */
  39. AMI_STREAM<T>* str = new AMI_STREAM<T>();
  40. {
  41. char * foo;
  42. str->name(&foo);
  43. if (stats)
  44. *stats << "Reading raster map <" << cellname
  45. << "> to stream <" << foo << ">." << endl;
  46. G_verbose_message(_("Reading data from <%s> to stream <%s>"), cellname, foo);
  47. }
  48. const char *mapset;
  49. mapset = G_find_raster (cellname, "");
  50. if (mapset == NULL)
  51. G_fatal_error(_("Raster map <%s> not found"), cellname);
  52. /* open map */
  53. int infd;
  54. if ( (infd = Rast_open_old (cellname, mapset)) < 0)
  55. G_fatal_error(_("Unable to open raster map <%s>"), cellname);
  56. /* determine map type (CELL/FCELL/DCELL) */
  57. RASTER_MAP_TYPE data_type;
  58. data_type = Rast_map_type(cellname, mapset);
  59. /* Allocate input buffer */
  60. void *inrast;
  61. inrast = Rast_allocate_buf(data_type);
  62. CELL c;
  63. FCELL f;
  64. DCELL d;
  65. T x;
  66. int isnull = 0;
  67. for (int i = 0; i< nrows; i++) {
  68. /* read input map */
  69. Rast_get_row (infd, inrast, i, data_type);
  70. for (int j=0; j<ncols; j++) {
  71. switch (data_type) {
  72. case CELL_TYPE:
  73. c = ((CELL *) inrast)[j];
  74. isnull = Rast_is_c_null_value(&c);
  75. if (!isnull) {
  76. x = (T)c; d = (DCELL)c;
  77. }
  78. break;
  79. case FCELL_TYPE:
  80. f = ((FCELL *) inrast)[j];
  81. isnull = Rast_is_f_null_value(&f);
  82. if (!isnull) {
  83. x = (T)f; d = (DCELL)f;
  84. }
  85. break;
  86. case DCELL_TYPE:
  87. d = ((DCELL *) inrast)[j];
  88. isnull = Rast_is_d_null_value(&d);
  89. if (!isnull) {
  90. x = (T)d;
  91. }
  92. break;
  93. default:
  94. G_fatal_error("Raster type not implemented");
  95. }
  96. /* cout << form("(i=%d,j=%d): (%d, %f)\n",i,j,x,d); cout.flush(); */
  97. /* handle null values */
  98. if (isnull) {
  99. x = TERRAFLOW_INTERNAL_NODATA_VALUE;
  100. (*nodata_count)++;
  101. } else {
  102. /* check range */
  103. if ((d > (DCELL)T_max_value) || (d < (DCELL)T_min_value)) {
  104. G_fatal_error("Value out of range, reading raster map <%s> "
  105. "at (i=%d, j=%d) value=%.1f",
  106. cellname, i, j, d);
  107. }
  108. }
  109. /* write x to stream */
  110. ae = str->write_item(x);
  111. assert(ae == AMI_ERROR_NO_ERROR);
  112. } /* for j */
  113. if (opt->verbose) G_percent(i, nrows, 2);
  114. }/* for i */
  115. if (opt->verbose)
  116. G_percent(1, 1, 2); /* finish it */
  117. /* delete buffers */
  118. G_free(inrast);
  119. /* close map files */
  120. Rast_close (infd);
  121. G_debug(3, "nrows=%d ncols=%d stream_len()=%"PRI_OFF_T, nrows, ncols,
  122. str->stream_len());
  123. assert((off_t) nrows * ncols == str->stream_len());
  124. rt_stop(rt);
  125. if (stats)
  126. stats->recordTime("reading raster map", rt);
  127. return str;
  128. }
  129. /* ---------------------------------------------------------------------- */
  130. template<class T>
  131. void
  132. stream2_CELL(AMI_STREAM<T>* str, dimension_type nrows, dimension_type ncols,
  133. char* cellname, bool usefcell=false) {
  134. Rtimer rt;
  135. AMI_err ae;
  136. RASTER_MAP_TYPE mtype= (usefcell ? FCELL_TYPE : CELL_TYPE);
  137. rt_start(rt);
  138. assert(str);
  139. assert(str->stream_len() == nrows*ncols);
  140. str->seek(0);
  141. {
  142. char * foo;
  143. str->name(&foo);
  144. if (stats)
  145. *stats << "Writing stream <" << foo << "> to raster map <" << cellname << ">.\n";
  146. G_verbose_message(_("Writing stream <%s> to raster map <%s>"), foo, cellname);
  147. }
  148. /* open output raster map */
  149. int outfd;
  150. if ( (outfd = Rast_open_new (cellname, mtype)) < 0)
  151. G_fatal_error (_("Unable to create raster map <%s>"), cellname);
  152. /* Allocate output buffer */
  153. unsigned char *outrast;
  154. outrast = (unsigned char *)Rast_allocate_buf(mtype);
  155. assert(outrast);
  156. T* elt;
  157. for (int i=0; i< nrows; i++) {
  158. for (int j=0; j< ncols; j++) {
  159. /* READ VALUE */
  160. ae = str->read_item(&elt);
  161. if (ae != AMI_ERROR_NO_ERROR) {
  162. str->sprint();
  163. G_fatal_error(_("stream2cell: Reading stream failed at (%d,%d)"),
  164. i, j);
  165. }
  166. /* WRITE VALUE */
  167. if(usefcell){
  168. if (is_nodata(*elt)) {
  169. Rast_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
  170. } else {
  171. ((FCELL *) outrast)[j] = (FCELL)(*elt);
  172. }
  173. }else{
  174. if (is_nodata(*elt)) {
  175. Rast_set_c_null_value( &( ((CELL *) outrast)[j]), 1);
  176. } else {
  177. ((CELL *) outrast)[j] = (CELL)(*elt);
  178. }
  179. }
  180. } /* for j*/
  181. Rast_put_row (outfd, outrast, mtype);
  182. G_percent(i, nrows, 2);
  183. }/* for i */
  184. G_percent(1, 1, 2); /* finish it */
  185. G_free(outrast);
  186. Rast_close (outfd);
  187. rt_stop(rt);
  188. if (stats)
  189. stats->recordTime("writing raster map", rt);
  190. str->seek(0);
  191. return;
  192. }
  193. /* laura: this is identical with stream2_FCELL; did not know how to
  194. template ona type --- is that possible? */
  195. /* ---------------------------------------------------------------------- */
  196. template<class T, class FUN>
  197. void
  198. stream2_CELL(AMI_STREAM<T> *str, dimension_type nrows, dimension_type ncols,
  199. FUN fmt, char* cellname) {
  200. Rtimer rt;
  201. AMI_err ae;
  202. assert(str && cellname);
  203. /* assert(str->stream_len() == nrows*ncols); */
  204. rt_start(rt);
  205. str->seek(0);
  206. {
  207. char * foo;
  208. str->name(&foo);
  209. if (stats)
  210. *stats << "Writing stream <" << foo << "> to raster map <" << cellname << ">." << endl;
  211. G_verbose_message(_("Writing stream <%s> to raster map <%s>"), foo, cellname);
  212. }
  213. /* open output raster map */
  214. int outfd;
  215. if ( (outfd = Rast_open_new (cellname, CELL_TYPE)) < 0) {
  216. G_fatal_error(_("Could not open <%s>"), cellname);
  217. }
  218. /* Allocate output buffer */
  219. unsigned char *outrast;
  220. outrast = (unsigned char *)Rast_allocate_buf(CELL_TYPE);
  221. assert(outrast);
  222. T* elt;
  223. ae = str->read_item(&elt);
  224. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  225. for (int i=0; i< nrows; i++) {
  226. for (int j=0; j< ncols; j++) {
  227. if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
  228. /* WRITE VALUE */
  229. if (is_nodata ( fmt(*elt) )) {
  230. Rast_set_c_null_value( &( ((CELL *) outrast)[j]), 1);
  231. } else {
  232. ((CELL *) outrast)[j] = (CELL)(fmt(*elt));
  233. }
  234. ae = str->read_item(&elt);
  235. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  236. } else {
  237. /* WRITE NODATA */
  238. Rast_set_c_null_value( &( ((CELL *) outrast)[j]), 1);
  239. }
  240. } /* for j*/
  241. Rast_put_row (outfd, outrast, CELL_TYPE);
  242. G_percent(i, nrows, 2);
  243. }/* for i */
  244. G_percent(1, 1, 2); /* finish it */
  245. G_free(outrast);
  246. Rast_close (outfd);
  247. rt_stop(rt);
  248. if (stats)
  249. stats->recordTime("writing raster map", rt);
  250. str->seek(0);
  251. return;
  252. }
  253. /* ---------------------------------------------------------------------- */
  254. template<class T, class FUN>
  255. void
  256. stream2_FCELL(AMI_STREAM<T> *str, dimension_type nrows, dimension_type ncols,
  257. FUN fmt, char* cellname) {
  258. Rtimer rt;
  259. AMI_err ae;
  260. assert(str && cellname);
  261. /* assert(str->stream_len() == nrows*ncols); */
  262. rt_start(rt);
  263. str->seek(0);
  264. {
  265. char * foo;
  266. str->name(&foo);
  267. if (stats)
  268. *stats << "Writing stream <" << foo << "> to raster map <" << cellname << ">." << endl;
  269. G_verbose_message(_("Writing stream <%s> to raster map <%s>"), foo, cellname);
  270. }
  271. /* open output raster map */
  272. int outfd;
  273. if ( (outfd = Rast_open_new (cellname, FCELL_TYPE)) < 0) {
  274. G_fatal_error(_("Could not open <%s>"), cellname);
  275. }
  276. /* Allocate output buffer */
  277. unsigned char *outrast;
  278. outrast = (unsigned char *)Rast_allocate_buf(FCELL_TYPE);
  279. assert(outrast);
  280. T* elt;
  281. ae = str->read_item(&elt);
  282. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  283. for (int i=0; i< nrows; i++) {
  284. for (int j=0; j< ncols; j++) {
  285. if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
  286. /* WRITE VALUE */
  287. if (is_nodata ( fmt(*elt) )) {
  288. Rast_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
  289. } else {
  290. ((FCELL *) outrast)[j] = (FCELL)(fmt(*elt));
  291. }
  292. ae = str->read_item(&elt);
  293. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  294. } else {
  295. /* WRITE NODATA */
  296. Rast_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
  297. }
  298. } /* for j*/
  299. Rast_put_row (outfd, outrast, FCELL_TYPE);
  300. G_percent(i, nrows, 2);
  301. }/* for i */
  302. G_percent(1, 1, 2); /* finish it */
  303. G_free(outrast);
  304. Rast_close (outfd);
  305. rt_stop(rt);
  306. if (stats)
  307. stats->recordTime("writing raster map", rt);
  308. str->seek(0);
  309. return;
  310. }
  311. /* ---------------------------------------------------------------------- */
  312. /* outstr is sorted by (i,j);
  313. class sweepOutput {
  314. public:
  315. dimension_type i,j;
  316. flowaccumulation_type accu;
  317. #ifdef OUTPUT_TCI
  318. tci_type tci;
  319. #endif
  320. };
  321. create an accu raster map, and a tci raster map if OUTPUT_TCI is defined
  322. */
  323. template<class T, class FUN1, class FUN2>
  324. void
  325. stream2_FCELL(AMI_STREAM<T>* str, dimension_type nrows, dimension_type ncols,
  326. FUN1 fmt1, FUN2 fmt2,
  327. char* cellname1, char* cellname2) {
  328. Rtimer rt;
  329. AMI_err ae;
  330. assert(str);
  331. #ifndef OUTPUT_TCI
  332. /* this function should be used only if tci is wanted as output */
  333. G_warning("Use this function only if tci is wanted as output");
  334. exit(1);
  335. #else
  336. rt_start(rt);
  337. str->seek(0);
  338. {
  339. char * foo;
  340. str->name(&foo);
  341. if (stats)
  342. *stats << "Writing stream <" << foo << "> to raster maps <"
  343. << cellname1 << "> and <" << cellname2 << ">." << endl;
  344. G_verbose_message(_("Writing stream <%s> to raster maps <%s> and <%s>"),
  345. foo, cellname1, cellname2);
  346. }
  347. /* open raster maps */
  348. int fd1;
  349. if ( (fd1 = Rast_open_new (cellname1, FCELL_TYPE)) < 0) {
  350. G_fatal_error(_("Could not open <%s>"), cellname1);
  351. }
  352. int fd2;
  353. if ( (fd2 = Rast_open_new (cellname2, FCELL_TYPE)) < 0) {
  354. G_fatal_error(_("Could not open <%s>"), cellname2);
  355. }
  356. /* Allocate output buffers */
  357. FCELL *rast1;
  358. rast1 = (FCELL*)Rast_allocate_buf(FCELL_TYPE);
  359. assert(rast1);
  360. FCELL *rast2;
  361. rast2 = (FCELL*)Rast_allocate_buf(FCELL_TYPE);
  362. assert(rast2);
  363. T* elt;
  364. ae = str->read_item(&elt);
  365. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  366. for (int i=0; i< nrows; i++) {
  367. for (int j=0; j< ncols; j++) {
  368. if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
  369. /* WRITE VALUE */
  370. if (is_nodata(fmt1(*elt))) {
  371. Rast_set_f_null_value(&(rast1[j]), 1);
  372. } else {
  373. rast1[j] = fmt1(*elt);
  374. };
  375. if (is_nodata( fmt2(*elt))) {
  376. Rast_set_f_null_value(&(rast2[j]), 1);
  377. } else {
  378. rast2[j] = fmt2(*elt);
  379. }
  380. /* read next value */
  381. ae = str->read_item(&elt);
  382. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  383. } else {
  384. /* WRITE NODATA */
  385. Rast_set_f_null_value(&(rast1[j]), 1);
  386. Rast_set_f_null_value(&(rast2[j]), 1);
  387. }
  388. } /* for j*/
  389. Rast_put_row (fd1, rast1, FCELL_TYPE);
  390. Rast_put_row (fd2, rast2, FCELL_TYPE);
  391. G_percent(i, nrows, 2);
  392. }/* for i */
  393. G_percent(1, 1, 2); /* finish it */
  394. G_free(rast1);
  395. Rast_close (fd1);
  396. G_free(rast2);
  397. Rast_close (fd2);
  398. rt_stop(rt);
  399. if (stats)
  400. stats->recordTime("writing stream to raster maps", rt);
  401. str->seek(0);
  402. return;
  403. #endif
  404. }
  405. #endif