streamutils.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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 STREAMUTILS_H
  19. #define STREAMUTILS_H
  20. #include <fstream>
  21. using namespace std;
  22. #include <grass/iostream/ami.h>
  23. #include "types.h"
  24. #include "common.h"
  25. template<class T>
  26. void
  27. printStream(ostream &s, AMI_STREAM<T> *str) {
  28. T *elt;
  29. AMI_err ae;
  30. str->seek(0);
  31. while((ae = str->read_item(&elt)) == AMI_ERROR_NO_ERROR) {
  32. s << *elt << endl;
  33. }
  34. str->seek(0);
  35. }
  36. /* laura note: this works that class T has an empty contructor which
  37. initializes it to the nodata value */
  38. template<class T, class FUN>
  39. void
  40. printStream2Grid(AMI_STREAM<T> *str,
  41. dimension_type nrows, dimension_type ncols,
  42. const char *name,
  43. FUN fmt) {
  44. T *elt, nodata;
  45. AMI_err ae;
  46. ofstream fstrm(name);
  47. if (stats)
  48. stats->comment("saving grid: ", name);
  49. fstrm << "rows=" << nrows << endl;
  50. fstrm << "cols=" << ncols << endl;
  51. str->seek(0);
  52. ae = str->read_item(&elt);
  53. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  54. for(dimension_type i=0; i<nrows; i++) {
  55. for(dimension_type j=0; j<ncols; j++) {
  56. if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
  57. fstrm << " " << fmt(*elt);
  58. ae = str->read_item(&elt);
  59. assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
  60. } else {
  61. fstrm << " " << fmt(nodata);
  62. }
  63. } /* for j */
  64. fstrm << endl;
  65. }
  66. assert(ae == AMI_ERROR_END_OF_STREAM); /* stream must have finished */
  67. str->seek(0);
  68. }
  69. template<class T, class FUN>
  70. void printGridStream(AMI_STREAM<T> *str,
  71. dimension_type nrows, dimension_type ncols,
  72. char *name,
  73. FUN fmt) {
  74. T *elt;
  75. AMI_err ae;
  76. ofstream fstrm(name);
  77. if (stats)
  78. stats->recordLength("saving grid", str);
  79. fstrm << "rows=" << nrows << endl;
  80. fstrm << "cols=" << ncols << endl;
  81. assert(str->stream_len() == nrows * ncols);
  82. str->seek(0);
  83. for(dimension_type i=0; i<nrows; i++) {
  84. for(dimension_type j=0; j<ncols; j++) {
  85. ae = str->read_item(&elt);
  86. assert(ae == AMI_ERROR_NO_ERROR);
  87. fstrm << " " << fmt(*elt);
  88. }
  89. fstrm << endl;
  90. }
  91. str->seek(0);
  92. }
  93. /* ********************************************************************** */
  94. /* assume sorted... */
  95. template<class T, class FUN>
  96. AMI_STREAM<T> *
  97. removeDuplicates(AMI_STREAM<T> *str, FUN fo) {
  98. AMI_err ae;
  99. AMI_STREAM<T> *newStr = new AMI_STREAM<T>();
  100. if(str->stream_len() == 0) return newStr; /* empty stream */
  101. str->seek(0);
  102. T prev, *elp;
  103. ae = str->read_item(&elp);
  104. assert(ae == AMI_ERROR_NO_ERROR);
  105. prev = *elp;
  106. while((ae = str->read_item(&elp)) == AMI_ERROR_NO_ERROR) {
  107. if(fo.compare(*elp, prev)) { /* differ */
  108. newStr->write_item(prev);
  109. prev = *elp;
  110. } else {
  111. /* cout << "duplicate: " << *elp << " of " << prev << endl; */
  112. }
  113. }
  114. newStr->write_item(prev); /* last one */
  115. return newStr;
  116. }
  117. /* ********************************************************************** */
  118. template<class T, class FUN>
  119. void
  120. removeDuplicatesEx(AMI_STREAM<T> **str, FUN fo) {
  121. AMI_STREAM<T> *tmp = removeDuplicates(*str, fo);
  122. delete *str;
  123. *str = tmp;
  124. }
  125. /* ********************************************************************** */
  126. /*
  127. * merge a grid and a stream together to form an new grid of the original type
  128. * str should be sorted in ij order
  129. */
  130. template<class T, class TT, class FUN>
  131. AMI_STREAM<T> *
  132. mergeStream2Grid(AMI_STREAM<T> *grid,
  133. dimension_type rows, dimension_type cols,
  134. AMI_STREAM<TT> *str,
  135. FUN fo) {
  136. AMI_err ae, aeS;
  137. T *gep; /* grid element */
  138. TT *sep; /* stream element */
  139. AMI_STREAM<T> *mergeStr = new AMI_STREAM<T>();
  140. str->seek(0);
  141. grid->seek(0);
  142. aeS = str->read_item(&sep);
  143. assert(aeS == AMI_ERROR_NO_ERROR || aeS == AMI_ERROR_END_OF_STREAM);
  144. for(dimension_type i=0; i<rows; i++) {
  145. for(dimension_type j=0; j<cols; j++) {
  146. ae = grid->read_item(&gep);
  147. assert(ae == AMI_ERROR_NO_ERROR);
  148. if((aeS == AMI_ERROR_NO_ERROR) && (sep->i == i) && (sep->j == j)) {
  149. ae = mergeStr->write_item(fo(*sep));
  150. assert(ae == AMI_ERROR_NO_ERROR);
  151. aeS = str->read_item(&sep);
  152. assert(aeS == AMI_ERROR_NO_ERROR || aeS == AMI_ERROR_END_OF_STREAM);
  153. } else {
  154. ae = mergeStr->write_item(fo(*gep));
  155. assert(ae == AMI_ERROR_NO_ERROR);
  156. }
  157. }
  158. }
  159. return mergeStr;
  160. }
  161. #endif