topidx.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include <math.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include <grass/glocale.h>
  5. #include "global.h"
  6. int natb;
  7. void initialize(void)
  8. {
  9. int i, j;
  10. natb = 0;
  11. for (i = 0; i < window.rows; i++) {
  12. for (j = 0; j < window.cols; j++) {
  13. av(i, j) = window.ns_res * window.ew_res;
  14. if (is_cv_null(i, j)) {
  15. natb++;
  16. Rast_set_d_null_value(&atbv(i, j), 1);
  17. }
  18. else {
  19. atbv(i, j) = -10.0;
  20. }
  21. }
  22. }
  23. }
  24. void calculate_atanb(void)
  25. {
  26. int i, j, k, snatb;
  27. int iter, ncells, nroute, nslp;
  28. double sum, route[9], tanB[9], dx, dx1, dx2, sumtb, C;
  29. int nsink;
  30. dx = window.ew_res;
  31. dx1 = 1 / dx;
  32. dx2 = 1 / (1.414 * dx);
  33. ncells = window.rows * window.cols;
  34. snatb = natb;
  35. G_important_message(_("Calculating..."));
  36. nsink = 0;
  37. for (iter = 1; natb < ncells; iter++) {
  38. /*
  39. for(i=0;i<80;i++)
  40. fprintf(stderr,"\b");
  41. fprintf(stderr,"Iteration: %d",iter);
  42. */
  43. G_percent(natb - snatb, ncells - snatb, 1);
  44. for (i = 0; i < window.rows; i++) {
  45. for (j = 0; j < window.cols; j++) {
  46. /* skip null values */
  47. if (is_cv_null(i, j))
  48. continue;
  49. /* skip squares already done */
  50. if (is_atbv_null(i, j) || atbv(i, j) >= ZERO)
  51. continue;
  52. /* check the 8 possible flow directions for
  53. * upslope elements without an atb value
  54. */
  55. if (i > 0) {
  56. if (j > 0 &&
  57. (is_cv_null(i - 1, j - 1) ||
  58. cv(i - 1, j - 1) > cv(i, j)) &&
  59. !is_atbv_null(i - 1, j - 1) &&
  60. atbv(i - 1, j - 1) < ZERO)
  61. continue;
  62. if ((is_cv_null(i - 1, j) ||
  63. cv(i - 1, j) > cv(i, j)) &&
  64. !is_atbv_null(i - 1, j) && atbv(i - 1, j) < ZERO)
  65. continue;
  66. if (j + 1 < window.cols &&
  67. (is_cv_null(i - 1, j + 1) ||
  68. cv(i - 1, j + 1) > cv(i, j)) &&
  69. !is_atbv_null(i - 1, j + 1) &&
  70. atbv(i - 1, j + 1) < ZERO)
  71. continue;
  72. }
  73. if (j > 0 &&
  74. (is_cv_null(i, j - 1) ||
  75. cv(i, j - 1) > cv(i, j)) &&
  76. !is_atbv_null(i, j - 1) && atbv(i, j - 1) < ZERO)
  77. continue;
  78. if (j + 1 < window.cols &&
  79. (is_cv_null(i, j + 1) ||
  80. cv(i, j + 1) > cv(i, j)) &&
  81. !is_atbv_null(i, j + 1) && atbv(i, j + 1) < ZERO)
  82. continue;
  83. if (i + 1 < window.rows) {
  84. if (j > 0 &&
  85. (is_cv_null(i + 1, j - 1) ||
  86. cv(i + 1, j - 1) > cv(i, j)) &&
  87. !is_atbv_null(i + 1, j - 1) &&
  88. atbv(i + 1, j - 1) < ZERO)
  89. continue;
  90. if ((is_cv_null(i + 1, j) ||
  91. cv(i + 1, j) > cv(i, j)) &&
  92. !is_atbv_null(i + 1, j) && atbv(i + 1, j) < ZERO)
  93. continue;
  94. if (j + 1 < window.cols &&
  95. (is_cv_null(i + 1, j + 1) ||
  96. cv(i + 1, j + 1) > cv(i, j)) &&
  97. !is_atbv_null(i + 1, j + 1) &&
  98. atbv(i + 1, j + 1) < ZERO)
  99. continue;
  100. }
  101. /* find the outflow directions and calculate
  102. * the sum of weights
  103. */
  104. sum = 0.0;
  105. for (k = 0; k < 9; k++)
  106. route[k] = 0.0;
  107. nroute = 0;
  108. if (i > 0) {
  109. if (j > 0 &&
  110. !is_cv_null(i - 1, j - 1) &&
  111. cv(i, j) - cv(i - 1, j - 1) > ZERO) {
  112. tanB[0] = (cv(i, j) - cv(i - 1, j - 1)) * dx2;
  113. route[0] = 0.354 * dx * tanB[0];
  114. sum += route[0];
  115. nroute++;
  116. }
  117. if (!is_cv_null(i - 1, j) &&
  118. cv(i, j) - cv(i - 1, j) > ZERO) {
  119. tanB[1] = (cv(i, j) - cv(i - 1, j)) * dx1;
  120. route[1] = 0.5 * dx * tanB[1];
  121. sum += route[1];
  122. nroute++;
  123. }
  124. if (j + 1 < window.cols &&
  125. !is_cv_null(i - 1, j + 1) &&
  126. cv(i, j) - cv(i - 1, j + 1) > ZERO) {
  127. tanB[2] = (cv(i, j) - cv(i - 1, j + 1)) * dx2;
  128. route[2] = 0.354 * dx * tanB[2];
  129. sum += route[2];
  130. nroute++;
  131. }
  132. }
  133. if (j > 0 &&
  134. !is_cv_null(i, j - 1) && cv(i, j) - cv(i, j - 1) > ZERO) {
  135. tanB[3] = (cv(i, j) - cv(i, j - 1)) * dx1;
  136. route[3] = 0.5 * dx * tanB[3];
  137. sum += route[3];
  138. nroute++;
  139. }
  140. if (j + 1 < window.cols) {
  141. if (!is_cv_null(i, j + 1) &&
  142. cv(i, j) - cv(i, j + 1) > ZERO) {
  143. tanB[5] = (cv(i, j) - cv(i, j + 1)) * dx1;
  144. route[5] = 0.5 * dx * tanB[5];
  145. sum += route[5];
  146. nroute++;
  147. }
  148. }
  149. if (i + 1 < window.rows) {
  150. if (j > 0 &&
  151. !is_cv_null(i + 1, j - 1) &&
  152. cv(i, j) - cv(i + 1, j - 1) > ZERO) {
  153. tanB[6] = (cv(i, j) - cv(i + 1, j - 1)) * dx2;
  154. route[6] = 0.354 * dx * tanB[6];
  155. sum += route[6];
  156. nroute++;
  157. }
  158. if (!is_cv_null(i + 1, j) &&
  159. cv(i, j) - cv(i + 1, j) > ZERO) {
  160. tanB[7] = (cv(i, j) - cv(i + 1, j)) * dx1;
  161. route[7] = 0.5 * dx * tanB[7];
  162. sum += route[7];
  163. nroute++;
  164. }
  165. if (j + 1 < window.cols &&
  166. !is_cv_null(i + 1, j + 1) &&
  167. cv(i, j) - cv(i + 1, j + 1) > ZERO) {
  168. tanB[8] = (cv(i, j) - cv(i + 1, j + 1)) * dx2;
  169. route[8] = 0.354 * dx * tanB[8];
  170. sum += route[8];
  171. nroute++;
  172. }
  173. }
  174. if (!nroute) {
  175. G_debug(1, "Sink or boundary node at %d, %d\n", i, j);
  176. nsink++;
  177. sumtb = 0.0;
  178. nslp = 0;
  179. if (i > 0) {
  180. if (j > 0 && !is_cv_null(i - 1, j - 1)) {
  181. sumtb += (cv(i - 1, j - 1) - cv(i, j)) * dx2;
  182. nslp++;
  183. }
  184. if (!is_cv_null(i - 1, j)) {
  185. sumtb += (cv(i - 1, j) - cv(i, j)) * dx1;
  186. nslp++;
  187. }
  188. if (j + 1 < window.cols && !is_cv_null(i - 1, j + 1)) {
  189. sumtb += (cv(i - 1, j + 1) - cv(i, j)) * dx2;
  190. nslp++;
  191. }
  192. }
  193. if (j > 0 && !is_cv_null(i, j - 1)) {
  194. sumtb += (cv(i, j - 1) - cv(i, j)) * dx1;
  195. nslp++;
  196. }
  197. if (j + 1 < window.cols && !is_cv_null(i, j + 1)) {
  198. sumtb += (cv(i, j + 1) - cv(i, j)) * dx1;
  199. nslp++;
  200. }
  201. if (i + 1 < window.rows) {
  202. if (j > 0 && !is_cv_null(i + 1, j - 1)) {
  203. sumtb += (cv(i + 1, j - 1) - cv(i, j)) * dx2;
  204. nslp++;
  205. }
  206. if (!is_cv_null(i + 1, j)) {
  207. sumtb += (cv(i + 1, j) - cv(i, j)) * dx1;
  208. nslp++;
  209. }
  210. if (j + 1 < window.cols && !is_cv_null(i + 1, j + 1)) {
  211. sumtb += (cv(i + 1, j + 1) - cv(i, j)) * dx2;
  212. nslp++;
  213. }
  214. }
  215. sumtb /= nslp;
  216. if (sumtb > ZERO) {
  217. atbv(i, j) = log((av(i, j) / (2 * dx * sumtb)));
  218. }
  219. else {
  220. Rast_set_d_null_value(&atbv(i, j), 1);
  221. }
  222. natb++;
  223. continue;
  224. }
  225. C = av(i, j) / sum;
  226. atbv(i, j) = log(C);
  227. natb++;
  228. if (i > 0) {
  229. if (j > 0) {
  230. av(i - 1, j - 1) += C * route[0];
  231. }
  232. av(i - 1, j) += C * route[1];
  233. if (j + 1 < window.cols) {
  234. av(i - 1, j + 1) += C * route[2];
  235. }
  236. }
  237. if (j > 0) {
  238. av(i, j - 1) += C * route[3];
  239. }
  240. if (j + 1 < window.cols) {
  241. av(i, j + 1) += C * route[5];
  242. }
  243. if (i + 1 < window.rows) {
  244. if (j > 0) {
  245. av(i + 1, j - 1) += C * route[6];
  246. }
  247. av(i + 1, j) += C * route[7];
  248. if (j + 1 < window.cols) {
  249. av(i + 1, j + 1) += C * route[8];
  250. }
  251. }
  252. }
  253. }
  254. }
  255. G_percent(natb - snatb, ncells - snatb, 1);
  256. G_important_message(_("Number of sinks or boundaries: %d"), nsink);
  257. }