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