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: 2025-08-01 10:10:57 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 outOfRangeVal{
      64             :         0};  //!< raster output value for pixels outside of max distance.
      65             :     double nodataVal{-1};      //!< raster output value for pixels with no data
      66             :     double targetHeight{0.0};  //!< target height above the DEM surface
      67             :     double maxDistance{
      68             :         0.0};  //!< maximum distance from observer to compute value
      69             :     double minDistance{
      70             :         0.0};  //!< minimum distance from observer to compute value.
      71             :     double startAngle{0.0};  //!< start angle of observable range
      72             :     double endAngle{0.0};    //!< end angle of observable range
      73             :     double lowPitch{
      74             :         -90.0};  //!< minimum pitch (vertical angle) of observable points
      75             :     double highPitch{
      76             :         90.0};  //!< maximum pitch (vertical angle) of observable points
      77             :     double curveCoeff{.85714};  //!< coefficient for atmospheric refraction
      78             :     OutputMode outputMode{OutputMode::Normal};  //!< Output information.
      79             :         //!< Normal, Height from DEM or Height from ground
      80             :     std::string outputFormat{};         //!< output raster format
      81             :     std::string outputFilename{};       //!< output raster filename
      82             :     CPLStringList creationOpts{};       //!< options for output raster creation
      83             :     CellMode cellMode{CellMode::Edge};  //!< Mode of cell height calculation.
      84             :     int observerSpacing{10};  //!< Observer spacing in cumulative mode.
      85             :     uint8_t numJobs{3};       //!< Relative number of jobs in cumulative mode.
      86             : 
      87             :     /// True if angle masking will occur.
      88       54619 :     bool angleMasking() const
      89             :     {
      90       54619 :         return startAngle != endAngle;
      91             :     }
      92             : 
      93             :     /// True if low pitch masking will occur.
      94     2976680 :     bool lowPitchMasking() const
      95             :     {
      96     2976680 :         return lowPitch > -90.0;
      97             :     }
      98             : 
      99             :     /// True if high pitch masking will occur.
     100     2975370 :     bool highPitchMasking() const
     101             :     {
     102     2975370 :         return highPitch < 90.0;
     103             :     }
     104             : 
     105             :     /// True if pitch masking will occur.
     106     2973960 :     bool pitchMasking() const
     107             :     {
     108     2973960 :         return lowPitchMasking() || highPitchMasking();
     109             :     }
     110             : };
     111             : 
     112             : /**
     113             :  * A window in a raster including pixels in [xStart, xStop) and [yStart, yStop).
     114             :  */
     115             : struct Window
     116             : {
     117             :     int xStart{};  //!< X start position
     118             :     int xStop{};   //!< X end position
     119             :     int yStart{};  //!< Y start position
     120             :     int yStop{};   //!< Y end position
     121             : 
     122             :     /// Returns true when one window is equal to the other.
     123          13 :     bool operator==(const Window &w2) const
     124             :     {
     125          13 :         return xStart == w2.xStart && xStop == w2.xStop &&
     126          26 :                yStart == w2.yStart && yStop == w2.yStop;
     127             :     }
     128             : 
     129             :     /// \brief  Window size in the X direction.
     130     1857690 :     int xSize() const
     131             :     {
     132     1857690 :         return xStop - xStart;
     133             :     }
     134             : 
     135             :     /// \brief  Window size in the Y direction.
     136       87319 :     int ySize() const
     137             :     {
     138       87319 :         return yStop - yStart;
     139             :     }
     140             : 
     141             :     /// \brief  Number of cells.
     142       86528 :     size_t size() const
     143             :     {
     144       86528 :         return static_cast<size_t>(xSize()) * ySize();
     145             :     }
     146             : 
     147             :     /// \brief  Determine if the X window contains the index.
     148             :     /// \param  nX  Index to check
     149             :     /// \return  True if the index is contained, false otherwise.
     150       29203 :     bool containsX(int nX) const
     151             :     {
     152       29203 :         return nX >= xStart && nX < xStop;
     153             :     }
     154             : 
     155             :     /// \brief  Determine if the Y window contains the index.
     156             :     /// \param  nY  Index to check
     157             :     /// \return  True if the index is contained, false otherwise.
     158         268 :     bool containsY(int nY) const
     159             :     {
     160         268 :         return nY >= xStart && nY < yStop;
     161             :     }
     162             : 
     163             :     /// \brief  Determine if the window contains the index.
     164             :     /// \param  nX  X coordinate of the index to check
     165             :     /// \param  nY  Y coordinate of the index to check
     166             :     /// \return  True if the index is contained, false otherwise.
     167          39 :     bool contains(int nX, int nY) const
     168             :     {
     169          39 :         return containsX(nX) && containsY(nY);
     170             :     }
     171             : 
     172             :     /// \brief  Clamp the argument to be in the window in the X dimension.
     173             :     /// \param  nX  Value to clamp.
     174             :     /// \return  Clamped value.
     175       83481 :     int clampX(int nX) const
     176             :     {
     177       83481 :         return xSize() ? std::clamp(nX, xStart, xStop - 1) : xStart;
     178             :     }
     179             : 
     180             :     /// \brief  Clamp the argument to be in the window in the Y dimension.
     181             :     /// \param  nY  Value to clamp.
     182             :     /// \return  Clamped value.
     183         470 :     int clampY(int nY) const
     184             :     {
     185         470 :         return ySize() ? std::clamp(nY, yStart, yStop - 1) : yStart;
     186             :     }
     187             : 
     188             :     /// \brief  Shift the X dimension by nShift.
     189             :     /// \param  nShift  Amount to shift
     190          39 :     void shiftX(int nShift)
     191             :     {
     192          39 :         xStart += nShift;
     193          39 :         xStop += nShift;
     194          39 :     }
     195             : };
     196             : 
     197           0 : inline std::ostream &operator<<(std::ostream &out, const Window &w)
     198             : {
     199           0 :     out << "Xstart/stop Ystart/stop = " << w.xStart << "/" << w.xStop << " "
     200           0 :         << w.yStart << "/" << w.yStop;
     201           0 :     return out;
     202             : }
     203             : 
     204             : /// Processing limits based on min/max distance restrictions.
     205             : /// The left side processing range is [left, leftMin).
     206             : /// The right side processing range is [rightMin, right).
     207             : struct LineLimits
     208             : {
     209             :     /// Constructor that takes the members in order.
     210       28780 :     LineLimits(int leftArg, int leftMinArg, int rightMinArg, int rightArg)
     211       28780 :         : left(leftArg), leftMin(leftMinArg), rightMin(rightMinArg),
     212       28780 :           right(rightArg)
     213             :     {
     214       28780 :     }
     215             : 
     216             :     int left;      //!< Starting (leftmost) cell on the left side.
     217             :     int leftMin;   //!< One past the rightmost cell on the left side.
     218             :     int rightMin;  //!< Starting (leftmost) cell on the right side.
     219             :     int right;     //!< One past the rightmost cell on the right side.
     220             : };
     221             : 
     222             : inline std::ostream &operator<<(std::ostream &out, const LineLimits &ll)
     223             : {
     224             :     out << "Left/LeftMin RightMin/Right = " << ll.left << "/" << ll.leftMin
     225             :         << " " << ll.rightMin << "/" << ll.right;
     226             :     return out;
     227             : }
     228             : 
     229             : constexpr int INVALID_ISECT = std::numeric_limits<int>::max();
     230             : 
     231             : }  // namespace viewshed
     232             : }  // namespace gdal
     233             : 
     234             : #endif

Generated by: LCOV version 1.14