Skip to content

Commit 08ab218

Browse files
committed
Checkpoint.
1 parent 1f2581f commit 08ab218

File tree

2 files changed

+80
-31
lines changed

2 files changed

+80
-31
lines changed

alg/viewshed/viewshed_executor.cpp

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ namespace gdal
2626
namespace viewshed
2727
{
2828

29+
CPLErr DummyBand::IReadBlock(int, int, void *)
30+
{
31+
return static_cast<CPLErr>(CPLE_NotSupported);
32+
}
33+
2934
namespace
3035
{
3136

@@ -113,6 +118,7 @@ double doMax(int nXOffset, int nYOffset, double dfThisPrev, double dfLast,
113118

114119
/// Constructor - the viewshed algorithm executor
115120
/// @param srcBand Source raster band
121+
/// @param sdBand Standard-deviation raster band
116122
/// @param dstBand Destination raster band
117123
/// @param nX X position of observer
118124
/// @param nY Y position of observer
@@ -123,11 +129,12 @@ double doMax(int nXOffset, int nYOffset, double dfThisPrev, double dfLast,
123129
/// @param emitWarningIfNoData Whether a warning must be emitted if an input
124130
/// pixel is at the nodata value.
125131
ViewshedExecutor::ViewshedExecutor(GDALRasterBand &srcBand,
132+
GDALRasterBand &sdBand,
126133
GDALRasterBand &dstBand, int nX, int nY,
127134
const Window &outExtent,
128135
const Window &curExtent, const Options &opts,
129136
Progress &progress, bool emitWarningIfNoData)
130-
: m_pool(4), m_srcBand(srcBand), m_dstBand(dstBand),
137+
: m_pool(4), m_srcBand(srcBand), m_sdBand(sdBand), m_dstBand(dstBand),
131138
m_emitWarningIfNoData(emitWarningIfNoData), oOutExtent(outExtent),
132139
oCurExtent(curExtent), m_nX(nX - oOutExtent.xStart), m_nY(nY),
133140
oOpts(opts), oProgress(progress),
@@ -146,6 +153,27 @@ ViewshedExecutor::ViewshedExecutor(GDALRasterBand &srcBand,
146153
m_hasNoData = hasNoData;
147154
}
148155

156+
/// Constructor - the viewshed algorithm executor
157+
/// @param srcBand Source raster band
158+
/// @param dstBand Destination raster band
159+
/// @param nX X position of observer
160+
/// @param nY Y position of observer
161+
/// @param outExtent Extent of output raster (relative to input)
162+
/// @param curExtent Extent of active raster.
163+
/// @param opts Configuration options.
164+
/// @param progress Reference to the progress tracker.
165+
/// @param emitWarningIfNoData Whether a warning must be emitted if an input
166+
/// pixel is at the nodata value.
167+
ViewshedExecutor::ViewshedExecutor(GDALRasterBand &srcBand,
168+
GDALRasterBand &dstBand, int nX, int nY,
169+
const Window &outExtent,
170+
const Window &curExtent, const Options &opts,
171+
Progress &progress, bool emitWarningIfNoData)
172+
: ViewshedExecutor(srcBand, m_dummyBand, dstBand, nX, nY, outExtent,
173+
curExtent, opts, progress, emitWarningIfNoData)
174+
{
175+
}
176+
149177
// calculate the height adjustment factor.
150178
double ViewshedExecutor::calcHeightAdjFactor()
151179
{
@@ -194,22 +222,33 @@ void ViewshedExecutor::setOutput(double &dfResult, double &dfCellVal,
194222
/// Read a line of raster data.
195223
///
196224
/// @param nLine Line number to read.
197-
/// @param line Raster line to fill.
225+
/// @param lines Raster line to fill.
198226
/// @return Success or failure.
199-
bool ViewshedExecutor::readLine(int nLine, std::vector<double> &line)
227+
bool ViewshedExecutor::readLine(int nLine, Lines &lines)
200228
{
201229
std::lock_guard g(iMutex);
202230

203231
if (GDALRasterIO(&m_srcBand, GF_Read, oOutExtent.xStart, nLine,
204-
oOutExtent.xSize(), 1, line.data(), oOutExtent.xSize(), 1,
205-
GDT_Float64, 0, 0))
232+
oOutExtent.xSize(), 1, lines.cur.data(),
233+
oOutExtent.xSize(), 1, GDT_Float64, 0, 0))
206234
{
207235
CPLError(CE_Failure, CPLE_AppDefined,
208236
"RasterIO error when reading DEM at position (%d,%d), "
209237
"size (%d,%d)",
210238
oOutExtent.xStart, nLine, oOutExtent.xSize(), 1);
211239
return false;
212240
}
241+
242+
if (sdMode())
243+
lines.input = lines.cur;
244+
245+
// Initialize the result line.
246+
// In DEM mode the base is the pre-adjustment value. In ground mode the base is zero.
247+
if (oOpts.outputMode == OutputMode::DEM)
248+
lines.result = lines.cur;
249+
else if (oOpts.outputMode == OutputMode::Ground)
250+
std::fill(lines.result.begin(), lines.result.end(), 0);
251+
213252
return true;
214253
}
215254

@@ -376,29 +415,23 @@ bool ViewshedExecutor::processFirstLine(Lines &lines)
376415
int nLine = oOutExtent.clampY(m_nY);
377416
int nYOffset = nLine - m_nY;
378417

379-
if (!readLine(nLine, lines.cur))
418+
if (!readLine(nLine, lines))
380419
return false;
381420

382421
// If the observer is outside of the raster, take the specified value as the Z height,
383422
// otherwise, take it as an offset from the raster height at that location.
384423
m_dfZObserver = oOpts.observer.z;
385424
if (oCurExtent.containsX(m_nX))
386-
{
387425
m_dfZObserver += lines.cur[m_nX];
388-
if (oOpts.outputMode == OutputMode::Normal)
389-
lines.result[m_nX] = oOpts.visibleVal;
390-
}
391-
m_dfHeightAdjFactor = calcHeightAdjFactor();
392-
393-
// In DEM mode the base is the pre-adjustment value. In ground mode the base is zero.
394-
if (oOpts.outputMode == OutputMode::DEM)
395-
lines.result = lines.cur;
396-
else if (oOpts.outputMode == OutputMode::Ground)
397-
std::fill(lines.result.begin(), lines.result.end(), 0);
398426

399427
LineLimits ll = adjustHeight(nYOffset, lines);
400-
if (oCurExtent.containsX(m_nX) && ll.leftMin != ll.rightMin)
401-
lines.result[m_nX] = oOpts.outOfRangeVal;
428+
if (oCurExtent.containsX(m_nX))
429+
{
430+
if (ll.leftMin != ll.rightMin)
431+
lines.result[m_nX] = oOpts.outOfRangeVal;
432+
else if (oOpts.outputMode == OutputMode::Normal)
433+
lines.result[m_nX] = oOpts.visibleVal;
434+
}
402435

403436
if (!oCurExtent.containsY(m_nY))
404437
processFirstLineTopOrBottom(ll, lines);
@@ -866,16 +899,9 @@ bool ViewshedExecutor::processLine(int nLine, Lines &lines)
866899
{
867900
int nYOffset = nLine - m_nY;
868901

869-
if (!readLine(nLine, lines.cur))
902+
if (!readLine(nLine, lines))
870903
return false;
871904

872-
// In DEM mode the base is the input DEM value.
873-
// In ground mode the base is zero.
874-
if (oOpts.outputMode == OutputMode::DEM)
875-
lines.result = lines.cur;
876-
else if (oOpts.outputMode == OutputMode::Ground)
877-
std::fill(lines.result.begin(), lines.result.end(), 0);
878-
879905
// Adjust height of the read line.
880906
LineLimits ll = adjustHeight(nYOffset, lines);
881907

@@ -962,6 +988,8 @@ bool ViewshedExecutor::run()
962988
firstLine.pitchMask.resize(oOutExtent.xSize(),
963989
std::numeric_limits<double>::quiet_NaN());
964990

991+
m_dfHeightAdjFactor = calcHeightAdjFactor();
992+
965993
if (!processFirstLine(firstLine))
966994
return false;
967995

@@ -1025,5 +1053,11 @@ bool ViewshedExecutor::run()
10251053
return true;
10261054
}
10271055

1056+
bool ViewshedExecutor::sdMode() const
1057+
{
1058+
// If the SD band isn't a dummy band, we're in SD mode.
1059+
return dynamic_cast<DummyBand *>(&m_sdBand) == nullptr;
1060+
}
1061+
10281062
} // namespace viewshed
10291063
} // namespace gdal

alg/viewshed/viewshed_executor.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,40 @@ struct Lines
3636
std::vector<double> result; //!< Result values for current line
3737
std::vector<double> prev; //!< Height values for previous line
3838
std::vector<double>
39-
pitchMask; //!< Height/indicator values for pitch masking.
39+
pitchMask; //!< Height/indicator values for pitch masking.
40+
std::vector<double> input; //!< Copy of input data when in SD mode.
4041

4142
/// Constructor
42-
Lines() : cur(), result(), prev(), pitchMask()
43+
Lines() : cur(), result(), prev(), pitchMask(), input()
4344
{
4445
}
4546

4647
/// Constructor that initializes to line length
4748
/// \param lineLen Line length.
4849
explicit Lines(size_t lineLen)
49-
: cur(lineLen), result(lineLen), prev(), pitchMask()
50+
: cur(lineLen), result(lineLen), prev(), pitchMask(), input()
5051
{
5152
}
5253
};
5354

55+
class DummyBand : public GDALRasterBand
56+
{
57+
virtual CPLErr IReadBlock(int, int, void *) override;
58+
};
59+
5460
class Progress;
5561

5662
/// Executes a viewshed computation on a source band, placing the result
5763
/// in the destination band.
5864
class ViewshedExecutor
5965
{
6066
public:
67+
ViewshedExecutor(GDALRasterBand &srcBand, GDALRasterBand &sdBand,
68+
GDALRasterBand &dstBand, int nX, int nY,
69+
const Window &oOutExtent, const Window &oCurExtent,
70+
const Options &opts, Progress &oProgress,
71+
bool emitWarningIfNoData);
72+
6173
ViewshedExecutor(GDALRasterBand &srcBand, GDALRasterBand &dstBand, int nX,
6274
int nY, const Window &oOutExtent, const Window &oCurExtent,
6375
const Options &opts, Progress &oProgress,
@@ -72,7 +84,9 @@ class ViewshedExecutor
7284

7385
private:
7486
CPLWorkerThreadPool m_pool;
87+
DummyBand m_dummyBand;
7588
GDALRasterBand &m_srcBand;
89+
GDALRasterBand &m_sdBand;
7690
GDALRasterBand &m_dstBand;
7791
double m_noDataValue = 0;
7892
bool m_hasNoData = false;
@@ -98,7 +112,7 @@ class ViewshedExecutor
98112

99113
double calcHeightAdjFactor();
100114
void setOutput(double &dfResult, double &dfCellVal, double dfZ);
101-
bool readLine(int nLine, std::vector<double> &line);
115+
bool readLine(int nLine, Lines &lines);
102116
bool writeLine(int nLine, std::vector<double> &vResult);
103117
bool processLine(int nLine, Lines &lines);
104118
bool processFirstLine(Lines &lines);
@@ -120,6 +134,7 @@ class ViewshedExecutor
120134
void applyPitchMask(std::vector<double> &vResult,
121135
const std::vector<double> &vPitchMaskVal);
122136
void calcTestAngles();
137+
bool sdMode() const;
123138
};
124139

125140
} // namespace viewshed

0 commit comments

Comments
 (0)