main.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * r3.stats
  3. *
  4. * Copyright (C) 2004-2007 by the GRASS Development Team
  5. * Author(s): Soeren Gebbert
  6. *
  7. * Purpose: Generates volume statistics for raster3d maps.
  8. *
  9. * This program is free software under the GNU General Public
  10. * License (>=v2). Read the file COPYING that comes with GRASS
  11. * for details.
  12. *
  13. */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <math.h>
  17. #include <grass/gis.h>
  18. #include <grass/raster3d.h>
  19. #include <grass/glocale.h>
  20. #include "local_proto.h"
  21. int main(int argc, char *argv[])
  22. {
  23. float val_f; /* for misc use */
  24. double val_d; /* for misc use */
  25. stat_table *stats = NULL;
  26. double min, max;
  27. equal_val_array *eqvals = NULL;
  28. unsigned int n = 0, nsteps;
  29. int map_type;
  30. char *infile = NULL;
  31. void *map = NULL;
  32. RASTER3D_Region region;
  33. unsigned int rows, cols, depths;
  34. unsigned int x, y, z;
  35. struct Option *inputfile, *steps;
  36. struct Flag *equal, *counts_only;
  37. struct GModule *module;
  38. G_gisinit(argv[0]);
  39. module = G_define_module();
  40. G_add_keyword(_("raster3d"));
  41. G_add_keyword(_("statistics"));
  42. module->description = _("Generates volume statistics for 3D raster maps.");
  43. /* Define the different options */
  44. inputfile = G_define_standard_option(G_OPT_R3_INPUT);
  45. steps = G_define_option();
  46. steps->key = "nsteps";
  47. steps->type = TYPE_INTEGER;
  48. steps->required = NO;
  49. steps->answer = "20";
  50. steps->description = _("Number of subranges to collect stats from");
  51. equal = G_define_flag();
  52. equal->key = 'e';
  53. equal->description =
  54. _("Calculate statistics based on equal value groups");
  55. counts_only = G_define_flag();
  56. counts_only->key = 'c';
  57. counts_only->description = _("Only print cell counts");
  58. if (G_parser(argc, argv))
  59. exit(EXIT_FAILURE);
  60. /*Set the defaults */
  61. Rast3d_init_defaults();
  62. /*get the current region */
  63. Rast3d_get_window(&region);
  64. cols = region.cols;
  65. rows = region.rows;
  66. depths = region.depths;
  67. sscanf(steps->answer, "%i", &nsteps);
  68. /* break if the wrong number of subranges are given */
  69. if (nsteps <= 0)
  70. G_fatal_error(_("The number of subranges has to be equal or greater than 1"));
  71. infile = inputfile->answer;
  72. if (NULL == G_find_raster3d(infile, ""))
  73. Rast3d_fatal_error(_("3D raster map <%s> not found"), infile);
  74. map =
  75. Rast3d_open_cell_old(infile, G_find_raster3d(infile, ""), &region,
  76. RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
  77. if (map == NULL)
  78. Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), infile);
  79. map_type = Rast3d_tile_type_map(map);
  80. /* calculate statistics for groups of equal values */
  81. if ((equal->answer)) {
  82. /*search for equal values */
  83. eqvals = NULL;
  84. n = 0;
  85. for (z = 0; z < depths; z++) {
  86. G_percent(z, depths - 1, 2);
  87. for (y = 0; y < rows; y++) {
  88. for (x = 0; x < cols; x++) {
  89. if (map_type == FCELL_TYPE) {
  90. Rast3d_get_value(map, x, y, z, &val_f, map_type);
  91. if (!Rast3d_is_null_value_num(&val_f, map_type)) {
  92. /*the first entry */
  93. if (eqvals == NULL)
  94. eqvals =
  95. add_equal_val_to_array(eqvals,
  96. (double)val_f);
  97. else
  98. check_equal_value(eqvals, (double)val_f);
  99. n++; /*count non null cells */
  100. }
  101. }
  102. else if (map_type == DCELL_TYPE) {
  103. Rast3d_get_value(map, x, y, z, &val_d, map_type);
  104. if (!Rast3d_is_null_value_num(&val_d, map_type)) {
  105. /*the first entry */
  106. if (eqvals == NULL)
  107. eqvals =
  108. add_equal_val_to_array(eqvals, val_d);
  109. else
  110. check_equal_value(eqvals, val_d);
  111. n++; /*count non null cells */
  112. }
  113. }
  114. }
  115. }
  116. }
  117. if (eqvals) {
  118. /* sort the equal values array */
  119. G_message(_("Sort non-null values"));
  120. heapsort_eqvals(eqvals, eqvals->count);
  121. /* create the statistic table with equal values */
  122. stats = create_stat_table(eqvals->count, eqvals, 0, 0);
  123. /* compute the number of null values */
  124. stats->null->count = rows * cols * depths - n;
  125. free_equal_val_array(eqvals);
  126. }
  127. }
  128. else {
  129. /* create the statistic table based on value ranges */
  130. /* get the range of the map */
  131. Rast3d_range_load(map);
  132. Rast3d_range_min_max(map, &min, &max);
  133. stats = create_stat_table(nsteps, NULL, min, max);
  134. n = 0;
  135. for (z = 0; z < depths; z++) {
  136. G_percent(z, depths - 1, 2);
  137. for (y = 0; y < rows; y++) {
  138. for (x = 0; x < cols; x++) {
  139. if (map_type == FCELL_TYPE) {
  140. Rast3d_get_value(map, x, y, z, &val_f, map_type);
  141. if (!Rast3d_is_null_value_num(&val_f, map_type)) {
  142. check_range_value(stats, (double)val_f);
  143. n++;
  144. }
  145. }
  146. else if (map_type == DCELL_TYPE) {
  147. Rast3d_get_value(map, x, y, z, &val_d, map_type);
  148. if (!Rast3d_is_null_value_num(&val_d, map_type)) {
  149. check_range_value(stats, val_d);
  150. n++;
  151. }
  152. }
  153. }
  154. }
  155. }
  156. /* compute the number of null values */
  157. stats->null->count = rows * cols * depths - n;
  158. }
  159. if(stats) {
  160. /* Compute the volume and percentage */
  161. update_stat_table(stats, &region);
  162. /* Print the statistics to stdout */
  163. print_stat_table(stats, counts_only->answer);
  164. free_stat_table(stats);
  165. }
  166. exit(EXIT_SUCCESS);
  167. }