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