LCOV - code coverage report
Current view: top level - alg/viewshed - viewshed_executor.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 5 5 100.0 %
Date: 2026-01-16 04:37:55 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Viewshed Generation
       4             :  * Purpose:  Core algorithm implementation for viewshed generation.
       5             :  * Author:   Tamas Szekeres, szekerest@gmail.com
       6             :  *
       7             :  * (c) 2024 info@hobu.co
       8             :  *
       9             :  ******************************************************************************
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #pragma once
      15             : 
      16             : #include <array>
      17             : #include <limits>
      18             : #include <mutex>
      19             : 
      20             : #include "gdal_priv.h"
      21             : #include "cpl_worker_thread_pool.h"
      22             : 
      23             : #include "viewshed_types.h"
      24             : 
      25             : namespace gdal
      26             : {
      27             : namespace viewshed
      28             : {
      29             : 
      30             : /**
      31             :  * Container for lines necessary for processing.
      32             :  */
      33             : struct Lines
      34             : {
      35             :     std::vector<double> cur;     //!< Current line being processed
      36             :     std::vector<double> result;  //!< Result values for current line
      37             :     std::vector<double> prev;    //!< Height values for previous line
      38             :     std::vector<double>
      39             :         pitchMask;  //!< Height/indicator values for pitch masking.
      40             :     std::vector<double> prevTmp;  //!< Saved prev values when in SD mode.
      41             :     std::vector<double> sd;       //!< SD mask.
      42             : 
      43             :     /// Constructor
      44             :     Lines() : cur(), result(), prev(), pitchMask(), prevTmp(), sd()
      45             :     {
      46             :     }
      47             : 
      48             :     /// Constructor that initializes to line length
      49             :     /// \param lineLen  Line length.
      50         732 :     explicit Lines(size_t lineLen)
      51         732 :         : cur(lineLen), result(lineLen), prev(), pitchMask(), prevTmp(), sd()
      52             :     {
      53         732 :     }
      54             : };
      55             : 
      56             : /// Dummy raster band.
      57             : //! @cond Doxygen_Suppress
      58             : class DummyBand : public GDALRasterBand
      59             : {
      60             :     CPLErr IReadBlock(int, int, void *) override;
      61             : };
      62             : //! @endcond
      63             : 
      64             : class Progress;
      65             : 
      66             : /// Executes a viewshed computation on a source band, placing the result
      67             : /// in the destination band.
      68             : class ViewshedExecutor
      69             : {
      70             :   public:
      71             :     ViewshedExecutor(GDALRasterBand &srcBand, GDALRasterBand &sdBand,
      72             :                      GDALRasterBand &dstBand, int nX, int nY,
      73             :                      const Window &oOutExtent, const Window &oCurExtent,
      74             :                      const Options &opts, Progress &oProgress,
      75             :                      bool emitWarningIfNoData);
      76             : 
      77             :     ViewshedExecutor(GDALRasterBand &srcBand, GDALRasterBand &dstBand, int nX,
      78             :                      int nY, const Window &oOutExtent, const Window &oCurExtent,
      79             :                      const Options &opts, Progress &oProgress,
      80             :                      bool emitWarningIfNoData);
      81             :     bool run();
      82             : 
      83             :     /** Return whether an input pixel is at the nodata value. */
      84         196 :     bool hasFoundNoData() const
      85             :     {
      86         196 :         return m_hasFoundNoData;
      87             :     }
      88             : 
      89             :   private:
      90             :     CPLWorkerThreadPool m_pool;
      91             :     DummyBand m_dummyBand;
      92             :     GDALRasterBand &m_srcBand;
      93             :     GDALRasterBand &m_sdBand;
      94             :     GDALRasterBand &m_dstBand;
      95             :     double m_noDataValue = 0;
      96             :     bool m_hasNoData = false;
      97             :     bool m_emitWarningIfNoData = false;
      98             :     bool m_hasFoundNoData = false;
      99             :     const Window oOutExtent;
     100             :     const Window oCurExtent;
     101             :     const int m_nX;
     102             :     const int m_nY;
     103             :     const Options oOpts;
     104             :     Progress &oProgress;
     105             :     double m_dfHeightAdjFactor{0};
     106             :     double m_dfMinDistance2;
     107             :     double m_dfMaxDistance2;
     108             :     double m_dfZObserver{0};
     109             :     std::mutex iMutex{};
     110             :     std::mutex oMutex{};
     111             :     GDALGeoTransform m_gt{};
     112             :     std::array<double, 5> m_testAngle{};
     113             :     double m_lowTanPitch{std::numeric_limits<double>::quiet_NaN()};
     114             :     double m_highTanPitch{std::numeric_limits<double>::quiet_NaN()};
     115             :     double (*oZcalc)(int, int, double, double, double){};
     116             : 
     117             :     double calcHeightAdjFactor();
     118             : 
     119             :     void setOutputNormal(Lines &lines, int pos, double dfZ);
     120             :     void setOutputSd(Lines &lines, int pos, double dfZ);
     121             : 
     122             :     bool readLine(int nLine, Lines &lines);
     123             :     bool writeLine(int nLine, std::vector<double> &vResult);
     124             :     bool processLine(int nLine, Lines &lines);
     125             :     bool processFirstLine(Lines &lines);
     126             :     void processFirstLineLeft(const LineLimits &ll, Lines &lines, bool sdCalc);
     127             :     void processFirstLineRight(const LineLimits &ll, Lines &lines, bool sdCalc);
     128             :     void processFirstLineTopOrBottom(const LineLimits &ll, Lines &lines);
     129             :     void processLineLeft(int nYOffset, LineLimits &ll, Lines &lines,
     130             :                          bool sdCalc);
     131             :     void processLineRight(int nYOffset, LineLimits &ll, Lines &lines,
     132             :                           bool sdCalc);
     133             :     LineLimits adjustHeight(int iLine, Lines &lines);
     134             :     bool maskInitial(std::vector<double> &vResult, const LineLimits &ll,
     135             :                      int nLine);
     136             :     bool maskAngleLeft(std::vector<double> &vResult, int nLine);
     137             :     bool maskAngleRight(std::vector<double> &vResult, int nLine);
     138             :     void maskLineLeft(std::vector<double> &vResult, const LineLimits &ll,
     139             :                       int nLine);
     140             :     void maskLineRight(std::vector<double> &vResult, const LineLimits &ll,
     141             :                        int nLine);
     142             :     void calcPitchMask(double dfZ, double dfDist, double dfResult,
     143             :                        double &maskVal);
     144             :     void applyPitchMask(std::vector<double> &vResult,
     145             :                         const std::vector<double> &vPitchMaskVal);
     146             :     void calcTestAngles();
     147             :     bool sdMode() const;
     148             : };
     149             : 
     150             : }  // namespace viewshed
     151             : }  // namespace gdal

Generated by: LCOV version 1.14