LCOV - code coverage report
Current view: top level - alg/viewshed - viewshed_types.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 29 33 87.9 %
Date: 2025-05-31 00:00:17 Functions: 12 13 92.3 %

          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       54671 :     bool angleMasking() const
      89             :     {
      90       54671 :         return startAngle != endAngle;
      91             :     }
      92             : };
      93             : 
      94             : /**
      95             :  * A window in a raster including pixels in [xStart, xStop) and [yStart, yStop).
      96             :  */
      97             : struct Window
      98             : {
      99             :     int xStart{};  //!< X start position
     100             :     int xStop{};   //!< X end position
     101             :     int yStart{};  //!< Y start position
     102             :     int yStop{};   //!< Y end position
     103             : 
     104             :     /// Returns true when one window is equal to the other.
     105          13 :     bool operator==(const Window &w2) const
     106             :     {
     107          13 :         return xStart == w2.xStart && xStop == w2.xStop &&
     108          26 :                yStart == w2.yStart && yStop == w2.yStop;
     109             :     }
     110             : 
     111             :     /// \brief  Window size in the X direction.
     112     1867340 :     int xSize() const
     113             :     {
     114     1867340 :         return xStop - xStart;
     115             :     }
     116             : 
     117             :     /// \brief  Window size in the Y direction.
     118       87319 :     int ySize() const
     119             :     {
     120       87319 :         return yStop - yStart;
     121             :     }
     122             : 
     123             :     /// \brief  Number of cells.
     124       86528 :     size_t size() const
     125             :     {
     126       86528 :         return static_cast<size_t>(xSize()) * ySize();
     127             :     }
     128             : 
     129             :     /// \brief  Determine if the X window contains the index.
     130             :     /// \param  nX  Index to check
     131             :     /// \return  True if the index is contained, false otherwise.
     132       29215 :     bool containsX(int nX) const
     133             :     {
     134       29215 :         return nX >= xStart && nX < xStop;
     135             :     }
     136             : 
     137             :     /// \brief  Determine if the Y window contains the index.
     138             :     /// \param  nY  Index to check
     139             :     /// \return  True if the index is contained, false otherwise.
     140         268 :     bool containsY(int nY) const
     141             :     {
     142         268 :         return nY >= xStart && nY < yStop;
     143             :     }
     144             : 
     145             :     /// \brief  Determine if the window contains the index.
     146             :     /// \param  nX  X coordinate of the index to check
     147             :     /// \param  nY  Y coordinate of the index to check
     148             :     /// \return  True if the index is contained, false otherwise.
     149          39 :     bool contains(int nX, int nY) const
     150             :     {
     151          39 :         return containsX(nX) && containsY(nY);
     152             :     }
     153             : 
     154             :     /// \brief  Clamp the argument to be in the window in the X dimension.
     155             :     /// \param  nX  Value to clamp.
     156             :     /// \return  Clamped value.
     157       83563 :     int clampX(int nX) const
     158             :     {
     159       83563 :         return xSize() ? std::clamp(nX, xStart, xStop - 1) : xStart;
     160             :     }
     161             : 
     162             :     /// \brief  Clamp the argument to be in the window in the Y dimension.
     163             :     /// \param  nY  Value to clamp.
     164             :     /// \return  Clamped value.
     165         470 :     int clampY(int nY) const
     166             :     {
     167         470 :         return ySize() ? std::clamp(nY, yStart, yStop - 1) : yStart;
     168             :     }
     169             : 
     170             :     /// \brief  Shift the X dimension by nShift.
     171             :     /// \param  nShift  Amount to shift
     172          39 :     void shiftX(int nShift)
     173             :     {
     174          39 :         xStart += nShift;
     175          39 :         xStop += nShift;
     176          39 :     }
     177             : };
     178             : 
     179           0 : inline std::ostream &operator<<(std::ostream &out, const Window &w)
     180             : {
     181           0 :     out << "Xstart/stop Ystart/stop = " << w.xStart << "/" << w.xStop << " "
     182           0 :         << w.yStart << "/" << w.yStop;
     183           0 :     return out;
     184             : }
     185             : 
     186             : /// Processing limits based on min/max distance restrictions.
     187             : /// The left side processing range is [left, leftMin).
     188             : /// The right side processing range is [rightMin, right).
     189             : struct LineLimits
     190             : {
     191             :     /// Constructor that takes the members in order.
     192       28820 :     LineLimits(int leftArg, int leftMinArg, int rightMinArg, int rightArg)
     193       28820 :         : left(leftArg), leftMin(leftMinArg), rightMin(rightMinArg),
     194       28820 :           right(rightArg)
     195             :     {
     196       28820 :     }
     197             : 
     198             :     int left;      //!< Starting (leftmost) cell on the left side.
     199             :     int leftMin;   //!< One past the rightmost cell on the left side.
     200             :     int rightMin;  //!< Starting (leftmost) cell on the right side.
     201             :     int right;     //!< One past the rightmost cell on the right side.
     202             : };
     203             : 
     204             : inline std::ostream &operator<<(std::ostream &out, const LineLimits &ll)
     205             : {
     206             :     out << "Left/LeftMin RightMin/Right = " << ll.left << "/" << ll.leftMin
     207             :         << " " << ll.rightMin << "/" << ll.right;
     208             :     return out;
     209             : }
     210             : 
     211             : constexpr int INVALID_ISECT = std::numeric_limits<int>::max();
     212             : 
     213             : }  // namespace viewshed
     214             : }  // namespace gdal
     215             : 
     216             : #endif

Generated by: LCOV version 1.14