22using namespace Qt::StringLiterals;
26 , mTileOverlapPixels( tileOverlapPixels )
35 mMaximumTileWidth = rdp->
stepWidth() - 2 * mTileOverlapPixels;
36 mMaximumTileHeight = rdp->
stepHeight() - 2 * mTileOverlapPixels;
43 const QgsRectangle &rasterExtent,
int rasterWidth,
int rasterHeight,
const QgsRectangle &
subRegion,
int &subRegionWidth,
int &subRegionHeight,
int &subRegionLeft,
int &subRegionTop,
int resamplingFactor
46 const double xRes = rasterExtent.
width() / rasterWidth;
47 const double yRes = rasterExtent.
height() / rasterHeight;
50 int bottom = rasterHeight - 1;
52 int right = rasterWidth - 1;
56 top =
static_cast< int >( std::floor( ( rasterExtent.
yMaximum() -
subRegion.yMaximum() ) / yRes ) );
60 bottom =
static_cast< int >( std::ceil( ( rasterExtent.
yMaximum() -
subRegion.yMinimum() ) / yRes ) - 1 );
65 left =
static_cast< int >( std::floor( (
subRegion.xMinimum() - rasterExtent.
xMinimum() ) / xRes ) );
69 right =
static_cast< int >( std::ceil( (
subRegion.xMaximum() - rasterExtent.
xMinimum() ) / xRes ) - 1 );
72 if ( resamplingFactor > 1 )
75 left = ( ( left + resamplingFactor - 1 ) / resamplingFactor ) * resamplingFactor;
76 top = ( ( top + resamplingFactor - 1 ) / resamplingFactor ) * resamplingFactor;
79 right = ( right / resamplingFactor ) * resamplingFactor - 1;
80 bottom = ( bottom / resamplingFactor ) * resamplingFactor - 1;
83 subRegionWidth = right - left + 1;
84 subRegionHeight = bottom - top + 1;
90 rasterExtent.
xMinimum() + ( left * xRes ),
91 rasterExtent.
yMaximum() - ( ( top + subRegionHeight ) * yRes ),
92 rasterExtent.
xMinimum() + ( ( left + subRegionWidth ) * xRes ),
93 rasterExtent.
yMaximum() - ( top * yRes )
105 mFeedback = feedback;
108 removePartInfo( bandNumber );
111 RasterPartInfo pInfo;
114 pInfo.currentCol = 0;
115 pInfo.currentRow = 0;
116 mRasterPartInfos.insert( bandNumber, pInfo );
118 mNumberBlocksWidth =
static_cast< int >( std::ceil(
static_cast< double >( nCols ) / mMaximumTileWidth ) );
119 mNumberBlocksHeight =
static_cast< int >( std::ceil(
static_cast< double >( nRows ) / mMaximumTileHeight ) );
124 int outTileColumns = 0;
126 int outTileTopLeftColumn = 0;
127 int outTileTopLeftRow = 0;
128 return readNextRasterPartInternal( bandNumber, columns, rows,
nullptr, topLeftColumn, topLeftRow, &blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
134 std::unique_ptr< QgsRasterBlock > nextBlock;
135 const bool result =
readNextRasterPart( bandNumber, nCols, nRows, nextBlock, topLeftCol, topLeftRow );
137 *block = nextBlock.release();
142 int bandNumber,
int &nCols,
int &nRows, std::unique_ptr<QgsRasterBlock> &block,
int &topLeftCol,
int &topLeftRow,
QgsRectangle *blockExtent,
int *tileColumns,
int *tileRows,
int *tileTopLeftColumn,
int *tileTopLeftRow
145 int outTileColumns = 0;
147 int outTileTopLeftColumn = 0;
148 int outTileTopLeftRow = 0;
149 const bool res = readNextRasterPartInternal( bandNumber, nCols, nRows, &block, topLeftCol, topLeftRow, blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
152 *tileColumns = outTileColumns;
154 *tileRows = outTileRows;
155 if ( tileTopLeftColumn )
156 *tileTopLeftColumn = outTileTopLeftColumn;
157 if ( tileTopLeftRow )
158 *tileTopLeftRow = outTileTopLeftRow;
163bool QgsRasterIterator::readNextRasterPartInternal(
164 int bandNumber,
int &nCols,
int &nRows, std::unique_ptr<QgsRasterBlock> *block,
int &topLeftCol,
int &topLeftRow,
QgsRectangle *blockExtent,
int &tileColumns,
int &tileRows,
int &tileTopLeftColumn,
int &tileTopLeftRow
171 const QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
172 if ( partIt == mRasterPartInfos.end() )
177 RasterPartInfo &pInfo = partIt.value();
180 if ( 0 == pInfo.nCols || 0 == pInfo.nRows )
188 if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
194 tileTopLeftColumn = pInfo.currentCol;
195 tileTopLeftRow = pInfo.currentRow;
197 tileColumns =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileWidth ), pInfo.nCols - tileTopLeftColumn ) );
198 tileRows =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileHeight ), pInfo.nRows - tileTopLeftRow ) );
200 if ( mSnapToPixelFactor > 1 )
203 tileColumns = ( tileColumns / mSnapToPixelFactor ) * mSnapToPixelFactor;
204 tileRows = ( tileRows / mSnapToPixelFactor ) * mSnapToPixelFactor;
207 pInfo.previousIteratedPixels = pInfo.iteratedPixels;
208 pInfo.currentBlockSize =
static_cast< std::size_t
>( tileColumns ) *
static_cast< std::size_t
>( tileRows );
209 pInfo.iteratedPixels += pInfo.currentBlockSize;
211 const qgssize tileRight = tileTopLeftColumn + tileColumns;
212 const qgssize tileBottom = tileTopLeftRow + tileRows;
214 const qgssize blockLeft = tileTopLeftColumn >= mTileOverlapPixels ? ( tileTopLeftColumn - mTileOverlapPixels ) : 0;
215 const qgssize blockTop = tileTopLeftRow >= mTileOverlapPixels ? ( tileTopLeftRow - mTileOverlapPixels ) : 0;
216 const qgssize blockRight = std::min< qgssize >( tileRight + mTileOverlapPixels, pInfo.nCols );
217 const qgssize blockBottom = std::min< qgssize >( tileBottom + mTileOverlapPixels, pInfo.nRows );
219 nCols = blockRight - blockLeft;
220 nRows = blockBottom - blockTop;
222 if ( mSnapToPixelFactor > 1 )
225 nCols = ( nCols / mSnapToPixelFactor ) * mSnapToPixelFactor;
226 nRows = ( nRows / mSnapToPixelFactor ) * mSnapToPixelFactor;
227 if ( nCols == 0 || nRows == 0 )
231 QgsDebugMsgLevel( u
"nCols = %1 nRows = %2"_s.arg( nCols ).arg( nRows ), 4 );
234 const QgsRectangle viewPortExtent = mExtent;
235 const double xmin = viewPortExtent.
xMinimum() + blockLeft /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
236 const double xmax = blockLeft + nCols == pInfo.nCols ? viewPortExtent.
xMaximum() :
237 viewPortExtent.
xMinimum() + ( blockLeft + nCols ) /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
238 const double ymin = blockTop + nRows == pInfo.nRows ? viewPortExtent.
yMinimum() :
239 viewPortExtent.
yMaximum() - ( blockTop + nRows ) /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
240 const double ymax = viewPortExtent.
yMaximum() - blockTop /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
241 const QgsRectangle blockRect( xmin, ymin, xmax, ymax );
244 *blockExtent = blockRect;
247 block->reset( mInput->block( bandNumber, blockRect, nCols, nRows, mFeedback ) );
248 topLeftCol = blockLeft;
249 topLeftRow = blockTop;
251 pInfo.currentCol = tileRight;
252 if ( pInfo.currentCol == pInfo.nCols && tileBottom == pInfo.nRows )
254 pInfo.currentRow = pInfo.nRows;
256 else if ( pInfo.currentCol == pInfo.nCols )
258 pInfo.currentCol = 0;
259 pInfo.currentRow = tileBottom;
267 removePartInfo( bandNumber );
272 if ( currentBlockProgress < 0 )
274 const auto partIt = mRasterPartInfos.find( bandNumber );
275 if ( partIt == mRasterPartInfos.constEnd() )
279 const std::size_t totalSize =
static_cast< std::size_t
>( partIt->nCols ) *
static_cast< std::size_t
>( partIt->nRows );
280 return static_cast< double >( partIt->iteratedPixels ) /
static_cast< double >( totalSize );
284 const auto partIt = mRasterPartInfos.find( bandNumber );
285 if ( partIt == mRasterPartInfos.constEnd() )
290 const std::size_t totalSize =
static_cast< std::size_t
>( partIt->nCols ) *
static_cast< std::size_t
>( partIt->nRows );
291 const double startOfBlockProgress =
static_cast< double >( partIt->previousIteratedPixels ) /
static_cast< double >( totalSize );
292 const double currentBlockProgressFraction = currentBlockProgress *
static_cast< double >( partIt->currentBlockSize ) /
static_cast< double >( totalSize );
294 return startOfBlockProgress + currentBlockProgressFraction;
298void QgsRasterIterator::removePartInfo(
int bandNumber )
300 const auto partIt = mRasterPartInfos.constFind( bandNumber );
301 if ( partIt != mRasterPartInfos.constEnd() )
303 mRasterPartInfos.remove( bandNumber );
Feedback object tailored for raster block reading.
Base class for raster data providers.
virtual int stepHeight() const
Step height for raster iterations.
virtual int stepWidth() const
Step width for raster iterations.
Base class for processing filters like renderers, reprojector, resampler etc.
static QgsRectangle subRegion(const QgsRectangle &rasterExtent, int rasterWidth, int rasterHeight, const QgsRectangle &subRegion, int &subRegionWidth, int &subRegionHeight, int &subRegionLeft, int &subRegionTop, int resamplingFactor=1)
Given an overall raster extent and width and height in pixels, calculates the sub region of the raste...
bool next(int bandNumber, int &columns, int &rows, int &topLeftColumn, int &topLeftRow, QgsRectangle &blockExtent)
Fetches details of the next part of the raster data.
QgsRasterIterator(QgsRasterInterface *input, int tileOverlapPixels=0)
Constructor for QgsRasterIterator, iterating over the specified input raster source.
const QgsRasterInterface * input() const
Returns the input raster interface which is being iterated over.
void stopRasterRead(int bandNumber)
Cancels the raster iteration and resets the iterator.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
bool readNextRasterPart(int bandNumber, int &nCols, int &nRows, QgsRasterBlock **block, int &topLeftCol, int &topLeftRow)
Fetches next part of raster data, caller takes ownership of the block and caller should delete the bl...
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
double progress(int bandNumber, double currentBlockProgress=-1) const
Returns the raster iteration progress as a fraction from 0 to 1.0, for the specified bandNumber.
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
A rectangle specified with double values.
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
#define QgsDebugMsgLevel(str, level)