process.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*****************************************************************************/
  2. /*** ***/
  3. /*** process() ***/
  4. /*** Reads in a raster map row by row for processing. ***/
  5. /*** Jo Wood, Project ASSIST, V1.0 7th February 1993 ***/
  6. /*** ***/
  7. /*****************************************************************************/
  8. #include <stdlib.h>
  9. #include <grass/gis.h>
  10. #include <grass/raster.h>
  11. #include <grass/glocale.h>
  12. #include <grass/gmath.h>
  13. #include "param.h"
  14. #include "nrutil.h"
  15. void process(void)
  16. {
  17. /*--------------------------------------------------------------------------*/
  18. /* INITIALISE */
  19. /*--------------------------------------------------------------------------*/
  20. DCELL *row_in, /* Buffer large enough to hold `wsize' */
  21. *row_out = NULL, /* raster rows. When GRASS reads in a */
  22. /* raster row, each element is of type */
  23. /* DCELL */
  24. *window_ptr, /* Stores local terrain window. */
  25. centre; /* Elevation of central cell in window. */
  26. CELL *featrow_out = NULL; /* store features in CELL */
  27. struct Cell_head region; /* Structure to hold region information */
  28. int nrows, /* Will store the current number of */
  29. ncols, /* rows and columns in the raster. */
  30. row, col, /* Counts through each row and column */
  31. /* of the input raster. */
  32. wind_row, /* Counts through each row and column */
  33. wind_col, /* of the local neighbourhood window. */
  34. *index_ptr; /* Row permutation vector for LU decomp. */
  35. double **normal_ptr, /* Cross-products matrix. */
  36. *obs_ptr, /* Observed vector. */
  37. temp; /* Unused */
  38. double *weight_ptr; /* Weighting matrix for observed values. */
  39. /*--------------------------------------------------------------------------*/
  40. /* GET RASTER AND WINDOW DETAILS */
  41. /*--------------------------------------------------------------------------*/
  42. G_get_window(&region); /* Fill out the region structure (the */
  43. /* geographical limits etc.) */
  44. nrows = Rast_window_rows(); /* Find out the number of rows and */
  45. ncols = Rast_window_cols(); /* columns of the raster. */
  46. if ((region.ew_res / region.ns_res >= 1.01) || /* If EW and NS resolns are */
  47. (region.ns_res / region.ew_res >= 1.01)) { /* >1% different, warn user. */
  48. G_warning(_("E-W and N-S grid resolutions are different. Taking average."));
  49. resoln = (region.ns_res + region.ew_res) / 2;
  50. }
  51. else
  52. resoln = region.ns_res;
  53. /*--------------------------------------------------------------------------*/
  54. /* RESERVE MEMORY TO HOLD Z VALUES AND MATRICES */
  55. /*--------------------------------------------------------------------------*/
  56. row_in = (DCELL *) G_malloc(ncols * sizeof(DCELL) * wsize);
  57. /* Reserve `wsize' rows of memory. */
  58. if (mparam != FEATURE)
  59. row_out = Rast_allocate_buf(DCELL_TYPE); /* Initialise output row buffer. */
  60. else
  61. featrow_out = Rast_allocate_buf(CELL_TYPE); /* Initialise output row buffer. */
  62. window_ptr = (DCELL *) G_malloc(SQR(wsize) * sizeof(DCELL));
  63. /* Reserve enough memory for local wind. */
  64. weight_ptr = (double *)G_malloc(SQR(wsize) * sizeof(double));
  65. /* Reserve enough memory weights matrix. */
  66. normal_ptr = dmatrix(0, 5, 0, 5); /* Allocate memory for 6*6 matrix */
  67. index_ptr = ivector(0, 5); /* and for 1D vector holding indices */
  68. obs_ptr = dvector(0, 5); /* and for 1D vector holding observed z */
  69. /* ---------------------------------------------------------------- */
  70. /* - CALCULATE LEAST SQUARES COEFFICIENTS - */
  71. /* ---------------------------------------------------------------- */
  72. /*--- Calculate weighting matrix. ---*/
  73. find_weight(weight_ptr);
  74. /* Initial coefficients need only be found once since they are
  75. constant for any given window size. The only element that
  76. changes is the observed vector (RHS of normal equations). */
  77. /*--- Find normal equations in matrix form. ---*/
  78. find_normal(normal_ptr, weight_ptr);
  79. /*--- Apply LU decomposition to normal equations. ---*/
  80. if (constrained) {
  81. G_ludcmp(normal_ptr, 5, index_ptr, &temp);
  82. /* To constrain the quadtratic
  83. through the central cell, ignore
  84. the calculations involving the
  85. coefficient f. Since these are
  86. all in the last row and column of
  87. the matrix, simply redimension. */
  88. /* disp_matrix(normal_ptr,obs_ptr,obs_ptr,5);
  89. */
  90. }
  91. else {
  92. G_ludcmp(normal_ptr, 6, index_ptr, &temp);
  93. /* disp_matrix(normal_ptr,obs_ptr,obs_ptr,6);
  94. */
  95. }
  96. /*--------------------------------------------------------------------------*/
  97. /* PROCESS INPUT RASTER AND WRITE OUT RASTER LINE BY LINE */
  98. /*--------------------------------------------------------------------------*/
  99. if (mparam != FEATURE)
  100. for (wind_row = 0; wind_row < EDGE; wind_row++)
  101. Rast_put_row(fd_out, row_out, DCELL_TYPE); /* Write out the edge cells as NULL. */
  102. else
  103. for (wind_row = 0; wind_row < EDGE; wind_row++)
  104. Rast_put_row(fd_out, featrow_out, CELL_TYPE); /* Write out the edge cells as NULL. */
  105. for (wind_row = 0; wind_row < wsize - 1; wind_row++)
  106. Rast_get_row(fd_in, row_in + (wind_row * ncols), wind_row,
  107. DCELL_TYPE);
  108. /* Read in enough of the first rows to */
  109. /* allow window to be examined. */
  110. for (row = EDGE; row < (nrows - EDGE); row++) {
  111. G_percent(row + 1, nrows - EDGE, 2);
  112. Rast_get_row(fd_in, row_in + ((wsize - 1) * ncols), row + EDGE,
  113. DCELL_TYPE);
  114. for (col = EDGE; col < (ncols - EDGE); col++) {
  115. /* Find central z value */
  116. centre = *(row_in + EDGE * ncols + col);
  117. for (wind_row = 0; wind_row < wsize; wind_row++)
  118. for (wind_col = 0; wind_col < wsize; wind_col++)
  119. /* Express all window values relative */
  120. /* to the central elevation. */
  121. *(window_ptr + (wind_row * wsize) + wind_col) =
  122. *(row_in + (wind_row * ncols) + col + wind_col -
  123. EDGE) - centre;
  124. /*--- Use LU back substitution to solve normal equations. ---*/
  125. find_obs(window_ptr, obs_ptr, weight_ptr);
  126. /* disp_wind(window_ptr);
  127. disp_matrix(normal_ptr,obs_ptr,obs_ptr,6);
  128. */
  129. if (constrained) {
  130. G_lubksb(normal_ptr, 5, index_ptr, obs_ptr);
  131. /*
  132. disp_matrix(normal_ptr,obs_ptr,obs_ptr,5);
  133. */
  134. }
  135. else {
  136. G_lubksb(normal_ptr, 6, index_ptr, obs_ptr);
  137. /*
  138. disp_matrix(normal_ptr,obs_ptr,obs_ptr,6);
  139. */
  140. }
  141. /*--- Calculate terrain parameter based on quad. coefficients. ---*/
  142. if (mparam == FEATURE)
  143. *(featrow_out + col) = (CELL) feature(obs_ptr);
  144. else
  145. *(row_out + col) = param(mparam, obs_ptr);
  146. if (mparam == ELEV)
  147. *(row_out + col) += centre; /* Add central elevation back */
  148. }
  149. if (mparam != FEATURE)
  150. Rast_put_row(fd_out, row_out, DCELL_TYPE); /* Write the row buffer to the output */
  151. /* raster. */
  152. else /* write FEATURE to CELL */
  153. Rast_put_row(fd_out, featrow_out, CELL_TYPE); /* Write the row buffer to the output */
  154. /* raster. */
  155. /* 'Shuffle' rows down one, and read in */
  156. /* one new row. */
  157. for (wind_row = 0; wind_row < wsize - 1; wind_row++)
  158. for (col = 0; col < ncols; col++)
  159. *(row_in + (wind_row * ncols) + col) =
  160. *(row_in + ((wind_row + 1) * ncols) + col);
  161. }
  162. for (wind_row = 0; wind_row < EDGE; wind_row++) {
  163. if (mparam != FEATURE)
  164. Rast_put_row(fd_out, row_out, DCELL_TYPE); /* Write out the edge cells as NULL. */
  165. else
  166. Rast_put_row(fd_out, featrow_out, CELL_TYPE); /* Write out the edge cells as NULL. */
  167. }
  168. /*--------------------------------------------------------------------------*/
  169. /* FREE MEMORY USED TO STORE RASTER ROWS, LOCAL WINDOW AND MATRICES */
  170. /*--------------------------------------------------------------------------*/
  171. G_free(row_in);
  172. if (mparam != FEATURE)
  173. G_free(row_out);
  174. else
  175. G_free(featrow_out);
  176. G_free(window_ptr);
  177. free_dmatrix(normal_ptr, 0, 5, 0, 5);
  178. free_dvector(obs_ptr, 0, 5);
  179. free_ivector(index_ptr, 0, 5);
  180. }