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