Skip to content

Commit 3f1056a

Browse files
committedJul 7, 2012
Added class QgsRasterIterator
1 parent 2b53f49 commit 3f1056a

File tree

3 files changed

+184
-0
lines changed

3 files changed

+184
-0
lines changed
 

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ SET(QGIS_CORE_SRCS
161161
raster/qgslinearminmaxenhancementwithclip.cpp
162162
raster/qgspseudocolorshader.cpp
163163
raster/qgsrasterinterface.cpp
164+
raster/qgsrasteriterator.cpp
164165
raster/qgsrasterlayer.cpp
165166
raster/qgsrastertransparency.cpp
166167
raster/qgsrasterpipe.cpp

‎src/core/raster/qgsrasteriterator.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#include "qgsrasteriterator.h"
2+
#include "qgsrasterinterface.h"
3+
#include "qgsrasterprojector.h"
4+
#include "qgsrasterviewport.h"
5+
6+
QgsRasterIterator::QgsRasterIterator( QgsRasterInterface* input ): mInput( input )
7+
{
8+
}
9+
10+
QgsRasterIterator::~QgsRasterIterator()
11+
{
12+
}
13+
14+
void QgsRasterIterator::startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel )
15+
{
16+
if ( !viewPort || !mapToPixel || !mInput )
17+
{
18+
return;
19+
}
20+
21+
//remove any previous part on that band
22+
removePartInfo( bandNumber );
23+
24+
//split raster into small portions if necessary
25+
RasterPartInfo pInfo;
26+
pInfo.nCols = viewPort->drawableAreaXDim;
27+
pInfo.nRows = viewPort->drawableAreaYDim;
28+
29+
//effective oversampling factors are different to global one because of rounding
30+
//oversamplingX = (( double )pInfo.nCols * oversampling ) / viewPort->drawableAreaXDim;
31+
//oversamplingY = (( double )pInfo.nRows * oversampling ) / viewPort->drawableAreaYDim;
32+
33+
// TODO : we dont know oversampling (grid size) here - how to get totalMemoryUsage ?
34+
//int totalMemoryUsage = pInfo.nCols * oversamplingX * pInfo.nRows * oversamplingY * mInput->dataTypeSize( bandNumber );
35+
int totalMemoryUsage = pInfo.nCols * pInfo.nRows * mInput->dataTypeSize( bandNumber );
36+
int parts = totalMemoryUsage / 100000000 + 1;
37+
int nPartsPerDimension = sqrt( parts );
38+
pInfo.nColsPerPart = pInfo.nCols / nPartsPerDimension;
39+
pInfo.nRowsPerPart = pInfo.nRows / nPartsPerDimension;
40+
pInfo.currentCol = 0;
41+
pInfo.currentRow = 0;
42+
pInfo.data = 0;
43+
pInfo.prj = 0;
44+
mRasterPartInfos.insert( bandNumber, pInfo );
45+
}
46+
47+
bool QgsRasterIterator::readNextRasterPart( int bandNumber, QgsRasterViewPort* viewPort,
48+
int& nCols, int& nRows,
49+
void** rasterData,
50+
int& topLeftCol, int& topLeftRow )
51+
{
52+
if ( !viewPort )
53+
{
54+
return false;
55+
}
56+
57+
//get partinfo
58+
QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
59+
if ( partIt == mRasterPartInfos.end() )
60+
{
61+
return false;
62+
}
63+
64+
RasterPartInfo& pInfo = partIt.value();
65+
66+
//remove last data block
67+
// TODO: data are released somewhere else (check)
68+
//free( pInfo.data );
69+
pInfo.data = 0;
70+
delete pInfo.prj;
71+
pInfo.prj = 0;
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( pInfo.nColsPerPart, pInfo.nCols - pInfo.currentCol );
81+
nRows = qMin( pInfo.nRowsPerPart, pInfo.nRows - pInfo.currentRow );
82+
83+
//get subrectangle
84+
QgsRectangle viewPortExtent = viewPort->mDrawnExtent;
85+
double xmin = viewPortExtent.xMinimum() + pInfo.currentCol / ( double )pInfo.nCols * viewPortExtent.width();
86+
double xmax = viewPortExtent.xMinimum() + ( pInfo.currentCol + nCols ) / ( double )pInfo.nCols * viewPortExtent.width();
87+
double ymin = viewPortExtent.yMaximum() - ( pInfo.currentRow + nRows ) / ( double )pInfo.nRows * viewPortExtent.height();
88+
double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / ( double )pInfo.nRows * viewPortExtent.height();
89+
QgsRectangle blockRect( xmin, ymin, xmax, ymax );
90+
91+
pInfo.data = mInput->block( bandNumber, blockRect, nCols, nRows );
92+
93+
*rasterData = pInfo.data;
94+
topLeftCol = pInfo.currentCol;
95+
topLeftRow = pInfo.currentRow;
96+
97+
pInfo.currentCol += nCols;
98+
if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow + nRows == pInfo.nRows ) //end of raster
99+
{
100+
pInfo.currentRow = pInfo.nRows;
101+
}
102+
else if ( pInfo.currentCol == pInfo.nCols ) //start new row
103+
{
104+
pInfo.currentCol = 0;
105+
pInfo.currentRow += pInfo.nRowsPerPart;
106+
}
107+
108+
return true;
109+
}
110+
111+
void QgsRasterIterator::stopRasterRead( int bandNumber )
112+
{
113+
removePartInfo( bandNumber );
114+
}
115+
116+
void QgsRasterIterator::removePartInfo( int bandNumber )
117+
{
118+
QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
119+
if ( partIt != mRasterPartInfos.end() )
120+
{
121+
RasterPartInfo& pInfo = partIt.value();
122+
//CPLFree( pInfo.data );
123+
free( pInfo.data );
124+
delete pInfo.prj;
125+
mRasterPartInfos.remove( bandNumber );
126+
}
127+
}

‎src/core/raster/qgsrasteriterator.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#ifndef QGSRASTERITERATOR_H
2+
#define QGSRASTERITERATOR_H
3+
4+
#include <QMap>
5+
6+
class QgsMapToPixel;
7+
class QgsRasterInterface;
8+
class QgsRasterProjector;
9+
class QgsRasterViewPort;
10+
11+
class QgsRasterIterator
12+
{
13+
public:
14+
//Stores information about reading of a raster band. Columns and rows are in unsampled coordinates
15+
struct RasterPartInfo
16+
{
17+
int currentCol;
18+
int currentRow;
19+
int nCols;
20+
int nRows;
21+
int nColsPerPart;
22+
int nRowsPerPart;
23+
void* data; //data (can be in oversampled/undersampled resolution)
24+
QgsRasterProjector* prj; //raster projector (or 0 if no reprojection is done)
25+
};
26+
27+
QgsRasterIterator( QgsRasterInterface* input );
28+
~QgsRasterIterator();
29+
30+
/**Start reading of raster band. Raster data can then be retrieved by calling readNextRasterPart until it returns false.
31+
@param bandNumer number of raster band to read
32+
@param viewPort describes raster position on screen
33+
*/
34+
void startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel );
35+
36+
/**Fetches next part of raster data
37+
@param nCols number of columns on output device
38+
@param nRows number of rows on output device
39+
@param nColsRaster number of raster columns (different to nCols if oversamplingX != 1.0)
40+
@param nRowsRaster number of raster rows (different to nRows if oversamplingY != 0)*/
41+
bool readNextRasterPart( int bandNumber, QgsRasterViewPort* viewPort,
42+
int& nCols, int& nRows,
43+
void** rasterData,
44+
int& topLeftCol, int& topLeftRow );
45+
46+
void stopRasterRead( int bandNumber );
47+
48+
private:
49+
QgsRasterInterface* mInput;
50+
QMap<int, RasterPartInfo> mRasterPartInfos;
51+
52+
/**Remove part into and release memory*/
53+
void removePartInfo( int bandNumber );
54+
};
55+
56+
#endif // QGSRASTERITERATOR_H

0 commit comments

Comments
 (0)
Please sign in to comment.