LCOV - code coverage report
Current view: top level - alg/viewshed - viewshed_types.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 35 39 89.7 %
Date: 2026-01-16 04:37:55 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /****************************************************************************
       2             :  * (c) 2024 info@hobu.co
       3             :  *
       4             :  * SPDX-License-Identifier: MIT
       5             :  ****************************************************************************/
       6             : #ifndef VIEWSHED_TYPES_H_INCLUDED
       7             : #define VIEWSHED_TYPES_H_INCLUDED
       8             : 
       9             : #include <algorithm>
      10             : #include <limits>
      11             : #include <string>
      12             : 
      13             : #include "gdal_priv.h"
      14             : 
      15             : namespace gdal
      16             : {
      17             : namespace viewshed
      18             : {
      19             : 
      20             : /// Unique pointer to GDAL dataset.
      21             : using DatasetPtr = std::unique_ptr<GDALDataset>;
      22             : 
      23             : /**
      24             :  * Raster output mode.
      25             :  */
      26             : enum class OutputMode
      27             : {
      28             :     Normal,     //!< Normal output mode (visibility only)
      29             :     DEM,        //!< Output height from DEM
      30             :     Ground,     //!< Output height from ground
      31             :     Cumulative  //!< Output observability heat map
      32             : };
      33             : 
      34             : /**
      35             :  * Cell height calculation mode.
      36             :  */
      37             : enum class CellMode
      38             : {
      39             :     Diagonal,  //!< Diagonal Mode
      40             :     Edge,      //!< Edge Mode
      41             :     Max,       //!< Maximum value produced by Diagonal and Edge mode
      42             :     Min        //!< Minimum value produced by Diagonal and Edge mode
      43             : };
      44             : 
      45             : /**
      46             :  * A point.
      47             :  */
      48             : struct Point
      49             : {
      50             :     double x;  //!< X value
      51             :     double y;  //!< Y value
      52             :     double z;  //!< Z value
      53             : };
      54             : 
      55             : /**
      56             :  * Options for viewshed generation.
      57             :  */
      58             : struct Options
      59             : {
      60             :     Point observer{0, 0, 0};  //!< x, y, and z of the observer
      61             :     double visibleVal{255};   //!< raster output value for visible pixels.
      62             :     double invisibleVal{0};   //!< raster output value for non-visible pixels.
      63             :     double maybeVisibleVal{
      64             :         2};  //!< raster output for potentially visible pixels.
      65             :     double outOfRangeVal{
      66             :         0};  //!< raster output value for pixels outside of max distance.
      67             :     double nodataVal{-1};      //!< raster output value for pixels with no data
      68             :     double targetHeight{0.0};  //!< target height above the DEM surface
      69             :     double maxDistance{
      70             :         0.0};  //!< maximum distance from observer to compute value
      71             :     double minDistance{
      72             :         0.0};  //!< minimum distance from observer to compute value.
      73             :     double startAngle{0.0};  //!< start angle of observable range
      74             :     double endAngle{0.0};    //!< end angle of observable range
      75             :     double lowPitch{
      76             :         -90.0};  //!< minimum pitch (vertical angle) of observable points
      77             :     double highPitch{
      78             :         90.0};  //!< maximum pitch (vertical angle) of observable points
      79             :     double curveCoeff{.85714};  //!< coefficient for atmospheric refraction
      80             :     OutputMode outputMode{OutputMode::Normal};  //!< Output information.
      81             :         //!< Normal, Height from DEM or Height from ground
      82             :     std::string outputFormat{};         //!< output raster format
      83             :     std::string outputFilename{};       //!< output raster filename
      84             :     CPLStringList creationOpts{};       //!< options for output raster creation
      85             :     CellMode cellMode{CellMode::Edge};  //!< Mode of cell height calculation.
      86             :     int observerSpacing{10};  //!< Observer spacing in cumulative mode.
      87             :     uint8_t numJobs{3};       //!< Relative number of jobs in cumulative mode.
      88             : 
      89             :     /// True if angle masking will occur.
      90       58393 :     bool angleMasking() const
      91             :     {
      92       58393 :         return startAngle != endAngle;
      93             :     }
      94             : 
      95             :     /// True if low pitch masking will occur.
      96     3072460 :     bool lowPitchMasking() const
      97             :     {
      98     3072460 :         return lowPitch > -90.0;
      99             :     }
     100             : 
     101             :     /// True if high pitch masking will occur.
     102     3072390 :     bool highPitchMasking() const
     103             :     {
     104     3072390 :         return highPitch < 90.0;
     105             :     }
     106             : 
     107             :     /// True if pitch masking will occur.
     108     3072210 :     bool pitchMasking() const
     109             :     {
     110     3072210 :         return lowPitchMasking() || highPitchMasking();
     111             :     }
     112             : };
     113             : 
     114             : /**
     115             :  * A window in a raster including pixels in [xStart, xStop) and [yStart, yStop).
     116             :  */
     117             : struct Window
     118             : {
     119             :     int xStart{};  //!< X start position
     120             :     int xStop{};   //!< X end position
     121             :     int yStart{};  //!< Y start position
     122             :     int yStop{};   //!< Y end position
     123             : 
     124             :     /// Returns true when one window is equal to the other.
     125          13 :     bool operator==(const Window &w2) const
     126             :     {
     127          13 :         return xStart == w2.xStart && xStop == w2.xStop &&
     128          26 :                yStart == w2.yStart && yStop == w2.yStop;
     129             :     }
     130             : 
     131             :     /// \brief  Window size in the X direction.
     132     1853240 :     int xSize() const
     133             :     {
     134     1853240 :         return xStop - xStart;
     135             :     }
     136             : 
     137             :     /// \brief  Window size in the Y direction.
     138       87364 :     int ySize() const
     139             :     {
     140       87364 :         return yStop - yStart;
     141             :     }
     142             : 
     143             :     /// \brief  Number of cells.
     144       86528 :     size_t size() const
     145             :     {
     146       86528 :         return static_cast<size_t>(xSize()) * ySize();
     147             :     }
     148             : 
     149             :     /// \brief  Determine if the X window contains the index.
     150             :     /// \param  nX  Index to check
     151             :     /// \return  True if the index is contained, false otherwise.
     152       29574 :     bool containsX(int nX) const
     153             :     {
     154       29574 :         return nX >= xStart && nX < xStop;
     155             :     }
     156             : 
     157             :     /// \brief  Determine if the Y window contains the index.
     158             :     /// \param  nY  Index to check
     159             :     /// \return  True if the index is contained, false otherwise.
     160         295 :     bool containsY(int nY) const
     161             :     {
     162         295 :         return nY >= xStart && nY < yStop;
     163             :     }
     164             : 
     165             :     /// \brief  Determine if the window contains the index.
     166             :     /// \param  nX  X coordinate of the index to check
     167             :     /// \param  nY  Y coordinate of the index to check
     168             :     /// \return  True if the index is contained, false otherwise.
     169          48 :     bool contains(int nX, int nY) const
     170             :     {
     171          48 :         return containsX(nX) && containsY(nY);
     172             :     }
     173             : 
     174             :     /// \brief  Clamp the argument to be in the window in the X dimension.
     175             :     /// \param  nX  Value to clamp.
     176             :     /// \return  Clamped value.
     177       84632 :     int clampX(int nX) const
     178             :     {
     179       84632 :         return xSize() ? std::clamp(nX, xStart, xStop - 1) : xStart;
     180             :     }
     181             : 
     182             :     /// \brief  Clamp the argument to be in the window in the Y dimension.
     183             :     /// \param  nY  Value to clamp.
     184             :     /// \return  Clamped value.
     185         488 :     int clampY(int nY) const
     186             :     {
     187         488 :         return ySize() ? std::clamp(nY, yStart, yStop - 1) : yStart;
     188             :     }
     189             : 
     190             :     /// \brief  Shift the X dimension by nShift.
     191             :     /// \param  nShift  Amount to shift
     192          48 :     void shiftX(int nShift)
     193             :     {
     194          48 :         xStart += nShift;
     195          48 :         xStop += nShift;
     196          48 :     }
     197             : };
     198             : 
     199           0 : inline std::ostream &operator<<(std::ostream &out, const Window &w)
     200             : {
     201           0 :     out << "Xstart/stop Ystart/stop = " << w.xStart << "/" << w.xStop << " "
     202           0 :         << w.yStart << "/" << w.yStop;
     203           0 :     return out;
     204             : }
     205             : 
     206             : /// Processing limits based on min/max distance restrictions.
     207             : /// The left side processing range is [left, leftMin).
     208             : /// The right side processing range is [rightMin, right).
     209             : struct LineLimits
     210             : {
     211             :     /// Constructor that takes the members in order.
     212       29125 :     LineLimits(int leftArg, int leftMinArg, int rightMinArg, int rightArg)
     213       29125 :         : left(leftArg), leftMin(leftMinArg), rightMin(rightMinArg),
     214       29125 :           right(rightArg)
     215             :     {
     216       29125 :     }
     217             : 
     218             :     int left;      //!< Starting (leftmost) cell on the left side.
     219             :     int leftMin;   //!< One past the rightmost cell on the left side.
     220             :     int rightMin;  //!< Starting (leftmost) cell on the right side.
     221             :     int right;     //!< One past the rightmost cell on the right side.
     222             : };
     223             : 
     224             : inline std::ostream &operator<<(std::ostream &out, const LineLimits &ll)
     225             : {
     226             :     out << "Left/LeftMin RightMin/Right = " << ll.left << "/" << ll.leftMin
     227             :         << " " << ll.rightMin << "/" << ll.right;
     228             :     return out;
     229             : }
     230             : 
     231             : constexpr int INVALID_ISECT = std::numeric_limits<int>::max();
     232             : 
     233             : }  // namespace viewshed
     234             : }  // namespace gdal
     235             : 
     236             : #endif

Generated by: LCOV version 1.14