main.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* main.c - r.surf.area */
  2. /* Copyright Notice
  3. * ----------------
  4. * Written by Bill Brown, USACERL December 21, 1994
  5. * Copyright 1994, Bill Brown, USACERL
  6. * brown@gis.uiuc.edu
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. /* Calculates area of regular 3D triangulated points
  23. * (centers of cells) in current region by
  24. * adding areas of triangles. Therefore, area of a flat surface
  25. * will be reported as (rows + cols -1)*(area of cell) less than area of
  26. * flat region due to a half row and half column missing around the
  27. * perimeter.
  28. * NOTE: This calculation is heavily dependent on data resolution
  29. * (think of it as a fractal shoreline problem, the more resolution
  30. * the more detail, the more area, etc). This program uses the
  31. * CURRENT GRASS REGION, not the resolution of the map.
  32. * This version actually calculates area twice for each triangle pair,
  33. * keeping a running minimum and maximum area depending on the
  34. * direction of the diagonal used.
  35. * Reported totals are:
  36. * 1) "plan" area within calculation region (rows-1 * cols-1 * cellarea)
  37. * 2) avg of min & max calculated 3d triangle area within this region
  38. * 3) "plan" area within current GRASS region (rows * cols * cellarea)
  39. * 4) scaling of calculated area to current GRASS region
  40. */
  41. /* Modified by Eric G. Miller to work with FP rasters and to handle
  42. * NULL value cells. I'm not too sure how bad the surface area
  43. * calculation will get if there are alot of NULL cells mixed around.
  44. * Added function prototypes and removed a couple unneccessary typedefs
  45. * Added the add_null_area() function.
  46. * 2000-10-17
  47. */
  48. #include <stdlib.h>
  49. #include <stdio.h>
  50. #include <grass/gis.h>
  51. #include <grass/raster.h>
  52. #include <grass/glocale.h>
  53. #include "local_proto.h"
  54. int main(int argc, char *argv[])
  55. {
  56. struct GModule *module;
  57. struct {
  58. struct Option *surf, *vscale, *units;
  59. } opt;
  60. DCELL *cell_buf[2];
  61. int row;
  62. struct Cell_head w;
  63. int cellfile, units;
  64. double minarea, maxarea, sz, nullarea;
  65. G_gisinit(argv[0]);
  66. module = G_define_module();
  67. G_add_keyword(_("raster"));
  68. G_add_keyword(_("surface"));
  69. G_add_keyword(_("statistics"));
  70. G_add_keyword(_("area estimation"));
  71. module->description = _("Prints estimation of surface area for raster map.");
  72. opt.surf = G_define_standard_option(G_OPT_R_MAP);
  73. opt.vscale = G_define_option();
  74. opt.vscale->key = "vscale";
  75. opt.vscale->type = TYPE_DOUBLE;
  76. opt.vscale->required = NO;
  77. opt.vscale->multiple = NO;
  78. opt.vscale->description = _("Vertical scale");
  79. opt.vscale->answer = "1.0";
  80. opt.units = G_define_standard_option(G_OPT_M_UNITS);
  81. opt.units->label = _("Output units");
  82. opt.units->description = _("Default: square map units");
  83. if (G_parser(argc, argv))
  84. exit(EXIT_FAILURE);
  85. sz = atof(opt.vscale->answer);
  86. if (opt.units->answer) {
  87. units = G_units(opt.units->answer);
  88. G_verbose_message(_("Output in '%s'"), G_get_units_name(units, TRUE, TRUE));
  89. }
  90. else {
  91. units = U_UNDEFINED;
  92. G_verbose_message(_("Output in 'square map units'"));
  93. }
  94. G_get_set_window(&w);
  95. /* open raster map for reading */
  96. cellfile = Rast_open_old(opt.surf->answer, "");
  97. cell_buf[0] = (DCELL *) G_malloc(w.cols * Rast_cell_size(DCELL_TYPE));
  98. cell_buf[1] = (DCELL *) G_malloc(w.cols * Rast_cell_size(DCELL_TYPE));
  99. {
  100. DCELL *top, *bottom;
  101. minarea = maxarea = nullarea = 0.0;
  102. for (row = 0; row < w.rows - 1; row++) {
  103. if (!row) {
  104. Rast_get_row(cellfile, cell_buf[1], 0, DCELL_TYPE);
  105. top = cell_buf[1];
  106. }
  107. Rast_get_row(cellfile, cell_buf[row % 2], row + 1,
  108. DCELL_TYPE);
  109. bottom = cell_buf[row % 2];
  110. add_row_area(top, bottom, sz, &w, &minarea, &maxarea);
  111. add_null_area(top, &w, &nullarea);
  112. top = bottom;
  113. G_percent(row, w.rows, 10);
  114. }
  115. /* Get last null row area */
  116. if (w.rows > 1)
  117. add_null_area(top, &w, &nullarea);
  118. }
  119. G_free(cell_buf[0]);
  120. G_free(cell_buf[1]);
  121. Rast_close(cellfile);
  122. { /* report */
  123. double reg_area, flat_area, estavg;
  124. flat_area = (w.cols - 1) * (w.rows - 1) * w.ns_res * w.ew_res;
  125. reg_area = w.cols * w.rows * w.ns_res * w.ew_res;
  126. estavg = (minarea + maxarea) / 2.0;
  127. fprintf(stdout, "%s %f\n",
  128. _("Null value area ignored in calculation:"),
  129. conv_value(nullarea, units));
  130. fprintf(stdout, "%s %f\n", _("Plan area used in calculation:"),
  131. conv_value(flat_area, units));
  132. fprintf(stdout, "%s\n\t%f %f %f\n",
  133. _("Surface area calculation(low, high, avg):"),
  134. conv_value(minarea, units),
  135. conv_value(maxarea, units),
  136. conv_value(estavg, units));
  137. fprintf(stdout, "%s %f\n", _("Current region plan area:"),
  138. conv_value(reg_area, units));
  139. fprintf(stdout, "%s %f\n", _("Estimated region Surface Area:"),
  140. flat_area > 0 ?
  141. conv_value(reg_area * estavg / flat_area, units) :
  142. 0);
  143. }
  144. exit(EXIT_SUCCESS);
  145. }