flow.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. #include <time.h>
  19. #include <ctype.h>
  20. #include "flow.h"
  21. #include "sweep.h"
  22. #include "option.h"
  23. #include "common.h"
  24. #include "sortutils.h"
  25. #include "streamutils.h"
  26. #include "water.h"
  27. #include "3scan.h"
  28. /* globals in common.H
  29. extern statsRecorder *stats; stats file
  30. extern userOptions *opt; command-line options
  31. extern struct Cell_head *region; header of the region
  32. extern dimension_type nrows, ncols;
  33. */
  34. /* defined in this module */
  35. AMI_STREAM<sweepItem>*
  36. fillstr2sweepstr(AMI_STREAM<waterWindowBaseType>* flowStream);
  37. /* ********************************************************************** */
  38. /* deletes fillStream */
  39. void
  40. computeFlowAccumulation(AMI_STREAM<waterWindowBaseType>* fillStream,
  41. AMI_STREAM<sweepOutput> *& outstr) {
  42. Rtimer rt, rtTotal;
  43. AMI_STREAM<sweepItem> *sweepstr;
  44. rt_start(rtTotal);
  45. assert(fillStream && outstr == NULL);
  46. if (stats) {
  47. stats->comment("------------------------------");
  48. stats->comment("COMPUTING FLOW ACCUMULATION");
  49. }
  50. { /* timestamp stats file and print memory */
  51. time_t t = time(NULL);
  52. char buf[BUFSIZ];
  53. if(t == (time_t)-1) {
  54. perror("time");
  55. exit(1);
  56. }
  57. #ifdef __MINGW32__
  58. strcpy(buf, ctime(&t));
  59. #else
  60. ctime_r(&t, buf);
  61. buf[24] = '\0';
  62. #endif
  63. if (stats) {
  64. stats->timestamp(buf);
  65. *stats << endl;
  66. }
  67. size_t mm_size = (opt->mem << 20); /* (in bytes) */
  68. formatNumber(buf, mm_size);
  69. if (stats)
  70. *stats << "memory size: " << buf << " bytes\n";
  71. }
  72. /* create sweepstream using info from fillStream */
  73. sweepstr = fillstr2sweepstr(fillStream);
  74. /* fillStream is deleted inside fillstr2sweepstr */
  75. /* sweep and dump outputs into outStream; trustdir=1 */
  76. outstr = sweep(sweepstr, opt->d8cut, 1);
  77. assert(outstr->stream_len() == sweepstr->stream_len());
  78. delete sweepstr;
  79. /* sort output stream into a grid */
  80. rt_start(rt);
  81. if (stats) {
  82. stats->comment( "sorting sweep output stream");
  83. stats->recordLength("output stream", outstr);
  84. }
  85. sort(&outstr, ijCmpSweepOutput());
  86. rt_stop(rt);
  87. if (stats) {
  88. stats->recordLength("output stream", outstr);
  89. stats->recordTime("sorting output stream", rt);
  90. }
  91. rt_stop(rtTotal);
  92. if (stats)
  93. stats->recordTime("compute flow accumulation", rtTotal);
  94. #ifdef SAVE_ASCII
  95. printStream2Grid(outstr, nrows, ncols, "flowaccumulation.asc",
  96. printAccumulationAscii());
  97. printStream2Grid(outstr, nrows, ncols, "tci.asc",
  98. printTciAscii());
  99. #endif
  100. return;
  101. }
  102. /****************************************************************/
  103. class flow_waterWindower {
  104. private:
  105. AMI_STREAM<sweepItem> *sweep_str;
  106. public:
  107. flow_waterWindower(AMI_STREAM<sweepItem> *str) :
  108. sweep_str(str) {};
  109. void processWindow(dimension_type i, dimension_type j,
  110. waterWindowBaseType *a,
  111. waterWindowBaseType *b,
  112. waterWindowBaseType *c);
  113. };
  114. /****************************************************************/
  115. void
  116. flow_waterWindower::processWindow(dimension_type i, dimension_type j,
  117. waterWindowBaseType *a,
  118. waterWindowBaseType *b,
  119. waterWindowBaseType *c) {
  120. elevation_type el1[3], el2[3], el3[3];
  121. toporank_type ac1[3], ac2[3], ac3[3];
  122. if (is_nodata(b[1].el)) {
  123. /*sweep_str does not include nodata */
  124. return;
  125. }
  126. /*#ifdef COMPRESSED_WINDOWS
  127. sweepItem win = sweepItem(i, j, a, b, c);
  128. #else
  129. */
  130. for (int k=0; k<3; k++) {
  131. el1[k] = a[k].el;
  132. ac1[k] = -a[k].depth; /*WEIRD */
  133. el2[k] = b[k].el;
  134. ac2[k] = -b[k].depth; /*WEIRD*/
  135. el3[k] = c[k].el;
  136. ac3[k] = -c[k].depth; /*WEIRD*/
  137. }
  138. /*
  139. genericWindow<elevation_type> e_win(el);
  140. genericWindow<toporank_type> a_win(ac);
  141. sweepItem win = sweepItem(i, j, b[1].dir, e_win, a_win);
  142. */
  143. sweepItem win = sweepItem(i, j, b[1].dir, el1, el2, el3, ac1, ac2, ac3);
  144. /* #endif */
  145. AMI_err ae = sweep_str->write_item(win);
  146. assert(ae == AMI_ERROR_NO_ERROR);
  147. }
  148. /****************************************************************/
  149. void
  150. waterWindowBaseType2sweepItem(AMI_STREAM<waterWindowBaseType> *baseStr,
  151. const dimension_type nrows,
  152. const dimension_type ncols,
  153. const elevation_type nodata_value,
  154. AMI_STREAM<sweepItem> *sweep_str) {
  155. flow_waterWindower winfo(sweep_str);
  156. waterWindowBaseType nodata((elevation_type)nodata_value,
  157. (direction_type)nodata_value,
  158. DEPTH_INITIAL);
  159. /*
  160. assert(baseStr->stream_len() > 0);
  161. XXX - should check if it fits in memory technically don't need to
  162. give the template args, but seems to help the compiler
  163. memoryScan(*baseStr, hdr, nodata, winfo);
  164. */
  165. memoryScan<waterWindowBaseType,flow_waterWindower>(*baseStr, nrows, ncols, nodata, winfo);
  166. }
  167. /****************************************************************/
  168. /* open fill's output stream and get all info from there; delete
  169. fillStream */
  170. AMI_STREAM<sweepItem>*
  171. fillstr2sweepstr(AMI_STREAM<waterWindowBaseType>* fillStream) {
  172. Rtimer rt;
  173. AMI_STREAM<sweepItem> *sweepstr;
  174. rt_start(rt);
  175. if (stats)
  176. stats->comment("creating sweep stream from fill output stream");
  177. assert(fillStream->stream_len() == (off_t)nrows * ncols);
  178. /* create the sweep stream */
  179. sweepstr = new AMI_STREAM<sweepItem>();
  180. waterWindowBaseType2sweepItem(fillStream, nrows, ncols,
  181. nodataType::ELEVATION_NODATA, sweepstr);
  182. delete fillStream;
  183. G_debug(1, "sweep stream size: %.2fMB",
  184. (double)sweepstr->stream_len()*sizeof(sweepItem)/(1<<20));
  185. G_debug(1, " (%d items, item size=%ld B\n ",
  186. (int)sweepstr->stream_len(), sizeof(sweepItem));;
  187. if (stats)
  188. stats->recordLength("sweep stream", sweepstr);
  189. /* sort sweep stream by (increasing) priority */
  190. G_debug(1, "Sorting sweep stream (%.2fMB) in priority order",
  191. (double)sweepstr->stream_len()*sizeof(sweepItem)/(1<<20));
  192. if (stats)
  193. stats->comment("sorting sweep stream");
  194. sort(&sweepstr, PrioCmpSweepItem());
  195. rt_stop(rt);
  196. if (stats) {
  197. stats->recordTime("create sweep stream", rt);
  198. stats->recordLength("(sorted) sweep stream", sweepstr);
  199. }
  200. return sweepstr;
  201. }