21 , mTileOverlapPixels( tileOverlapPixels )
22 , mMaximumTileWidth( DEFAULT_MAXIMUM_TILE_WIDTH )
23 , mMaximumTileHeight( DEFAULT_MAXIMUM_TILE_HEIGHT )
30 mMaximumTileWidth = rdp->
stepWidth() - 2 * mTileOverlapPixels;
31 mMaximumTileHeight = rdp->
stepHeight() - 2 * mTileOverlapPixels;
39 const double xRes = rasterExtent.
width() / rasterWidth;
40 const double yRes = rasterExtent.
height() / rasterHeight;
43 int bottom = rasterHeight - 1;
45 int right = rasterWidth - 1;
65 if ( resamplingFactor > 1 )
68 left = ( ( left + resamplingFactor - 1 ) / resamplingFactor ) * resamplingFactor;
69 top = ( ( top + resamplingFactor - 1 ) / resamplingFactor ) * resamplingFactor;
72 right = ( right / resamplingFactor ) * resamplingFactor - 1;
73 bottom = ( bottom / resamplingFactor ) * resamplingFactor - 1;
76 subRegionWidth = right - left + 1;
77 subRegionHeight = bottom - top + 1;
83 rasterExtent.
yMaximum() - ( ( top + subRegionHeight ) * yRes ),
84 rasterExtent.
xMinimum() + ( ( left + subRegionWidth ) * xRes ),
85 rasterExtent.
yMaximum() - ( top * yRes ) );
99 removePartInfo( bandNumber );
102 RasterPartInfo pInfo;
105 pInfo.currentCol = 0;
106 pInfo.currentRow = 0;
107 mRasterPartInfos.insert( bandNumber, pInfo );
109 mNumberBlocksWidth =
static_cast< int >( std::ceil(
static_cast< double >( nCols ) / mMaximumTileWidth ) );
110 mNumberBlocksHeight =
static_cast< int >( std::ceil(
static_cast< double >( nRows ) / mMaximumTileHeight ) );
115 int outTileColumns = 0;
117 int outTileTopLeftColumn = 0;
118 int outTileTopLeftRow = 0;
119 return readNextRasterPartInternal( bandNumber, columns, rows,
nullptr, topLeftColumn, topLeftRow, &blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
123 int &nCols,
int &nRows,
125 int &topLeftCol,
int &topLeftRow )
128 std::unique_ptr< QgsRasterBlock > nextBlock;
129 const bool result =
readNextRasterPart( bandNumber, nCols, nRows, nextBlock, topLeftCol, topLeftRow );
131 *block = nextBlock.release();
135bool QgsRasterIterator::readNextRasterPart(
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 )
137 int outTileColumns = 0;
139 int outTileTopLeftColumn = 0;
140 int outTileTopLeftRow = 0;
141 const bool res = readNextRasterPartInternal( bandNumber, nCols, nRows, &block, topLeftCol, topLeftRow, blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
144 *tileColumns = outTileColumns;
146 *tileRows = outTileRows;
147 if ( tileTopLeftColumn )
148 *tileTopLeftColumn = outTileTopLeftColumn;
149 if ( tileTopLeftRow )
150 *tileTopLeftRow = outTileTopLeftRow;
155bool QgsRasterIterator::readNextRasterPartInternal(
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 )
161 const QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
162 if ( partIt == mRasterPartInfos.end() )
167 RasterPartInfo &pInfo = partIt.value();
170 if ( 0 == pInfo.nCols || 0 == pInfo.nRows )
178 if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
184 tileTopLeftColumn = pInfo.currentCol;
185 tileTopLeftRow = pInfo.currentRow;
187 tileColumns =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileWidth ), pInfo.nCols - tileTopLeftColumn ) );
188 tileRows =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileHeight ), pInfo.nRows - tileTopLeftRow ) );
190 if ( mSnapToPixelFactor > 1 )
193 tileColumns = ( tileColumns / mSnapToPixelFactor ) * mSnapToPixelFactor;
194 tileRows = ( tileRows / mSnapToPixelFactor ) * mSnapToPixelFactor;
197 const qgssize tileRight = tileTopLeftColumn + tileColumns;
198 const qgssize tileBottom = tileTopLeftRow + tileRows;
200 const qgssize blockLeft = tileTopLeftColumn >= mTileOverlapPixels ? ( tileTopLeftColumn - mTileOverlapPixels ) : 0;
201 const qgssize blockTop = tileTopLeftRow >= mTileOverlapPixels ? ( tileTopLeftRow - mTileOverlapPixels ) : 0;
202 const qgssize blockRight = std::min< qgssize >( tileRight + mTileOverlapPixels, pInfo.nCols );
203 const qgssize blockBottom = std::min< qgssize >( tileBottom + mTileOverlapPixels, pInfo.nRows );
205 nCols = blockRight - blockLeft;
206 nRows = blockBottom - blockTop;
208 if ( mSnapToPixelFactor > 1 )
211 nCols = ( nCols / mSnapToPixelFactor ) * mSnapToPixelFactor;
212 nRows = ( nRows / mSnapToPixelFactor ) * mSnapToPixelFactor;
213 if ( nCols == 0 || nRows == 0 )
217 QgsDebugMsgLevel( QStringLiteral(
"nCols = %1 nRows = %2" ).arg( nCols ).arg( nRows ), 4 );
221 const double xmin = viewPortExtent.
xMinimum() + blockLeft /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
222 const double xmax = blockLeft + nCols == pInfo.nCols ? viewPortExtent.
xMaximum() :
223 viewPortExtent.
xMinimum() + ( blockLeft + nCols ) /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
224 const double ymin = blockTop + nRows == pInfo.nRows ? viewPortExtent.
yMinimum() :
225 viewPortExtent.
yMaximum() - ( blockTop + nRows ) /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
226 const double ymax = viewPortExtent.
yMaximum() - blockTop /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
230 *blockExtent = blockRect;
233 block->reset( mInput->
block( bandNumber, blockRect, nCols, nRows, mFeedback ) );
234 topLeftCol = blockLeft;
235 topLeftRow = blockTop;
237 pInfo.currentCol = tileRight;
238 if ( pInfo.currentCol == pInfo.nCols && tileBottom == pInfo.nRows )
240 pInfo.currentRow = pInfo.nRows;
242 else if ( pInfo.currentCol == pInfo.nCols )
244 pInfo.currentCol = 0;
245 pInfo.currentRow = tileBottom;
253 removePartInfo( bandNumber );
258 const auto partIt = mRasterPartInfos.find( bandNumber );
259 if ( partIt == mRasterPartInfos.constEnd() )
264 return ( (
static_cast< double >( partIt->currentRow ) /
static_cast< double >( mMaximumTileHeight ) ) * mNumberBlocksWidth +
static_cast< double >( partIt->currentCol ) /
static_cast< double >( mMaximumTileWidth ) ) / (
static_cast< double >( mNumberBlocksWidth ) *
static_cast< double >( mNumberBlocksHeight ) );
267void QgsRasterIterator::removePartInfo(
int bandNumber )
269 const auto partIt = mRasterPartInfos.constFind( bandNumber );
270 if ( partIt != mRasterPartInfos.constEnd() )
272 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.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
virtual QgsRasterInterface * input() const
Current input.
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.
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...
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
double progress(int bandNumber) const
Returns the raster iteration progress as a fraction from 0 to 1.0, for the specified bandNumber.
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)