get_stats.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <grass/gis.h>
  6. #include <grass/raster.h>
  7. #include <grass/spawn.h>
  8. #include "options.h"
  9. #include "dhist.h"
  10. static void run_stats(const char *mapname, int quiet, const char *tempfile)
  11. {
  12. char buf[32];
  13. const char *argv[12];
  14. int argc = 0;
  15. argv[argc++] = "r.stats";
  16. argv[argc++] = "-r";
  17. if (cat_ranges)
  18. argv[argc++] = "-C";
  19. if (quiet)
  20. argv[argc++] = "-q";
  21. argv[argc++] = type == COUNT
  22. ? "-c"
  23. : "-a";
  24. argv[argc++] = mapname;
  25. if (!cat_ranges) {
  26. sprintf(buf, "nsteps=%d", nsteps);
  27. argv[argc++] = buf;
  28. }
  29. argv[argc++] = SF_REDIRECT_FILE;
  30. argv[argc++] = SF_STDOUT;
  31. argv[argc++] = SF_MODE_OUT;
  32. argv[argc++] = tempfile;
  33. argv[argc++] = NULL;
  34. if (G_vspawn_ex(argv[0], argv) != 0)
  35. G_fatal_error("error running r.stats");
  36. }
  37. int get_stats(const char *mapname, struct stat_list *dist_stats, /* linked list of stats */
  38. int quiet)
  39. {
  40. char buf[1024]; /* input buffer for reading stats */
  41. int done = 0;
  42. char *tempfile; /* temp file name */
  43. FILE *fd; /* temp file pointer */
  44. long int cat; /* a category value */
  45. long int stat; /* a category stat value */
  46. struct stat_node *ptr = NULL;
  47. int first;
  48. /* write stats to a temp file */
  49. tempfile = G_tempfile();
  50. is_fp = Rast_map_is_fp(mapname, "");
  51. if (is_fp) {
  52. if (cat_ranges) {
  53. if (Rast_read_cats(mapname, "", &cats) < 0)
  54. G_fatal_error("Can't read category file");
  55. if (Rast_number_of_cats(&cats) <= 0) {
  56. G_warning("There are no labeled cats, using nsteps argument");
  57. cat_ranges = 0;
  58. }
  59. }
  60. if (Rast_read_fp_range(map_name, "", &fp_range) <= 0)
  61. G_fatal_error("Can't read frange file");
  62. }
  63. run_stats(mapname, quiet, tempfile);
  64. /* open temp file and read the stats into a linked list */
  65. fd = fopen(tempfile, "r");
  66. if (fd == NULL) {
  67. perror("opening r.stats output file");
  68. G_fatal_error("unable to continue.");
  69. }
  70. dist_stats->ptr = NULL;
  71. dist_stats->count = 0;
  72. dist_stats->sumstat = 0;
  73. first = 1;
  74. while (!done) {
  75. if (fgets(buf, sizeof(buf), fd) != NULL) {
  76. /* WARNING!!!!!!
  77. * this will be very wrong if type!=COUNT
  78. * since the stat prodcued by r.stats will be a floating point value
  79. * possibly less than 1 (shapiro)
  80. */
  81. if (sscanf(buf, "* %ld", &stat) == 1) {
  82. dist_stats->null_stat = stat;
  83. if (stat > dist_stats->maxstat && nodata)
  84. dist_stats->maxstat = stat;
  85. if (stat < dist_stats->minstat && nodata)
  86. dist_stats->minstat = stat;
  87. if (nodata)
  88. dist_stats->sumstat += stat;
  89. }
  90. else if (sscanf(buf, "%ld %ld", &cat, &stat) == 2) {
  91. /* count stats */
  92. dist_stats->count++;
  93. /* sum stats */
  94. dist_stats->sumstat += stat;
  95. /* a max or a min stat? */
  96. if (first) {
  97. dist_stats->maxstat = stat;
  98. dist_stats->minstat = stat;
  99. dist_stats->maxcat = cat;
  100. dist_stats->mincat = cat;
  101. first = 0;
  102. }
  103. if (stat > dist_stats->maxstat)
  104. dist_stats->maxstat = stat;
  105. if (stat < dist_stats->minstat)
  106. dist_stats->minstat = stat;
  107. /* a max or a min cat? */
  108. if (cat > dist_stats->maxcat)
  109. dist_stats->maxcat = cat;
  110. if (cat < dist_stats->mincat)
  111. dist_stats->mincat = cat;
  112. /* put it in the list */
  113. if (dist_stats->ptr == NULL) {
  114. /* first in list */
  115. dist_stats->ptr = (struct stat_node *)
  116. G_malloc(sizeof(struct stat_node));
  117. dist_stats->ptr->cat = cat;
  118. dist_stats->ptr->stat = stat;
  119. dist_stats->ptr->next = NULL;
  120. ptr = dist_stats->ptr;
  121. }
  122. else {
  123. ptr->next = (struct stat_node *)
  124. G_malloc(sizeof(struct stat_node));
  125. ptr->next->cat = cat;
  126. ptr->next->stat = stat;
  127. ptr->next->next = NULL; /* mod: shapiro */
  128. ptr = ptr->next;
  129. }
  130. }
  131. }
  132. else
  133. done = 1;
  134. }
  135. fclose(fd);
  136. unlink(tempfile);
  137. return 0;
  138. }