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 );
100 int outTileColumns = 0;
102 int outTileTopLeftColumn = 0;
103 int outTileTopLeftRow = 0;
104 return readNextRasterPartInternal( bandNumber, columns, rows,
nullptr, topLeftColumn, topLeftRow, &blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
108 int &nCols,
int &nRows,
110 int &topLeftCol,
int &topLeftRow )
113 std::unique_ptr< QgsRasterBlock > nextBlock;
114 const bool result =
readNextRasterPart( bandNumber, nCols, nRows, nextBlock, topLeftCol, topLeftRow );
116 *block = nextBlock.release();
120bool 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 )
122 int outTileColumns = 0;
124 int outTileTopLeftColumn = 0;
125 int outTileTopLeftRow = 0;
126 const bool res = readNextRasterPartInternal( bandNumber, nCols, nRows, &block, topLeftCol, topLeftRow, blockExtent, outTileColumns, outTileRows, outTileTopLeftColumn, outTileTopLeftRow );
129 *tileColumns = outTileColumns;
131 *tileRows = outTileRows;
132 if ( tileTopLeftColumn )
133 *tileTopLeftColumn = outTileTopLeftColumn;
134 if ( tileTopLeftRow )
135 *tileTopLeftRow = outTileTopLeftRow;
140bool 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 )
146 const QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
147 if ( partIt == mRasterPartInfos.end() )
152 RasterPartInfo &pInfo = partIt.value();
155 if ( 0 == pInfo.nCols || 0 == pInfo.nRows )
163 if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
170 tileTopLeftColumn = pInfo.currentCol;
171 tileTopLeftRow = pInfo.currentRow;
172 tileColumns =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileWidth ), pInfo.nCols - tileTopLeftColumn ) );
173 tileRows =
static_cast< int >( std::min(
static_cast< qgssize >( mMaximumTileHeight ), pInfo.nRows - tileTopLeftRow ) );
174 const qgssize tileRight = tileTopLeftColumn + tileColumns;
175 const qgssize tileBottom = tileTopLeftRow + tileRows;
177 const qgssize blockLeft = tileTopLeftColumn >= mTileOverlapPixels ? ( tileTopLeftColumn - mTileOverlapPixels ) : 0;
178 const qgssize blockTop = tileTopLeftRow >= mTileOverlapPixels ? ( tileTopLeftRow - mTileOverlapPixels ) : 0;
179 const qgssize blockRight = std::min< qgssize >( tileRight + mTileOverlapPixels, pInfo.nCols );
180 const qgssize blockBottom = std::min< qgssize >( tileBottom + mTileOverlapPixels, pInfo.nRows );
182 nCols = blockRight - blockLeft;
183 nRows = blockBottom - blockTop;
185 QgsDebugMsgLevel( QStringLiteral(
"nCols = %1 nRows = %2" ).arg( nCols ).arg( nRows ), 4 );
189 const double xmin = viewPortExtent.
xMinimum() + blockLeft /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
190 const double xmax = blockLeft + nCols == pInfo.nCols ? viewPortExtent.
xMaximum() :
191 viewPortExtent.
xMinimum() + ( blockLeft + nCols ) /
static_cast< double >( pInfo.nCols ) * viewPortExtent.
width();
192 const double ymin = blockTop + nRows == pInfo.nRows ? viewPortExtent.
yMinimum() :
193 viewPortExtent.
yMaximum() - ( blockTop + nRows ) /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
194 const double ymax = viewPortExtent.
yMaximum() - blockTop /
static_cast< double >( pInfo.nRows ) * viewPortExtent.
height();
198 *blockExtent = blockRect;
201 block->reset( mInput->
block( bandNumber, blockRect, nCols, nRows, mFeedback ) );
202 topLeftCol = blockLeft;
203 topLeftRow = blockTop;
205 pInfo.currentCol = tileRight;
206 if ( pInfo.currentCol == pInfo.nCols && tileBottom == pInfo.nRows )
208 pInfo.currentRow = pInfo.nRows;
210 else if ( pInfo.currentCol == pInfo.nCols )
212 pInfo.currentCol = 0;
213 pInfo.currentRow = tileBottom;
221 removePartInfo( bandNumber );
224void QgsRasterIterator::removePartInfo(
int bandNumber )
226 const auto partIt = mRasterPartInfos.constFind( bandNumber );
227 if ( partIt != mRasterPartInfos.constEnd() )
229 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.
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
double height() const
Returns the height of the rectangle.
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)