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 subRegionWidth = right - left + 1;
66 subRegionHeight = bottom - top + 1;
71 rasterExtent.
yMaximum() - ( ( top + subRegionHeight ) * yRes ),
72 rasterExtent.
xMinimum() + ( ( left + subRegionWidth ) * xRes ),
73 rasterExtent.
yMaximum() - ( top * yRes ) );
87 removePartInfo( bandNumber );
95 mRasterPartInfos.insert( bandNumber, pInfo );
97 mNumberBlocksWidth =
static_cast< int >( std::ceil(
static_cast< double >( nCols ) / mMaximumTileWidth ) );
98 mNumberBlocksHeight =
static_cast< int >( std::ceil(
static_cast< double >( nRows ) / mMaximumTileHeight ) );
103 int outTileColumns = 0;
105 int outTileTopLeftColumn = 0;
106 int outTileTopLeftRow = 0;
107 return readNextRasterPartInternal( bandNumber, columns, rows,
nullptr, topLeftColumn, topLeftRow, &blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
111 int &nCols,
int &nRows,
113 int &topLeftCol,
int &topLeftRow )
116 std::unique_ptr< QgsRasterBlock > nextBlock;
117 const bool result =
readNextRasterPart( bandNumber, nCols, nRows, nextBlock, topLeftCol, topLeftRow );
119 *block = nextBlock.release();
123bool 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 )
125 int outTileColumns = 0;
127 int outTileTopLeftColumn = 0;
128 int outTileTopLeftRow = 0;
129 const bool res = readNextRasterPartInternal( bandNumber, nCols, nRows, &block, topLeftCol, topLeftRow, blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
132 *tileColumns = outTileColumns;
134 *tileRows = outTileRows;
135 if ( tileTopLeftColumn )
136 *tileTopLeftColumn = outTileTopLeftColumn;
137 if ( tileTopLeftRow )
138 *tileTopLeftRow = outTileTopLeftRow;
143bool 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 )
149 const QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
150 if ( partIt == mRasterPartInfos.end() )
155 RasterPartInfo &pInfo = partIt.value();
158 if ( 0 == pInfo.nCols || 0 == pInfo.nRows )
166 if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
173 tileTopLeftColumn = pInfo.currentCol;
174 tileTopLeftRow = pInfo.currentRow;
175 tileColumns =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileWidth ), pInfo.nCols - tileTopLeftColumn ) );
176 tileRows =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileHeight ), pInfo.nRows - tileTopLeftRow ) );
177 const qgssize tileRight = tileTopLeftColumn + tileColumns;
178 const qgssize tileBottom = tileTopLeftRow + tileRows;
180 const qgssize blockLeft = tileTopLeftColumn >= mTileOverlapPixels ? ( tileTopLeftColumn - mTileOverlapPixels ) : 0;
181 const qgssize blockTop = tileTopLeftRow >= mTileOverlapPixels ? ( tileTopLeftRow - mTileOverlapPixels ) : 0;
182 const qgssize blockRight = std::min< qgssize >( tileRight + mTileOverlapPixels, pInfo.nCols );
183 const qgssize blockBottom = std::min< qgssize >( tileBottom + mTileOverlapPixels, pInfo.nRows );
185 nCols = blockRight - blockLeft;
186 nRows = blockBottom - blockTop;
188 QgsDebugMsgLevel( QStringLiteral(
"nCols = %1 nRows = %2" ).arg( nCols ).arg( nRows ), 4 );
192 const double xmin = viewPortExtent.
xMinimum() + blockLeft /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
193 const double xmax = blockLeft + nCols == pInfo.nCols ? viewPortExtent.
xMaximum() :
194 viewPortExtent.
xMinimum() + ( blockLeft + nCols ) /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
195 const double ymin = blockTop + nRows == pInfo.nRows ? viewPortExtent.
yMinimum() :
196 viewPortExtent.
yMaximum() - ( blockTop + nRows ) /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
197 const double ymax = viewPortExtent.
yMaximum() - blockTop /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
201 *blockExtent = blockRect;
204 block->reset( mInput->
block( bandNumber, blockRect, nCols, nRows, mFeedback ) );
205 topLeftCol = blockLeft;
206 topLeftRow = blockTop;
208 pInfo.currentCol = tileRight;
209 if ( pInfo.currentCol == pInfo.nCols && tileBottom == pInfo.nRows )
211 pInfo.currentRow = pInfo.nRows;
213 else if ( pInfo.currentCol == pInfo.nCols )
215 pInfo.currentCol = 0;
216 pInfo.currentRow = tileBottom;
224 removePartInfo( bandNumber );
229 const auto partIt = mRasterPartInfos.find( bandNumber );
230 if ( partIt == mRasterPartInfos.constEnd() )
235 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 ) );
238void QgsRasterIterator::removePartInfo(
int bandNumber )
240 const auto partIt = mRasterPartInfos.constFind( bandNumber );
241 if ( partIt != mRasterPartInfos.constEnd() )
243 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.
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...
static QgsRectangle subRegion(const QgsRectangle &rasterExtent, int rasterWidth, int rasterHeight, const QgsRectangle &subRegion, int &subRegionWidth, int &subRegionHeight, int &subRegionLeft, int &subRegionTop)
Given an overall raster extent and width and height in pixels, calculates the sub region of the raste...
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)