grass2str.h 12 KB

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