|
@@ -1,863 +0,0 @@
|
|
|
-
|
|
|
-/****************************************************************************
|
|
|
- *
|
|
|
- * MODULE: r.viewshed
|
|
|
- *
|
|
|
- * AUTHOR(S): Laura Toma, Bowdoin College - ltoma@bowdoin.edu
|
|
|
- * Yi Zhuang - yzhuang@bowdoin.edu
|
|
|
-
|
|
|
- * Ported to GRASS by William Richard -
|
|
|
- * wkrichar@bowdoin.edu or willster3021@gmail.com
|
|
|
- *
|
|
|
- * Date: july 2008
|
|
|
- *
|
|
|
- * PURPOSE: To calculate the viewshed (the visible cells in the
|
|
|
- * raster) for the given viewpoint (observer) location. The
|
|
|
- * visibility model is the following: Two points in the raster are
|
|
|
- * considered visible to each other if the cells where they belong are
|
|
|
- * visible to each other. Two cells are visible to each other if the
|
|
|
- * line-of-sight that connects their centers does not intersect the
|
|
|
- * terrain. The height of a cell is assumed to be constant, and the
|
|
|
- * terrain is viewed as a tesselation of flat cells. This model is
|
|
|
- * suitable for high resolution rasters; it may not be accurate for
|
|
|
- * low resolution rasters, where it may be better to interpolate the
|
|
|
- * height at a point based on the neighbors, rather than assuming
|
|
|
- * cells are "flat". The viewshed algorithm is efficient both in
|
|
|
- * terms of CPU operations and I/O operations. It has worst-case
|
|
|
- * complexity O(n lg n) in the RAM model and O(sort(n)) in the
|
|
|
- * I/O-model. For the algorithm and all the other details see the
|
|
|
- * paper: "Computing Visibility on * Terrains in External Memory" by
|
|
|
- * Herman Haverkort, Laura Toma and Yi Zhuang.
|
|
|
- *
|
|
|
- * COPYRIGHT: (C) 2008 by the GRASS Development Team
|
|
|
- *
|
|
|
- * This program is free software under the GNU General Public License
|
|
|
- * (>=v2). Read the file COPYING that comes with GRASS for details.
|
|
|
- *
|
|
|
- *****************************************************************************/
|
|
|
-
|
|
|
-
|
|
|
-#include <stdlib.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include <string.h>
|
|
|
-#include <ctype.h>
|
|
|
-#include <unistd.h>
|
|
|
-
|
|
|
-#ifdef __GRASS__
|
|
|
-extern "C"
|
|
|
-{
|
|
|
-#include <grass/config.h>
|
|
|
-#include <grass/gis.h>
|
|
|
-#include <grass/glocale.h>
|
|
|
-}
|
|
|
-#include "grass.h"
|
|
|
-#include <grass/iostream/ami.h>
|
|
|
-
|
|
|
-#else
|
|
|
-#include <ami.h>
|
|
|
-#endif
|
|
|
-
|
|
|
-#include "viewshed.h"
|
|
|
-#include "visibility.h"
|
|
|
-#include "grid.h"
|
|
|
-#include "rbbst.h"
|
|
|
-#include "statusstructure.h"
|
|
|
-#include "distribute.h"
|
|
|
-#include "print_message.h"
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* if the user does not specify how much memory is available for the
|
|
|
- program, this is the default value used (in bytes) */
|
|
|
-#define DEFAULT_MEMORY 500<<20
|
|
|
-
|
|
|
-
|
|
|
-/* observer elevation above the terrain */
|
|
|
-#define DEFAULT_OBS_ELEVATION 0
|
|
|
-
|
|
|
-
|
|
|
-/* All these flags are used for debugging */
|
|
|
-
|
|
|
-/* if this flag is set, it always runs in memory */
|
|
|
-//#define FORCE_INTERNAL
|
|
|
-
|
|
|
-/* if this is set, it runs in external memory, even if the problem is
|
|
|
- small enough to fit in memory. In external memory it first tries
|
|
|
- to run the base-case, then recursion. */
|
|
|
-//#define FORCE_EXTERNAL
|
|
|
-
|
|
|
-/* if this flag is set it runs in external memory, and starts
|
|
|
- recursion without checking the base-case. */
|
|
|
-//#define FORCE_DISTRIBUTION
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-/* forward declarations */
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-void print_timings_internal(Rtimer sweepTime, Rtimer outputTime, Rtimer totalTime);
|
|
|
-void print_timings_external_memory(Rtimer totalTime, Rtimer viewshedTime,
|
|
|
- Rtimer outputTime, Rtimer sortOutputTime);
|
|
|
-void print_status(Viewpoint vp,ViewOptions viewOptions, long long memSizeBytes);void print_usage();
|
|
|
-#ifdef __GRASS__
|
|
|
-void parse_args(int argc, char *argv[], int *vpRow, int *vpCol,
|
|
|
- ViewOptions* viewOptions, long long *memSizeBytes,
|
|
|
- Cell_head * window);
|
|
|
-#else
|
|
|
-void parse_args(int argc, char *argv[], int *vpRow, int *vpCol,
|
|
|
- ViewOptions* viewOptions, long long *memSizeBytes);
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-int main(int argc, char *argv[]) {
|
|
|
-
|
|
|
-#ifdef __GRASS__
|
|
|
- /* GRASS initialization stuff */
|
|
|
- struct GModule *module;
|
|
|
-
|
|
|
- /*initialize GIS environment */
|
|
|
- G_gisinit(argv[0]);
|
|
|
-
|
|
|
- /*initialize module */
|
|
|
- module = G_define_module();
|
|
|
- module->keywords = _("raster, viewshed, line of sight");
|
|
|
- module->description = _("IO-efficient viewshed algorithm");
|
|
|
-
|
|
|
- struct Cell_head region;
|
|
|
- if (G_get_set_window(®ion) == -1) {
|
|
|
- G_fatal_error("error getting current region");
|
|
|
- exit(EXIT_FAILURE);
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* parameters set up */
|
|
|
- long long memSizeBytes = DEFAULT_MEMORY;
|
|
|
- /* the maximum size of main memory that the program ca use. The
|
|
|
- user can specify it, otherwise the default value of 500MB is
|
|
|
- used. The program uses this value to decied in which mode to
|
|
|
- run --- in internal memory, or external memory. */
|
|
|
-
|
|
|
- int vpRow, vpCol;
|
|
|
- /* the coordinates of the viewpoint in the raster; right now the
|
|
|
- algorithm assumes that the viewpoint is inside the grid, though
|
|
|
- this is not necessary; some changes will be needed to make it
|
|
|
- work with a viewpoint outside the terrain */
|
|
|
-
|
|
|
- ViewOptions viewOptions;
|
|
|
- //viewOptions.inputfname = (char*)malloc(500);
|
|
|
- //viewOptions.outputfname = (char*)malloc(500);
|
|
|
- //assert(inputfname && outputfname);
|
|
|
- viewOptions.obsElev = DEFAULT_OBS_ELEVATION;
|
|
|
- viewOptions.maxDist = INFINITY_DISTANCE;
|
|
|
- viewOptions.outputMode = OUTPUT_ANGLE;
|
|
|
- viewOptions.doCurv = 0;
|
|
|
-
|
|
|
-#ifdef __GRASS__
|
|
|
- parse_args(argc,argv, &vpRow, &vpCol,&viewOptions, &memSizeBytes,®ion);
|
|
|
-#else
|
|
|
- parse_args(argc,argv, &vpRow, &vpCol, &viewOptions, &memSizeBytes);
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
- /* set viewpoint with the coordinates specified by user. The
|
|
|
- height of the viewpoint is not known at this point---it will be
|
|
|
- set during the execution of the algorithm */
|
|
|
- Viewpoint vp;
|
|
|
- set_viewpoint_coord(&vp, vpRow, vpCol);
|
|
|
-
|
|
|
- print_status(vp, viewOptions,memSizeBytes);
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* set up the header of the raster with all raster info and make
|
|
|
- sure the requested viewpoint is on the map */
|
|
|
- GridHeader *hd;
|
|
|
-#ifdef __GRASS__
|
|
|
- hd = read_header_from_GRASS(viewOptions.inputfname, ®ion);
|
|
|
- assert(hd);
|
|
|
-
|
|
|
- /* LT: there is no need to exit if viewpoint is outside grid,
|
|
|
- the algorithm will work correctly in theory. But this
|
|
|
- requires some changes. To do.*/
|
|
|
- if (!(vp.row < hd->nrows && vp.col < hd->ncols)) {
|
|
|
- G_fatal_error(_("Viewpoint outside grid"));
|
|
|
- G_fatal_error(_("viewpont: (row=%d, col=%d)"), vp.row, vp.col);
|
|
|
- G_fatal_error(_("grid: (rows=%d, cols=%d)"), hd->nrows, hd->ncols);
|
|
|
- exit(EXIT_FAILURE);
|
|
|
- }
|
|
|
-#else
|
|
|
- /*open file input file and read grid header from grid ascii file */
|
|
|
- hd = read_header_from_arcascii_file(viewOptions.inputfname);
|
|
|
- assert(hd);
|
|
|
- printf("input grid: (rows=%d, cols=%d)\n", hd->nrows, hd->ncols);
|
|
|
- fflush(stdout);
|
|
|
- /*sanity check */
|
|
|
- if (!(vp.row < hd->nrows && vp.col < hd->ncols)) {
|
|
|
- printf("Viewpoint outside grid\n");
|
|
|
- printf("viewpont: (row=%d, col=%d)\n", vp.row, vp.col);
|
|
|
- printf("grid: (rows=%d, cols=%d)\n", hd->nrows, hd->ncols);
|
|
|
- exit(1);
|
|
|
- /* LT: there is no need to exit if viewpoint is outside grid,
|
|
|
- the algorithm will work correctly in theory. But this
|
|
|
- requires some changes. To do.*/
|
|
|
- }
|
|
|
-#endif /*__GRASS__*/
|
|
|
-
|
|
|
-
|
|
|
- /* set curvature params */
|
|
|
-#ifdef __GRASS__
|
|
|
- viewOptions.cellsize = region.ew_res;
|
|
|
- double e2;
|
|
|
- G_get_ellipsoid_parameters(&viewOptions.ellps_a, &e2);
|
|
|
- if (viewOptions.ellps_a == 0) {
|
|
|
- /*according to r.los, this can be
|
|
|
- problematic, so we'll have a backup, hardcoded radius :-( */
|
|
|
- G_warning(_
|
|
|
- ("Problems obtaining current ellipsoid parameters, usting sphere (6370997.0)"));
|
|
|
- viewOptions.ellps_a = 6370997.00;
|
|
|
- }
|
|
|
-#else
|
|
|
- /* in standalone mode we do not know how to adjust for curvature */
|
|
|
- assert(viewOptions.doCurv == 0);
|
|
|
- viewOptions.ellps_a = 0;
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* decide whether the computation of the viewshed will take place
|
|
|
- in-memory or in external memory */
|
|
|
- int IN_MEMORY;
|
|
|
- long long inmemSizeBytes = get_viewshed_memory_usage(hd);
|
|
|
- printf("In-memory memory usage is %lld B (%d MB), \
|
|
|
-max mem allowed=%lld B(%dMB)\n",
|
|
|
- inmemSizeBytes, (int) (inmemSizeBytes >> 20),
|
|
|
- memSizeBytes, (int)(memSizeBytes>>20));
|
|
|
- if (inmemSizeBytes < memSizeBytes) {
|
|
|
- IN_MEMORY = 1;
|
|
|
- print_message("*************\nIN_MEMORY MODE\n*************\n");
|
|
|
- }
|
|
|
- else {
|
|
|
- print_message("*************\nEXTERNAL_MEMORY MODE\n**********\n");
|
|
|
- IN_MEMORY = 0;
|
|
|
- }
|
|
|
- fflush(stdout);
|
|
|
- /* the mode can be forced to in memory or external if the user
|
|
|
- wants to test or debug a specific mode */
|
|
|
-#ifdef FORCE_EXTERNAL
|
|
|
- IN_MEMORY = 0;
|
|
|
- print_message("FORCED EXTERNAL\n");
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef FORCE_INTERNAL
|
|
|
- IN_MEMORY = 1;
|
|
|
- print_message("FORCED INTERNAL\n");
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* compute viewshed in memory */
|
|
|
- /* ************************************************************ */
|
|
|
- if (IN_MEMORY) {
|
|
|
- /*//////////////////////////////////////////////////// */
|
|
|
- /*/viewshed in internal memory */
|
|
|
- /*//////////////////////////////////////////////////// */
|
|
|
- Rtimer totalTime, outputTime, sweepTime;
|
|
|
- MemoryVisibilityGrid *visgrid;
|
|
|
-
|
|
|
- rt_start(totalTime);
|
|
|
-
|
|
|
- /*compute the viewshed and store it in visgrid */
|
|
|
- rt_start(sweepTime);
|
|
|
- visgrid = viewshed_in_memory(viewOptions.inputfname,hd,&vp, viewOptions);
|
|
|
- rt_stop(sweepTime);
|
|
|
-
|
|
|
- /* write the output */
|
|
|
- rt_start(outputTime);
|
|
|
- save_inmem_visibilitygrid(visgrid, viewOptions, vp);
|
|
|
- rt_stop(outputTime);
|
|
|
-
|
|
|
- rt_stop(totalTime);
|
|
|
-
|
|
|
- print_timings_internal(sweepTime, outputTime, totalTime);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* compute viewshed in external memory */
|
|
|
- /* ************************************************************ */
|
|
|
- else {
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* set up external memory mode */
|
|
|
- /* setup STREAM_DIR if not already set */
|
|
|
- char buf[1000];
|
|
|
- if (getenv(STREAM_TMPDIR) != NULL) {
|
|
|
- /*if already set */
|
|
|
- fprintf(stderr, "%s=%s\n", STREAM_TMPDIR, getenv(STREAM_TMPDIR));
|
|
|
- printf("Intermediate stream location: %s\n", getenv(STREAM_TMPDIR));
|
|
|
- }
|
|
|
- else {
|
|
|
- /*set it */
|
|
|
- sprintf(buf, "%s=%s", STREAM_TMPDIR, "/var/tmp/");
|
|
|
- fprintf(stderr, "setting %s ", buf);
|
|
|
- putenv(buf);
|
|
|
- if (getenv(STREAM_TMPDIR) == NULL) {
|
|
|
- fprintf(stderr, ", not set\n");
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- else {
|
|
|
- fprintf(stderr, ", ok.\n");
|
|
|
- }
|
|
|
- printf("Intermediate stream location: %s\n", "/var/tmp/" );
|
|
|
- }
|
|
|
- fprintf(stderr, "Intermediate files will not be deleted "
|
|
|
- "in case of abnormal termination.\n");
|
|
|
- fprintf(stderr, "To save space delete these files manually!\n");
|
|
|
-
|
|
|
-
|
|
|
- /* initialize IOSTREAM memory manager */
|
|
|
- MM_manager.set_memory_limit(memSizeBytes);
|
|
|
- MM_manager.warn_memory_limit();
|
|
|
- MM_manager.print_limit_mode();
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* BASE CASE OR DISTRIBUTION */
|
|
|
- /* determine whether base-case of external algorithm is enough,
|
|
|
- or recursion is necessary */
|
|
|
- int BASE_CASE = 0;
|
|
|
-
|
|
|
- if (get_active_str_size_bytes(hd) < memSizeBytes)
|
|
|
- BASE_CASE = 1;
|
|
|
-
|
|
|
- /*if the user set the FORCE_DISTRIBUTION flag, then the
|
|
|
- algorithm runs in the fuly recursive mode (even if this is
|
|
|
- not necessary). This is used solely for debugging purpses */
|
|
|
-#ifdef FORCE_DISTRIBUTION
|
|
|
- BASE_CASE = 0;
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* external memory, base case */
|
|
|
- /* ************************************************************ */
|
|
|
- if (BASE_CASE) {
|
|
|
- print_message
|
|
|
- ("---Active structure small, starting base case---\n");
|
|
|
-
|
|
|
- Rtimer totalTime, viewshedTime, outputTime, sortOutputTime;
|
|
|
-
|
|
|
- rt_start(totalTime);
|
|
|
-
|
|
|
- /*run viewshed's algorithm */
|
|
|
- IOVisibilityGrid *visgrid;
|
|
|
-
|
|
|
- rt_start(viewshedTime);
|
|
|
- visgrid = viewshed_external(viewOptions.inputfname,hd,&vp,viewOptions);
|
|
|
- rt_stop(viewshedTime);
|
|
|
-
|
|
|
- /*sort output */
|
|
|
- rt_start(sortOutputTime);
|
|
|
- sort_io_visibilitygrid(visgrid);
|
|
|
- rt_stop(sortOutputTime);
|
|
|
-
|
|
|
- /*save output stream to file. */
|
|
|
- rt_start(outputTime);
|
|
|
- save_io_visibilitygrid(visgrid, viewOptions, vp);
|
|
|
- rt_stop(outputTime);
|
|
|
-
|
|
|
- rt_stop(totalTime);
|
|
|
-
|
|
|
- print_timings_external_memory(totalTime, viewshedTime,
|
|
|
- outputTime, sortOutputTime);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /************************************************************/
|
|
|
- /* external memory, recursive distribution sweeping recursion */
|
|
|
- /************************************************************ */
|
|
|
- else { /* if not BASE_CASE */
|
|
|
-#ifndef FORCE_DISTRIBUTION
|
|
|
- print_message("---Active structure does not fit in memory,");
|
|
|
-#else
|
|
|
- print_message("FORCED DISTRIBUTION\n");
|
|
|
-#endif
|
|
|
-
|
|
|
- Rtimer totalTime, sweepTime, outputTime, sortOutputTime;
|
|
|
-
|
|
|
- rt_start(totalTime);
|
|
|
-
|
|
|
- /*get the viewshed solution by distribution */
|
|
|
- IOVisibilityGrid *visgrid;
|
|
|
-
|
|
|
- rt_start(sweepTime);
|
|
|
- visgrid = distribute_and_sweep(viewOptions.inputfname,hd,&vp,viewOptions);
|
|
|
-
|
|
|
- rt_stop(sweepTime);
|
|
|
-
|
|
|
- /*sort the visibility grid so that it is in order when it is
|
|
|
- outputted */
|
|
|
- rt_start(sortOutputTime);
|
|
|
- sort_io_visibilitygrid(visgrid);
|
|
|
- rt_stop(sortOutputTime);
|
|
|
-
|
|
|
- rt_start(outputTime);
|
|
|
- save_io_visibilitygrid(visgrid, viewOptions, vp);
|
|
|
- rt_stop(outputTime);
|
|
|
-
|
|
|
-
|
|
|
- rt_stop(totalTime);
|
|
|
-
|
|
|
- print_timings_external_memory(totalTime, sweepTime,
|
|
|
- outputTime, sortOutputTime);
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- /*end external memory, distribution sweep */
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* ************************************************************ */
|
|
|
- /* FINISH UP, ALL CASES */
|
|
|
- /* ************************************************************ */
|
|
|
- /*close input file and free grid header */
|
|
|
-#ifdef __GRASS__
|
|
|
- G_free(hd);
|
|
|
- /*following GRASS's coding standards for history and exiting */
|
|
|
- struct History history;
|
|
|
- G_short_history(viewOptions.outputfname, "raster", &history);
|
|
|
- G_command_history(&history);
|
|
|
- G_write_history(viewOptions.outputfname, &history);
|
|
|
- exit(EXIT_SUCCESS);
|
|
|
-#else
|
|
|
- free(hd);
|
|
|
-#endif
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-/*There are two versions of the function parse_args, one for when it is in GRASS, one for independent compilition. */
|
|
|
-#ifdef __GRASS__
|
|
|
-void
|
|
|
-parse_args(int argc, char *argv[], int *vpRow, int *vpCol,
|
|
|
- ViewOptions* viewOptions, long long *memSizeBytes,
|
|
|
- Cell_head *window) {
|
|
|
-
|
|
|
- assert(vpRow && vpCol && memSizeBytes && window);
|
|
|
-
|
|
|
- /* the input */
|
|
|
- struct Option *inputOpt;
|
|
|
- inputOpt = G_define_standard_option(G_OPT_R_ELEV);
|
|
|
- inputOpt->key = "input";
|
|
|
-
|
|
|
- /* the output */
|
|
|
- struct Option *outputOpt;
|
|
|
- outputOpt = G_define_standard_option(G_OPT_R_OUTPUT);
|
|
|
- outputOpt->description = "Name of output viewshed raser map\n\t\t\tdefault format: {NODATA, -1 (invisible), vertical angle wrt viewpoint (visible)}";
|
|
|
-
|
|
|
-
|
|
|
- /* row-column flag */
|
|
|
- struct Flag *row_col;
|
|
|
- row_col = G_define_flag();
|
|
|
- row_col->key = 'r';
|
|
|
- row_col->description =
|
|
|
- _("Use row-column location rather than latitude-longitude location");
|
|
|
-
|
|
|
- /* curvature flag */
|
|
|
- struct Flag *curvature;
|
|
|
- curvature = G_define_flag();
|
|
|
- curvature->key = 'c';
|
|
|
- curvature->description =
|
|
|
- _("Consider the curvature of the earth (current ellipsoid)");
|
|
|
-
|
|
|
-
|
|
|
- /* boolean output flag */
|
|
|
- struct Flag *booleanOutput;
|
|
|
- booleanOutput = G_define_flag();
|
|
|
- booleanOutput->key = 'b';
|
|
|
- booleanOutput->description =
|
|
|
- _("Output format is {0 (invisible) 1 (visible)}");
|
|
|
-
|
|
|
- /* output mode = elevation flag */
|
|
|
- struct Flag *elevationFlag;
|
|
|
- elevationFlag = G_define_flag();
|
|
|
- elevationFlag->key = 'e';
|
|
|
- elevationFlag->description =
|
|
|
- ("Output format is {NODATA, -1 (invisible), elev-viewpoint_elev (visible)}");
|
|
|
-
|
|
|
- /* viewpoint coordinates */
|
|
|
- struct Option *viewLocOpt;
|
|
|
- viewLocOpt = G_define_option();
|
|
|
- viewLocOpt->key = "viewpoint_location";
|
|
|
- viewLocOpt->type = TYPE_STRING;
|
|
|
- viewLocOpt->required = YES;
|
|
|
- viewLocOpt->key_desc = "lat,long";
|
|
|
- viewLocOpt->description =
|
|
|
- ("Coordinates of viewing position in latitude-longitude (if -r flag is present, then coordinates are row-column)");
|
|
|
-
|
|
|
- /* observer elevation */
|
|
|
- struct Option *obsElevOpt;
|
|
|
- obsElevOpt = G_define_option();
|
|
|
- obsElevOpt->key = "observer_elevation";
|
|
|
- obsElevOpt->type = TYPE_DOUBLE;
|
|
|
- obsElevOpt->required = NO;
|
|
|
- obsElevOpt->key_desc = "value";
|
|
|
- obsElevOpt->description = _("Viewing elevation above the ground");
|
|
|
- obsElevOpt->answer = "0.0";
|
|
|
-
|
|
|
- /* max distance */
|
|
|
- struct Option *maxDistOpt;
|
|
|
- maxDistOpt = G_define_option();
|
|
|
- maxDistOpt->key = "max_dist";
|
|
|
- maxDistOpt->type = TYPE_DOUBLE;
|
|
|
- maxDistOpt->required = NO;
|
|
|
- maxDistOpt->key_desc = "value";
|
|
|
- maxDistOpt->description =
|
|
|
- ("Maximum visibility radius. By default infinity (-1).");
|
|
|
- char infdist[10];
|
|
|
- sprintf(infdist, "%d", INFINITY_DISTANCE);
|
|
|
- maxDistOpt->answer = infdist;
|
|
|
-
|
|
|
-
|
|
|
- /* memory size */
|
|
|
- struct Option *memAmountOpt;
|
|
|
- memAmountOpt = G_define_option();
|
|
|
- memAmountOpt->key = "memory_usage";
|
|
|
- memAmountOpt->type = TYPE_INTEGER;
|
|
|
- memAmountOpt->required = NO;
|
|
|
- memAmountOpt->key_desc = "value";
|
|
|
- memAmountOpt->description = _("The amount of main memory in MB to be used");
|
|
|
- memAmountOpt->answer = "500";
|
|
|
-
|
|
|
-
|
|
|
- /*fill the options and flags with G_parser */
|
|
|
- if (G_parser(argc, argv))
|
|
|
- exit(EXIT_FAILURE);
|
|
|
-
|
|
|
-
|
|
|
- /* store the parameters into a structure to be used along the way */
|
|
|
- strcpy(viewOptions->inputfname, inputOpt->answer);
|
|
|
- strcpy(viewOptions->outputfname, outputOpt->answer);
|
|
|
-
|
|
|
- viewOptions->obsElev = atof(obsElevOpt->answer);
|
|
|
-
|
|
|
- viewOptions->maxDist = atof(maxDistOpt->answer);
|
|
|
- if (viewOptions->maxDist < 0 &&
|
|
|
- viewOptions->maxDist!= INFINITY_DISTANCE) {
|
|
|
- G_fatal_error(_("negative max distance value is not valid"));
|
|
|
- exit(EXIT_FAILURE);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- viewOptions->doCurv = curvature->answer;
|
|
|
- if (booleanOutput->answer)
|
|
|
- viewOptions->outputMode = OUTPUT_BOOL;
|
|
|
- else if (elevationFlag->answer)
|
|
|
- viewOptions->outputMode = OUTPUT_ELEV;
|
|
|
- else viewOptions->outputMode = OUTPUT_ANGLE;
|
|
|
-
|
|
|
- int memSizeMB = atoi(memAmountOpt->answer);
|
|
|
- if (memSizeMB <0) {
|
|
|
- printf("Memory cannot be negative.\n");
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- *memSizeBytes = (long long)memSizeMB;
|
|
|
- *memSizeBytes = (*memSizeBytes) << 20;
|
|
|
-
|
|
|
- /*The algorithm runs with the viewpoint row and col, so depending
|
|
|
- on if the row_col flag is present we either need to store the
|
|
|
- row and col, or convert the lat-lon coordinates to row and
|
|
|
- column format */
|
|
|
- if (row_col->answer) {
|
|
|
- *vpRow = atoi(viewLocOpt->answers[1]);
|
|
|
- *vpCol = atoi(viewLocOpt->answers[0]);
|
|
|
- printf("viewpoint in row-col mode: (%d,%d)\n", *vpRow, *vpCol);
|
|
|
- }
|
|
|
- else {
|
|
|
- *vpRow =
|
|
|
- (int)G_northing_to_row(atof(viewLocOpt->answers[1]), window);
|
|
|
- *vpCol = (int)G_easting_to_col(atof(viewLocOpt->answers[0]), window);
|
|
|
- printf("viewpoint converted from lat-lon mode: (%d,%d)\n",*vpRow,*vpCol);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-#else /* if not in GRASS mode */
|
|
|
-void
|
|
|
-parse_args(int argc, char *argv[], int *vpRow, int *vpCol,
|
|
|
- ViewOptions* viewOptions, long long *memSizeBytes) {
|
|
|
-
|
|
|
- assert(vpRow && vpCol && viewOptions && memSizeBytes);
|
|
|
-
|
|
|
- int gotrow = 0, gotcol=0, gotinput = 0, gotoutput = 0;
|
|
|
- int c;
|
|
|
-
|
|
|
- /*deal with flags for the output using getopt */
|
|
|
- while ((c = getopt(argc, argv, "i:o:r:c:v:e:d:m:")) != -1) {
|
|
|
- switch (c) {
|
|
|
- case 'i':
|
|
|
- /* inputfile name */
|
|
|
- //*inputfname = optarg;
|
|
|
- strcpy(viewOptions->inputfname, optarg);
|
|
|
- gotinput = 1;
|
|
|
- break;
|
|
|
- case 'o':
|
|
|
- //*outputfname = optarg;
|
|
|
- strcpy(viewOptions->outputfname, optarg);
|
|
|
- gotoutput= 1;
|
|
|
- break;
|
|
|
- case 'r':
|
|
|
- *vpRow = atoi(optarg);
|
|
|
- gotrow=1;
|
|
|
- break;
|
|
|
- case 'c':
|
|
|
- *vpCol = atoi(optarg);
|
|
|
- gotcol = 1;
|
|
|
- break;
|
|
|
- case 'v':
|
|
|
- /* output mode */
|
|
|
- if (strcmp(optarg, "angle")==0)
|
|
|
- viewOptions->outputMode= OUTPUT_ANGLE;
|
|
|
- else if (strcmp(optarg, "bool")==0)
|
|
|
- viewOptions->outputMode= OUTPUT_BOOL;
|
|
|
- else if (strcmp(optarg, "elev")==0)
|
|
|
- viewOptions->outputMode= OUTPUT_ELEV;
|
|
|
- else {
|
|
|
- printf("unknown option %s: use -v: [angle|bool|elev]\n", optarg);
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 'e':
|
|
|
- viewOptions->obsElev = atof(optarg);
|
|
|
- break;
|
|
|
- case 'd':
|
|
|
- viewOptions->maxDist = atof(optarg);
|
|
|
- if (viewOptions->maxDist < 0) {
|
|
|
- printf("max distance needs to be positive\n");
|
|
|
- exit(EXIT_FAILURE);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 'm':
|
|
|
- int memSizeMB;
|
|
|
- memSizeMB = atoi(optarg);
|
|
|
- if (memSizeMB <0) {
|
|
|
- printf("Memory cannot be negative.\n");
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- *memSizeBytes = (long long)memSizeMB;
|
|
|
- *memSizeBytes = (*memSizeBytes) << 20;
|
|
|
- break;
|
|
|
- case '?':
|
|
|
- if (optopt == 'i' || optopt == 'o' || optopt == 'r' ||
|
|
|
- optopt == 'c' || optopt == 'e' || optopt == 'd' ||
|
|
|
- optopt == 'm')
|
|
|
- fprintf(stderr, "Option -%c requires an argument.\n", optopt);
|
|
|
- else if (isprint(optopt))
|
|
|
- fprintf(stderr, "Unknown option '-%c'.\n", optopt);
|
|
|
- else
|
|
|
- fprintf(stderr, "Unknown option character '\\x%x.\n", optopt);
|
|
|
- print_usage();
|
|
|
- exit(1);
|
|
|
- //default:
|
|
|
- //exit(1);
|
|
|
- }
|
|
|
- } /* while getopt */
|
|
|
-
|
|
|
- /*check to make sure the required options are set.*/
|
|
|
- if(!(gotinput && gotoutput && gotrow &&gotcol)) {
|
|
|
- printf("Not all required options set.\n");
|
|
|
- print_usage();
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- printf("viewpoint: (%d, %d)\n", *vpRow, *vpCol);
|
|
|
- return;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-/*print the timings for the internal memory method of computing the
|
|
|
- viewshed */
|
|
|
-void
|
|
|
-print_timings_internal(Rtimer sweepTime, Rtimer outputTime, Rtimer totalTime) {
|
|
|
-
|
|
|
- char timeused[100];
|
|
|
- printf("TOTAL TIMING: \n");
|
|
|
- rt_sprint_safe(timeused, sweepTime);
|
|
|
- printf("\t%30s", "sweep:");
|
|
|
- printf(timeused); printf("\n");
|
|
|
-
|
|
|
- rt_sprint_safe(timeused, outputTime);
|
|
|
- printf("\t%30s", "output:");
|
|
|
- printf(timeused); printf("\n");
|
|
|
-
|
|
|
- rt_sprint_safe(timeused, totalTime);
|
|
|
- printf("\t%30s", "total:");
|
|
|
- printf(timeused);
|
|
|
- printf("\n");
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-/*print the timings for the external memory method of solving the viewshed */
|
|
|
-void
|
|
|
-print_timings_external_memory(Rtimer totalTime, Rtimer viewshedTime,
|
|
|
- Rtimer outputTime, Rtimer sortOutputTime)
|
|
|
-{
|
|
|
-
|
|
|
- /*print timings */
|
|
|
- char timeused[100];
|
|
|
-
|
|
|
- printf("\n\nTOTAL TIMING: \n");
|
|
|
- rt_sprint_safe(timeused, viewshedTime);
|
|
|
- printf("\t%30s", "total sweep:");
|
|
|
- printf(timeused);
|
|
|
- printf("\n");
|
|
|
- rt_sprint_safe(timeused, sortOutputTime);
|
|
|
- printf("\t%30s", "sort output:");
|
|
|
- printf(timeused);
|
|
|
- printf("\n");
|
|
|
- rt_sprint_safe(timeused, outputTime);
|
|
|
- printf("\t%30s", "Write result grid:");
|
|
|
- printf(timeused);
|
|
|
- printf("\n");
|
|
|
- rt_sprint_safe(timeused, totalTime);
|
|
|
- printf("\t%30s", "Total Time:");
|
|
|
- printf(timeused);
|
|
|
- printf("\n\n");
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-void print_status(Viewpoint vp,ViewOptions viewOptions, long long memSizeBytes)
|
|
|
-{
|
|
|
-
|
|
|
-
|
|
|
-#ifdef __GRASS__
|
|
|
- G_message(_("Options set as:\n"));
|
|
|
- G_message(_("---input: %s \n---output: %s \n---viewpoint: (%d, %d)"),
|
|
|
- viewOptions.inputfname, viewOptions.outputfname,
|
|
|
- vp.row, vp.col);
|
|
|
- if (viewOptions.outputMode == OUTPUT_ANGLE) {
|
|
|
- G_message(_("---outputting viewshed in angle mode:"));
|
|
|
- G_message(_("---The output is {NODATA, %d(invisible),angle(visible)}.\n"), INVISIBLE);
|
|
|
- }
|
|
|
- if (viewOptions.outputMode == OUTPUT_BOOL) {
|
|
|
- G_message(_("---outputting viewshed in boolean mode: "));
|
|
|
- G_message(_("---The output is {%d (invisible), %d (visible)}.\n"),
|
|
|
- BOOL_INVISIBLE, BOOL_VISIBLE);
|
|
|
- }
|
|
|
- if (viewOptions.outputMode == OUTPUT_ELEV) {
|
|
|
- G_message(_("---outputting viewshed in elevation mode: "));
|
|
|
- G_message(_("---The output is {NODATA, %d (invisible), elev (visible)}.\n"),
|
|
|
- INVISIBLE);
|
|
|
- }
|
|
|
- G_message(_("---observer elevation above terrain: %f\n"), viewOptions.obsElev);
|
|
|
-
|
|
|
- if (viewOptions.maxDist == INFINITY_DISTANCE)
|
|
|
- G_message(_("---max distance: infinity\n"));
|
|
|
- else G_message(_("---max distance: %f\n"), viewOptions.maxDist);
|
|
|
-
|
|
|
- G_message(_("---consider earth curvature: %d\n"), viewOptions.doCurv);
|
|
|
-
|
|
|
- G_message(_("---max memory = %d MB\n"), (int)(memSizeBytes >> 20));
|
|
|
- G_message(_("---------------------------------\n"));
|
|
|
-
|
|
|
-#else
|
|
|
- printf("---------------------------------\nOptions set as:\n");
|
|
|
- printf("input: %s \noutput: %s\n",
|
|
|
- viewOptions.inputfname, viewOptions.outputfname);
|
|
|
- printf("viewpoint: (%d, %d)\n", vp.row, vp.col);
|
|
|
- if (viewOptions.outputMode == OUTPUT_ANGLE) {
|
|
|
- printf("outputting viewshed in angle mode: ");
|
|
|
- printf("The output is {NODATA, %d (invisible), angle (visible)}.\n",
|
|
|
- INVISIBLE);
|
|
|
- }
|
|
|
- if (viewOptions.outputMode == OUTPUT_BOOL) {
|
|
|
- printf("outputting viewshed in boolean mode: ");
|
|
|
- printf("The output is {%d (invisible), %d (visible)}.\n",
|
|
|
- BOOL_INVISIBLE, BOOL_VISIBLE);
|
|
|
- }
|
|
|
- if (viewOptions.outputMode == OUTPUT_ELEV) {
|
|
|
- printf("outputting viewshed in elevation mode: ");
|
|
|
- printf("The output is {NODATA, %d (invisible), elev (visible)}.\n",
|
|
|
- INVISIBLE);
|
|
|
- }
|
|
|
-
|
|
|
- printf("observer elevation above terrain: %f\n", viewOptions.obsElev);
|
|
|
-
|
|
|
- if (viewOptions.maxDist == INFINITY_DISTANCE)
|
|
|
- printf("max distance: infinity\n");
|
|
|
- else printf("max distance: %f\n", viewOptions.maxDist);
|
|
|
-
|
|
|
- printf("consider earth curvature: %d\n", viewOptions.doCurv);
|
|
|
-
|
|
|
- printf("max memory = %d MB\n", (int)(memSizeBytes >> 20));
|
|
|
- printf("---------------------------------\n");
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-/* ------------------------------------------------------------ */
|
|
|
-/*print the usage information. Only used in the stand-alone version*/
|
|
|
-void print_usage() {
|
|
|
- printf("\nusage: ioviewshed -i <input name> -o <output name> -r <row number> -c <column number> [-v <angle | bool | elev>] [-e <observer elevation>] [-d <max distance>] [-m <memory usage MB>]\n\n");
|
|
|
-
|
|
|
- printf("OPTIONS\n");
|
|
|
- printf("-i \t input map name.\n");
|
|
|
- printf("-o \t output map name.\n");
|
|
|
- printf("-r \t row number.\n");
|
|
|
- printf("-c \t column number.\n");
|
|
|
- printf("-v \t iutput mode. Default is angle.\n");
|
|
|
- printf(" \t\t angle: output is {NODATA, -1 (invisible), angle (visible)}\n\t\t\t angle is a value in [0,180] and represents the vertical angle wrt viewpoint.\n");
|
|
|
- printf(" \t\t bool: output is {0 (invisible), 1 (visible)}.\n");
|
|
|
- printf(" \t\t elev: output is {NODATA, -1 (invisible), elev (visible)}. This is not implemented in the standalone version.\n");
|
|
|
- printf("-e \t observer elevation. Default is 0.\n");
|
|
|
- printf("-d \t maximum distance. Default is infinity.\n");
|
|
|
- printf("-m \t memory usage in MB. Default is 500.\n");
|
|
|
-}
|