get_stats.c 4.5 KB

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