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