count.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include <limits.h>
  2. #include <float.h>
  3. #include <math.h>
  4. #include <unistd.h>
  5. #include <grass/gis.h>
  6. #include <grass/raster.h>
  7. #include <grass/glocale.h>
  8. #include "local_proto.h"
  9. static void set_min(struct RASTER_MAP_PTR *, int, struct RASTER_MAP_PTR *);
  10. static void set_max(struct RASTER_MAP_PTR *, int, struct RASTER_MAP_PTR *);
  11. /* get_stats() Find out the number of cells total, number of nulls
  12. * the min value, the max value and the create the null replacement
  13. * value.
  14. */
  15. void get_stats(struct rr_state *theState)
  16. {
  17. int nrows, ncols, row, col;
  18. theState->fd_old = Rast_open_old(theState->inraster, "");
  19. if (theState->docover == 1)
  20. theState->fd_cold = Rast_open_old(theState->inrcover, "");
  21. theState->buf.type = Rast_get_map_type(theState->fd_old);
  22. theState->buf.data.v = Rast_allocate_buf(theState->buf.type);
  23. if (theState->docover == 1) {
  24. theState->cover.type = Rast_get_map_type(theState->fd_cold);
  25. theState->cover.data.v = Rast_allocate_buf(theState->cover.type);
  26. }
  27. theState->nulls.type = theState->buf.type;
  28. theState->min.type = theState->buf.type;
  29. theState->max.type = theState->buf.type;
  30. theState->nulls.data.v =
  31. (void *)G_malloc(Rast_cell_size(theState->nulls.type));
  32. theState->min.data.v =
  33. (void *)G_malloc(Rast_cell_size(theState->min.type));
  34. theState->max.data.v =
  35. (void *)G_malloc(Rast_cell_size(theState->max.type));
  36. if (theState->docover == 1) {
  37. theState->cnulls.type = theState->cover.type;
  38. theState->cmin.type = theState->cover.type;
  39. theState->cmax.type = theState->cover.type;
  40. theState->cnulls.data.v =
  41. (void *)G_malloc(Rast_cell_size(theState->cnulls.type));
  42. theState->cmin.data.v =
  43. (void *)G_malloc(Rast_cell_size(theState->cmin.type));
  44. theState->cmax.data.v =
  45. (void *)G_malloc(Rast_cell_size(theState->cmax.type));
  46. }
  47. nrows = Rast_window_rows();
  48. ncols = Rast_window_cols();
  49. theState->nCells = (long) nrows * ncols;
  50. theState->nNulls = 0;
  51. set_min(NULL, 0, &theState->min);
  52. set_max(NULL, 0, &theState->max);
  53. if (theState->docover == 1) {
  54. theState->cnCells = nrows * ncols;
  55. theState->cnNulls = 0;
  56. set_min(NULL, 0, &theState->cmin);
  57. set_max(NULL, 0, &theState->cmax);
  58. }
  59. G_message(_("Collecting Stats..."));
  60. for (row = 0; row < nrows; row++) {
  61. Rast_get_row(theState->fd_old, theState->buf.data.v,
  62. row, theState->buf.type);
  63. if (theState->docover == 1)
  64. Rast_get_row(theState->fd_cold, theState->cover.data.v,
  65. row, theState->cover.type);
  66. for (col = 0; col < ncols; col++) {
  67. if (is_null_value(theState->buf, col)) {
  68. theState->nNulls++;
  69. }
  70. else {
  71. set_min(&theState->buf, col, &theState->min);
  72. set_max(&theState->buf, col, &theState->max);
  73. }
  74. if (theState->docover == 1) {
  75. if (is_null_value(theState->cover, col)) {
  76. theState->cnNulls++;
  77. }
  78. else {
  79. set_min(&theState->cover, col, &theState->cmin);
  80. set_max(&theState->cover, col, &theState->cmax);
  81. }
  82. }
  83. }
  84. G_percent(row, nrows, 2);
  85. }
  86. G_percent(1, 1, 1);
  87. /* rewind the in raster map descriptor for later use */
  88. lseek(theState->fd_old, 0, SEEK_SET);
  89. if (theState->docover == 1)
  90. lseek(theState->fd_cold, 0, SEEK_SET);
  91. /* Set the NULL value replacement */
  92. switch (theState->nulls.type) {
  93. case CELL_TYPE:
  94. *theState->nulls.data.c = *theState->min.data.c - 1;
  95. if (theState->docover == 1)
  96. *theState->cnulls.data.c = *theState->cmin.data.c - 1;
  97. break;
  98. case FCELL_TYPE:
  99. *theState->nulls.data.f = floor(*theState->min.data.f - 1);
  100. if (theState->docover == 1)
  101. *theState->cnulls.data.f = floor(*theState->cmin.data.f - 1);
  102. break;
  103. case DCELL_TYPE:
  104. *theState->nulls.data.d = floor(*theState->min.data.d - 1);
  105. if (theState->docover == 1)
  106. *theState->cnulls.data.d = floor(*theState->cmin.data.d - 1);
  107. break;
  108. default: /* Huh? */
  109. G_fatal_error(_("Programmer error in get_stats/switch"));
  110. }
  111. } /* get_stats() */
  112. static void set_min(struct RASTER_MAP_PTR *from, int col,
  113. struct RASTER_MAP_PTR *to)
  114. {
  115. if (from == NULL) {
  116. switch (to->type) {
  117. case CELL_TYPE:
  118. *to->data.c = INT_MAX;
  119. break;
  120. case FCELL_TYPE:
  121. *to->data.f = FLT_MAX;
  122. break;
  123. case DCELL_TYPE:
  124. *to->data.d = DBL_MAX;
  125. break;
  126. }
  127. }
  128. else {
  129. switch (to->type) {
  130. case CELL_TYPE:
  131. *to->data.c = (*to->data.c < from->data.c[col]) ?
  132. *to->data.c : from->data.c[col];
  133. break;
  134. case FCELL_TYPE:
  135. *to->data.f = (*to->data.f < from->data.f[col]) ?
  136. *to->data.f : from->data.f[col];
  137. break;
  138. case DCELL_TYPE:
  139. *to->data.d = (*to->data.d < from->data.d[col]) ?
  140. *to->data.d : from->data.d[col];
  141. break;
  142. }
  143. }
  144. }
  145. static void set_max(struct RASTER_MAP_PTR *from, int col,
  146. struct RASTER_MAP_PTR *to)
  147. {
  148. if (from == NULL) {
  149. switch (to->type) {
  150. case CELL_TYPE:
  151. *to->data.c = INT_MIN;
  152. break;
  153. case FCELL_TYPE:
  154. *to->data.f = FLT_MIN;
  155. break;
  156. case DCELL_TYPE:
  157. *to->data.d = DBL_MIN;
  158. break;
  159. }
  160. }
  161. else {
  162. switch (to->type) {
  163. case CELL_TYPE:
  164. *to->data.c = (*to->data.c > from->data.c[col]) ?
  165. *to->data.c : from->data.c[col];
  166. break;
  167. case FCELL_TYPE:
  168. *to->data.f = (*to->data.f > from->data.f[col]) ?
  169. *to->data.f : from->data.f[col];
  170. break;
  171. case DCELL_TYPE:
  172. *to->data.d = (*to->data.d > from->data.d[col]) ?
  173. *to->data.d : from->data.d[col];
  174. break;
  175. }
  176. }
  177. }