QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsrasteriterator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasteriterator.cpp
3  ---------------------
4  begin : July 2012
5  copyright : (C) 2012 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include "qgsrasteriterator.h"
16 #include "qgsrasterinterface.h"
17 #include "qgsrasterprojector.h"
18 #include "qgsrasterviewport.h"
19 #include "qgsrasterdataprovider.h"
20 
22  : mInput( input )
23  , mMaximumTileWidth( DEFAULT_MAXIMUM_TILE_WIDTH )
24  , mMaximumTileHeight( DEFAULT_MAXIMUM_TILE_HEIGHT )
25 {
26  for ( QgsRasterInterface *ri = input; ri; ri = ri->input() )
27  {
28  QgsRasterDataProvider *rdp = dynamic_cast<QgsRasterDataProvider *>( ri );
29  if ( rdp )
30  {
31  mMaximumTileWidth = rdp->stepWidth();
32  mMaximumTileHeight = rdp->stepHeight();
33  break;
34  }
35  }
36 }
37 
38 void QgsRasterIterator::startRasterRead( int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback )
39 {
40  if ( !mInput )
41  {
42  return;
43  }
44 
45  mExtent = extent;
46  mFeedback = feedback;
47 
48  //remove any previous part on that band
49  removePartInfo( bandNumber );
50 
51  //split raster into small portions if necessary
52  RasterPartInfo pInfo;
53  pInfo.nCols = nCols;
54  pInfo.nRows = nRows;
55  pInfo.currentCol = 0;
56  pInfo.currentRow = 0;
57  mRasterPartInfos.insert( bandNumber, pInfo );
58 }
59 
60 bool QgsRasterIterator::next( int bandNumber, int &columns, int &rows, int &topLeftColumn, int &topLeftRow, QgsRectangle &blockExtent )
61 {
62  return readNextRasterPartInternal( bandNumber, columns, rows, nullptr, topLeftColumn, topLeftRow, &blockExtent );
63 }
64 
66  int &nCols, int &nRows,
67  QgsRasterBlock **block,
68  int &topLeftCol, int &topLeftRow )
69 {
70  *block = nullptr;
71  std::unique_ptr< QgsRasterBlock > nextBlock;
72  bool result = readNextRasterPart( bandNumber, nCols, nRows, nextBlock, topLeftCol, topLeftRow );
73  if ( result )
74  *block = nextBlock.release();
75  return result;
76 }
77 
78 bool QgsRasterIterator::readNextRasterPart( int bandNumber, int &nCols, int &nRows, std::unique_ptr<QgsRasterBlock> &block, int &topLeftCol, int &topLeftRow, QgsRectangle *blockExtent )
79 {
80  return readNextRasterPartInternal( bandNumber, nCols, nRows, &block, topLeftCol, topLeftRow, blockExtent );
81 }
82 
83 bool QgsRasterIterator::readNextRasterPartInternal( int bandNumber, int &nCols, int &nRows, std::unique_ptr<QgsRasterBlock> *block, int &topLeftCol, int &topLeftRow, QgsRectangle *blockExtent )
84 {
85  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
86  if ( block )
87  block->reset();
88  //get partinfo
89  QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
90  if ( partIt == mRasterPartInfos.end() )
91  {
92  return false;
93  }
94 
95  RasterPartInfo &pInfo = partIt.value();
96 
97  // If we started with zero cols or zero rows, just return (avoids divide by zero below)
98  if ( 0 == pInfo.nCols || 0 == pInfo.nRows )
99  {
100  return false;
101  }
102 
103  //remove last data block
104 
105  //already at end
106  if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
107  {
108  return false;
109  }
110 
111  //read data block
112  nCols = static_cast< int >( std::min( static_cast< qgssize >( mMaximumTileWidth ), pInfo.nCols - pInfo.currentCol ) );
113  nRows = static_cast< int >( std::min( static_cast< qgssize >( mMaximumTileHeight ), pInfo.nRows - pInfo.currentRow ) );
114  QgsDebugMsgLevel( QStringLiteral( "nCols = %1 nRows = %2" ).arg( nCols ).arg( nRows ), 4 );
115 
116  //get subrectangle
117  QgsRectangle viewPortExtent = mExtent;
118  double xmin = viewPortExtent.xMinimum() + pInfo.currentCol / static_cast< double >( pInfo.nCols ) * viewPortExtent.width();
119  double xmax = pInfo.currentCol + nCols == pInfo.nCols ? viewPortExtent.xMaximum() : // avoid extra FP math if not necessary
120  viewPortExtent.xMinimum() + ( pInfo.currentCol + nCols ) / static_cast< double >( pInfo.nCols ) * viewPortExtent.width();
121  double ymin = pInfo.currentRow + nRows == pInfo.nRows ? viewPortExtent.yMinimum() : // avoid extra FP math if not necessary
122  viewPortExtent.yMaximum() - ( pInfo.currentRow + nRows ) / static_cast< double >( pInfo.nRows ) * viewPortExtent.height();
123  double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / static_cast< double >( pInfo.nRows ) * viewPortExtent.height();
124  QgsRectangle blockRect( xmin, ymin, xmax, ymax );
125 
126  if ( blockExtent )
127  *blockExtent = blockRect;
128 
129  if ( block )
130  block->reset( mInput->block( bandNumber, blockRect, nCols, nRows, mFeedback ) );
131  topLeftCol = pInfo.currentCol;
132  topLeftRow = pInfo.currentRow;
133 
134  pInfo.currentCol += nCols;
135  if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow + nRows == pInfo.nRows ) //end of raster
136  {
137  pInfo.currentRow = pInfo.nRows;
138  }
139  else if ( pInfo.currentCol == pInfo.nCols ) //start new row
140  {
141  pInfo.currentCol = 0;
142  pInfo.currentRow += nRows;
143  }
144 
145  return true;
146 }
147 
148 void QgsRasterIterator::stopRasterRead( int bandNumber )
149 {
150  removePartInfo( bandNumber );
151 }
152 
153 void QgsRasterIterator::removePartInfo( int bandNumber )
154 {
155  auto partIt = mRasterPartInfos.constFind( bandNumber );
156  if ( partIt != mRasterPartInfos.constEnd() )
157  {
158  mRasterPartInfos.remove( bandNumber );
159  }
160 }
qgsrasterprojector.h
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
qgsrasterviewport.h
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsRasterIterator::QgsRasterIterator
QgsRasterIterator(QgsRasterInterface *input)
Constructor for QgsRasterIterator, iterating over the specified input raster source.
Definition: qgsrasteriterator.cpp:21
QgsRasterIterator::next
bool next(int bandNumber, int &columns, int &rows, int &topLeftColumn, int &topLeftRow, QgsRectangle &blockExtent)
Fetches details of the next part of the raster data.
Definition: qgsrasteriterator.cpp:60
qgsrasteriterator.h
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
qgsrasterinterface.h
QgsRasterDataProvider::stepHeight
virtual int stepHeight() const
Step height for raster iterations.
Definition: qgsrasterdataprovider.h:543
QgsRasterIterator::startRasterRead
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
Definition: qgsrasteriterator.cpp:38
QgsRasterDataProvider::stepWidth
virtual int stepWidth() const
Step width for raster iterations.
Definition: qgsrasterdataprovider.h:536
QgsRasterIterator::input
const QgsRasterInterface * input() const
Returns the input raster interface which is being iterated over.
Definition: qgsrasteriterator.h:117
QgsRasterIterator::stopRasterRead
void stopRasterRead(int bandNumber)
Cancels the raster iteration and resets the iterator.
Definition: qgsrasteriterator.cpp:148
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsRasterIterator::readNextRasterPart
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...
Definition: qgsrasteriterator.cpp:65
QgsRasterInterface
Base class for processing filters like renderers, reprojector, resampler etc.
Definition: qgsrasterinterface.h:117
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
QgsRasterInterface::input
virtual QgsRasterInterface * input() const
Current input.
Definition: qgsrasterinterface.h:269
QgsRasterBlockFeedback
Feedback object tailored for raster block reading.
Definition: qgsrasterinterface.h:41
QgsRasterInterface::block
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.
QgsRasterDataProvider
Base class for raster data providers.
Definition: qgsrasterdataprovider.h:89
QgsRasterBlock
Raster data container.
Definition: qgsrasterblock.h:37
qgsrasterdataprovider.h
qgssize
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...
Definition: qgis.h:768