QGIS API Documentation  2.99.0-Master (0cba29c)
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  , mFeedback( nullptr )
24  , mMaximumTileWidth( DEFAULT_MAXIMUM_TILE_WIDTH )
25  , mMaximumTileHeight( DEFAULT_MAXIMUM_TILE_HEIGHT )
26 {
27  for ( QgsRasterInterface *ri = input; ri; ri = ri->input() )
28  {
29  QgsRasterDataProvider *rdp = dynamic_cast<QgsRasterDataProvider *>( ri );
30  if ( rdp )
31  {
32  mMaximumTileWidth = rdp->stepWidth();
33  mMaximumTileHeight = rdp->stepHeight();
34  break;
35  }
36  }
37 }
38 
39 void QgsRasterIterator::startRasterRead( int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback )
40 {
41  if ( !mInput )
42  {
43  return;
44  }
45 
46  mExtent = extent;
47  mFeedback = feedback;
48 
49  //remove any previous part on that band
50  removePartInfo( bandNumber );
51 
52  //split raster into small portions if necessary
53  RasterPartInfo pInfo;
54  pInfo.nCols = nCols;
55  pInfo.nRows = nRows;
56  pInfo.currentCol = 0;
57  pInfo.currentRow = 0;
58  pInfo.prj = nullptr;
59  mRasterPartInfos.insert( bandNumber, pInfo );
60 }
61 
63  int &nCols, int &nRows,
64  QgsRasterBlock **block,
65  int &topLeftCol, int &topLeftRow )
66 {
67  QgsDebugMsgLevel( "Entered", 4 );
68  *block = nullptr;
69  //get partinfo
70  QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
71  if ( partIt == mRasterPartInfos.end() )
72  {
73  return false;
74  }
75 
76  RasterPartInfo &pInfo = partIt.value();
77 
78  // If we started with zero cols or zero rows, just return (avoids divide by zero below)
79  if ( 0 == pInfo.nCols || 0 == pInfo.nRows )
80  {
81  return false;
82  }
83 
84  //remove last data block
85  delete pInfo.prj;
86  pInfo.prj = nullptr;
87 
88  //already at end
89  if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
90  {
91  return false;
92  }
93 
94  //read data block
95  nCols = qMin( mMaximumTileWidth, pInfo.nCols - pInfo.currentCol );
96  nRows = qMin( mMaximumTileHeight, pInfo.nRows - pInfo.currentRow );
97  QgsDebugMsgLevel( QString( "nCols = %1 nRows = %2" ).arg( nCols ).arg( nRows ), 4 );
98 
99  //get subrectangle
100  QgsRectangle viewPortExtent = mExtent;
101  double xmin = viewPortExtent.xMinimum() + pInfo.currentCol / static_cast< double >( pInfo.nCols ) * viewPortExtent.width();
102  double xmax = pInfo.currentCol + nCols == pInfo.nCols ? viewPortExtent.xMaximum() : // avoid extra FP math if not necessary
103  viewPortExtent.xMinimum() + ( pInfo.currentCol + nCols ) / static_cast< double >( pInfo.nCols ) * viewPortExtent.width();
104  double ymin = pInfo.currentRow + nRows == pInfo.nRows ? viewPortExtent.yMinimum() : // avoid extra FP math if not necessary
105  viewPortExtent.yMaximum() - ( pInfo.currentRow + nRows ) / static_cast< double >( pInfo.nRows ) * viewPortExtent.height();
106  double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / static_cast< double >( pInfo.nRows ) * viewPortExtent.height();
107  QgsRectangle blockRect( xmin, ymin, xmax, ymax );
108 
109  *block = mInput->block( bandNumber, blockRect, nCols, nRows, mFeedback );
110  topLeftCol = pInfo.currentCol;
111  topLeftRow = pInfo.currentRow;
112 
113  pInfo.currentCol += nCols;
114  if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow + nRows == pInfo.nRows ) //end of raster
115  {
116  pInfo.currentRow = pInfo.nRows;
117  }
118  else if ( pInfo.currentCol == pInfo.nCols ) //start new row
119  {
120  pInfo.currentCol = 0;
121  pInfo.currentRow += nRows;
122  }
123 
124  return true;
125 }
126 
127 void QgsRasterIterator::stopRasterRead( int bandNumber )
128 {
129  removePartInfo( bandNumber );
130 }
131 
132 void QgsRasterIterator::removePartInfo( int bandNumber )
133 {
134  QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
135  if ( partIt != mRasterPartInfos.end() )
136  {
137  RasterPartInfo &pInfo = partIt.value();
138  delete pInfo.prj;
139  mRasterPartInfos.remove( bandNumber );
140  }
141 }
A rectangle specified with double values.
Definition: qgsrectangle.h:38
QgsRasterIterator(QgsRasterInterface *input)
virtual QgsRasterInterface * input() const
Current input.
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:38
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.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:118
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...
Base class for processing filters like renderers, reprojector, resampler etc.
void stopRasterRead(int bandNumber)
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:106
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:91
virtual int stepHeight() const
Step height for raster iterations.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:96
virtual int stepWidth() const
Step width for raster iterations.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:101
Feedback object tailored for raster block reading.
void startRasterRead(int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:125
Base class for raster data providers.