get_stats.c 3.9 KB

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