123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /* main.c - r.surf.area */
- /* Copyright Notice
- * ----------------
- * Written by Bill Brown, USACERL December 21, 1994
- * Copyright 1994, Bill Brown, USACERL
- * brown@gis.uiuc.edu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- /* Calculates area of regular 3D triangulated points
- * (centers of cells) in current region by
- * adding areas of triangles. Therefore, area of a flat surface
- * will be reported as (rows + cols -1)*(area of cell) less than area of
- * flat region due to a half row and half column missing around the
- * perimeter.
- * NOTE: This calculation is heavily dependent on data resolution
- * (think of it as a fractal shoreline problem, the more resolution
- * the more detail, the more area, etc). This program uses the
- * CURRENT GRASS REGION, not the resolution of the map.
- * This version actually calculates area twice for each triangle pair,
- * keeping a running minimum and maximum area depending on the
- * direction of the diagonal used.
- * Reported totals are:
- * 1) "plan" area within calculation region (rows-1 * cols-1 * cellarea)
- * 2) avg of min & max calculated 3d triangle area within this region
- * 3) "plan" area within current GRASS region (rows * cols * cellarea)
- * 4) scaling of calculated area to current GRASS region
- */
- /* Modified by Eric G. Miller to work with FP rasters and to handle
- * NULL value cells. I'm not too sure how bad the surface area
- * calculation will get if there are alot of NULL cells mixed around.
- * Added function prototypes and removed a couple unneccessary typedefs
- * Added the add_null_area() function.
- * 2000-10-17
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/glocale.h>
- #include "local_proto.h"
- int main(int argc, char *argv[])
- {
- struct GModule *module;
- struct {
- struct Option *surf, *vscale, *units;
- } opt;
- DCELL *cell_buf[2];
- int row;
- struct Cell_head w;
- int cellfile, units;
- double minarea, maxarea, sz, nullarea;
- G_gisinit(argv[0]);
- module = G_define_module();
- G_add_keyword(_("raster"));
- G_add_keyword(_("surface"));
- G_add_keyword(_("statistics"));
- G_add_keyword(_("area estimation"));
- module->description = _("Prints estimation of surface area for raster map.");
- opt.surf = G_define_standard_option(G_OPT_R_MAP);
-
- opt.vscale = G_define_option();
- opt.vscale->key = "vscale";
- opt.vscale->type = TYPE_DOUBLE;
- opt.vscale->required = NO;
- opt.vscale->multiple = NO;
- opt.vscale->description = _("Vertical scale");
- opt.vscale->answer = "1.0";
-
- opt.units = G_define_standard_option(G_OPT_M_UNITS);
- opt.units->label = _("Output units");
- opt.units->description = _("Default: square map units");
-
- if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
- sz = atof(opt.vscale->answer);
- if (opt.units->answer) {
- units = G_units(opt.units->answer);
- G_verbose_message(_("Output in '%s'"), G_get_units_name(units, TRUE, TRUE));
- }
- else {
- units = U_UNDEFINED;
- G_verbose_message(_("Output in 'square map units'"));
- }
-
- G_get_set_window(&w);
- /* open raster map for reading */
- cellfile = Rast_open_old(opt.surf->answer, "");
- cell_buf[0] = (DCELL *) G_malloc(w.cols * Rast_cell_size(DCELL_TYPE));
- cell_buf[1] = (DCELL *) G_malloc(w.cols * Rast_cell_size(DCELL_TYPE));
- {
- DCELL *top, *bottom;
- minarea = maxarea = nullarea = 0.0;
- for (row = 0; row < w.rows - 1; row++) {
- if (!row) {
- Rast_get_row(cellfile, cell_buf[1], 0, DCELL_TYPE);
- top = cell_buf[1];
- }
- Rast_get_row(cellfile, cell_buf[row % 2], row + 1,
- DCELL_TYPE);
- bottom = cell_buf[row % 2];
- add_row_area(top, bottom, sz, &w, &minarea, &maxarea);
- add_null_area(top, &w, &nullarea);
- top = bottom;
- G_percent(row, w.rows, 10);
- }
- /* Get last null row area */
- if (w.rows > 1)
- add_null_area(top, &w, &nullarea);
- }
- G_free(cell_buf[0]);
- G_free(cell_buf[1]);
- Rast_close(cellfile);
- { /* report */
- double reg_area, flat_area, estavg;
- flat_area = (w.cols - 1) * (w.rows - 1) * w.ns_res * w.ew_res;
- reg_area = w.cols * w.rows * w.ns_res * w.ew_res;
- estavg = (minarea + maxarea) / 2.0;
- fprintf(stdout, "%s %f\n",
- _("Null value area ignored in calculation:"),
- conv_value(nullarea, units));
- fprintf(stdout, "%s %f\n", _("Plan area used in calculation:"),
- conv_value(flat_area, units));
- fprintf(stdout, "%s\n\t%f %f %f\n",
- _("Surface area calculation(low, high, avg):"),
- conv_value(minarea, units),
- conv_value(maxarea, units),
- conv_value(estavg, units));
- fprintf(stdout, "%s %f\n", _("Current region plan area:"),
- conv_value(reg_area, units));
- fprintf(stdout, "%s %f\n", _("Estimated region Surface Area:"),
- flat_area > 0 ?
- conv_value(reg_area * estavg / flat_area, units) :
- 0);
- }
- exit(EXIT_SUCCESS);
- }
|