Skip to content

Commit 82f6739

Browse files
committedJul 1, 2012
rasterprojector in pipe
1 parent 3f227c4 commit 82f6739

File tree

5 files changed

+126
-267
lines changed

5 files changed

+126
-267
lines changed
 

‎src/app/qgsrasterlayerproperties.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
241241
{
242242
mZoomedOutResamplingComboBox->setCurrentIndex( 0 );
243243
}
244-
mMaximumOversamplingSpinBox->setValue( renderer->maxOversampling() );
244+
mMaximumOversamplingSpinBox->setValue( resampleFilter->maxOversampling() );
245245
}
246246

247247
//transparency band

‎src/core/qgsrasterprojector.cpp

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,36 @@ QgsRasterProjector::QgsRasterProjector(
3737
QgsDebugMsg( "Entered" );
3838
QgsDebugMsg( "theDestExtent = " + theDestExtent.toString() );
3939

40+
calc();
41+
}
42+
43+
QgsRasterProjector::QgsRasterProjector(
44+
QgsCoordinateReferenceSystem theSrcCRS,
45+
QgsCoordinateReferenceSystem theDestCRS,
46+
double theMaxSrcXRes, double theMaxSrcYRes,
47+
QgsRectangle theExtent )
48+
: mSrcCRS( theSrcCRS )
49+
, mDestCRS( theDestCRS )
50+
, mCoordinateTransform( theDestCRS, theSrcCRS )
51+
, mExtent( theExtent )
52+
, mMaxSrcXRes( theMaxSrcXRes ), mMaxSrcYRes( theMaxSrcYRes )
53+
{
54+
QgsDebugMsg( "Entered" );
55+
}
56+
57+
QgsRasterProjector::~QgsRasterProjector()
58+
{
59+
//delete mCoordinateTransform;
60+
//delete pHelperTop;
61+
//delete pHelperBottom;
62+
}
63+
64+
void QgsRasterProjector::calc()
65+
{
66+
mCPMatrix.clear();
67+
//delete pHelperTop;
68+
//delete pHelperBottom;
69+
4070
mDestXRes = mDestExtent.width() / ( mDestCols );
4171
mDestYRes = mDestExtent.height() / ( mDestRows );
4272

@@ -110,11 +140,6 @@ QgsRasterProjector::QgsRasterProjector(
110140
mHelperTopRow = 0;
111141
}
112142

113-
QgsRasterProjector::~QgsRasterProjector()
114-
{
115-
//delete mCoordinateTransform;
116-
}
117-
118143
void QgsRasterProjector::calcSrcExtent()
119144
{
120145
/* Run around the mCPMatrix and find source extent */
@@ -508,3 +533,62 @@ bool QgsRasterProjector::checkRows()
508533
}
509534
return true;
510535
}
536+
537+
void * QgsRasterProjector::readBlock( int bandNo, QgsRectangle const & extent, int width, int height )
538+
{
539+
QgsDebugMsg( "Entered" );
540+
if ( !mInput ) return 0;
541+
542+
int bandNumber = 0;
543+
if ( ! mSrcCRS.isValid() || ! mDestCRS.isValid() || mSrcCRS == mDestCRS )
544+
{
545+
return mInput->readBlock( bandNumber, extent, width, height );
546+
}
547+
548+
mDestExtent = extent;
549+
mDestRows = height;
550+
mDestCols = width;
551+
calc();
552+
553+
QgsDebugMsg( QString( "srcExtent:\n%1" ).arg( srcExtent().toString() ) );
554+
QgsDebugMsg( QString( "srcCols = %1 srcRows = %1" ).arg( srcCols() ).arg( srcRows() ) );
555+
556+
// If we zoom out too much, projector srcRows / srcCols maybe 0, which can cause problems in providers
557+
if ( srcRows() <= 0 || srcCols() <= 0 )
558+
{
559+
return 0;
560+
}
561+
562+
void * inputData = mInput->readBlock( bandNumber, srcExtent(), srcCols(), srcRows() );
563+
564+
if ( !inputData ) return 0;
565+
566+
// ARGB32 only for now
567+
int pixelSize = 4;
568+
569+
int inputSize = pixelSize * srcCols() * srcRows();
570+
571+
int outputSize = width * height * pixelSize;
572+
void * outputData = malloc( outputSize );
573+
574+
// TODO: fill by transparent
575+
576+
int srcRow, srcCol;
577+
for ( int i = 0; i < height; ++i )
578+
{
579+
for ( int j = 0; j < width; ++j )
580+
{
581+
srcRowCol( i, j, &srcRow, &srcCol );
582+
int srcIndex = pixelSize * ( srcRow * mSrcCols + srcCol );
583+
int destIndex = pixelSize * ( i * width + j );
584+
585+
if ( srcIndex >= inputSize || destIndex >= outputSize ) continue; // should not happen
586+
587+
memcpy(( char* )outputData + destIndex, ( char* )inputData + srcIndex, pixelSize );
588+
}
589+
}
590+
591+
free( inputData );
592+
593+
return outputData;
594+
}

‎src/core/qgsrasterprojector.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@
3030
#include "qgsrectangle.h"
3131
#include "qgscoordinatereferencesystem.h"
3232
#include "qgscoordinatetransform.h"
33+
#include "qgsrasterface.h"
3334

3435
#include <cmath>
3536

3637
//class QgsRectangle;
3738
class QgsPoint;
3839

3940
//class CORE_EXPORT QgsRasterProjector
40-
class QgsRasterProjector
41+
class QgsRasterProjector : public QgsRasterFace
4142
{
4243
// Q_OBJECT
4344
public:
@@ -53,11 +54,16 @@ class QgsRasterProjector
5354
double theMaxSrcXRes, double theMaxSrcYRes,
5455
QgsRectangle theExtent
5556
);
57+
QgsRasterProjector(
58+
QgsCoordinateReferenceSystem theSrcCRS,
59+
QgsCoordinateReferenceSystem theDestCRS,
60+
double theMaxSrcXRes, double theMaxSrcYRes,
61+
QgsRectangle theExtent
62+
);
5663

5764
/** \brief The destructor */
5865
~QgsRasterProjector();
5966

60-
6167
/** \brief get destination point for _current_ destination position */
6268
void destPointOnCPMatrix( int theRow, int theCol, double *theX, double *theY );
6369

@@ -77,6 +83,9 @@ class QgsRasterProjector
7783
/** \brief Get source row and column indexes for current source extent and resolution */
7884
void srcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol );
7985

86+
/** \brief Calculate matrix */
87+
void calc();
88+
8089
/** \brief insert rows to matrix */
8190
void insertRows();
8291

@@ -128,6 +137,8 @@ class QgsRasterProjector
128137
int dstRows() const { return mDestRows; }
129138
int dstCols() const { return mDestCols; }
130139

140+
void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );
141+
131142
private:
132143
/** Source CRS */
133144
QgsCoordinateReferenceSystem mSrcCRS;

‎src/core/raster/qgsrasterlayer.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ email : tim at linfiniti.com
4040
#include "qgscolorrampshader.h"
4141

4242
//renderers
43-
//#include "qgspalettedrasterrenderer.h"
44-
//#include "qgsmultibandcolorrenderer.h"
45-
//#include "qgssinglebandcolordatarenderer.h"
46-
//#include "qgssinglebandpseudocolorrenderer.h"
43+
#include "qgspalettedrasterrenderer.h"
44+
#include "qgsmultibandcolorrenderer.h"
45+
#include "qgssinglebandcolordatarenderer.h"
46+
#include "qgssinglebandpseudocolorrenderer.h"
4747
#include "qgssinglebandgrayrenderer.h"
4848

49+
#include "qgsrasterprojector.h"
50+
4951
#include <cstdio>
5052
#include <cmath>
5153
#include <limits>
@@ -825,17 +827,24 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
825827

826828
if ( mRenderer )
827829
{
828-
//mRenderer->draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
829-
//if ( mResampleFilter )
830-
//{
831-
QgsRasterDrawer drawer( mResampleFilter );
830+
//QgsRasterDrawer drawer( mRenderer );
831+
//QgsRasterDrawer drawer( mResampleFilter );
832+
833+
double maxSrcXRes = 0;
834+
double maxSrcYRes = 0;
835+
836+
if ( mDataProvider->capabilities() & QgsRasterDataProvider::ExactResolution )
837+
{
838+
maxSrcXRes = mDataProvider->extent().width() / mDataProvider->xSize();
839+
maxSrcYRes = mDataProvider->extent().height() / mDataProvider->ySize();
840+
}
841+
842+
QgsRasterProjector projector( theRasterViewPort->mSrcCRS, theRasterViewPort->mDestCRS, maxSrcXRes, maxSrcYRes, mDataProvider->extent() );
843+
844+
projector.setInput( mResampleFilter );
845+
846+
QgsRasterDrawer drawer( &projector );
832847
drawer.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
833-
//}
834-
//else
835-
//{
836-
// QgsRasterDrawer drawer( mRenderer );
837-
// drawer.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
838-
//}
839848
}
840849

841850
QgsDebugMsg( QString( "raster draw time (ms): %1" ).arg( time.elapsed() ) );

‎src/core/raster/qgsrasterrenderer.cpp

Lines changed: 0 additions & 245 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include <QImage>
3232
#include <QPainter>
3333

34-
//QgsRasterRenderer::QgsRasterRenderer( QgsRasterFace* input, const QString& type ): mInput( input ),
3534
QgsRasterRenderer::QgsRasterRenderer( QgsRasterFace* input, const QString& type ): QgsRasterFace( input ),
3635
mType( type ), mZoomedInResampler( 0 ), mZoomedOutResampler( 0 ), mOpacity( 1.0 ), mRasterTransparency( 0 ),
3736
mAlphaBand( -1 ), mInvertColor( false ), mMaxOversampling( 2.0 )
@@ -42,167 +41,6 @@ QgsRasterRenderer::~QgsRasterRenderer()
4241
{
4342
}
4443

45-
/*
46-
void QgsRasterRenderer::startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double& oversamplingX, double& oversamplingY )
47-
{
48-
if ( !viewPort || !mapToPixel || !mInput )
49-
{
50-
return;
51-
}
52-
53-
//remove any previous part on that band
54-
removePartInfo( bandNumber );
55-
56-
//calculate oversampling factor
57-
double oversampling = 1.0; //approximate global oversampling factor
58-
59-
if ( mZoomedInResampler || mZoomedOutResampler )
60-
{
61-
QgsRectangle providerExtent = mInput->extent();
62-
if ( viewPort->mSrcCRS.isValid() && viewPort->mDestCRS.isValid() && viewPort->mSrcCRS != viewPort->mDestCRS )
63-
{
64-
QgsCoordinateTransform t( viewPort->mSrcCRS, viewPort->mDestCRS );
65-
providerExtent = t.transformBoundingBox( providerExtent );
66-
}
67-
double pixelRatio = mapToPixel->mapUnitsPerPixel() / ( providerExtent.width() / mInput->xSize() );
68-
oversampling = ( pixelRatio > mMaxOversampling ) ? mMaxOversampling : pixelRatio;
69-
}
70-
71-
//set oversampling back to 1.0 if no resampler for zoomed in / zoomed out (nearest neighbour)
72-
if (( oversampling < 1.0 && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) )
73-
{
74-
oversampling = 1.0;
75-
}
76-
77-
//split raster into small portions if necessary
78-
RasterPartInfo pInfo;
79-
pInfo.nCols = viewPort->drawableAreaXDim;
80-
pInfo.nRows = viewPort->drawableAreaYDim;
81-
82-
//effective oversampling factors are different to global one because of rounding
83-
oversamplingX = (( double )pInfo.nCols * oversampling ) / viewPort->drawableAreaXDim;
84-
oversamplingY = (( double )pInfo.nRows * oversampling ) / viewPort->drawableAreaYDim;
85-
86-
int totalMemoryUsage = pInfo.nCols * oversamplingX * pInfo.nRows * oversamplingY * mInput->dataTypeSize( bandNumber );
87-
int parts = totalMemoryUsage / 100000000 + 1;
88-
int nPartsPerDimension = sqrt(( double ) parts );
89-
pInfo.nColsPerPart = pInfo.nCols / nPartsPerDimension;
90-
pInfo.nRowsPerPart = pInfo.nRows / nPartsPerDimension;
91-
pInfo.currentCol = 0;
92-
pInfo.currentRow = 0;
93-
pInfo.data = 0;
94-
pInfo.prj = 0;
95-
mRasterPartInfos.insert( bandNumber, pInfo );
96-
}
97-
98-
bool QgsRasterRenderer::readNextRasterPart( int bandNumber, double oversamplingX, double oversamplingY, QgsRasterViewPort* viewPort,
99-
int& nCols, int& nRows, int& nColsRaster, int& nRowsRaster, void** rasterData, int& topLeftCol, int& topLeftRow )
100-
{
101-
if ( !viewPort )
102-
{
103-
return false;
104-
}
105-
106-
//get partinfo
107-
QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
108-
if ( partIt == mRasterPartInfos.end() )
109-
{
110-
return false;
111-
}
112-
113-
RasterPartInfo& pInfo = partIt.value();
114-
115-
//remove last data block
116-
CPLFree( pInfo.data );
117-
pInfo.data = 0;
118-
delete pInfo.prj;
119-
pInfo.prj = 0;
120-
121-
//already at end
122-
if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows )
123-
{
124-
return false;
125-
}
126-
127-
//read data block
128-
nCols = qMin( pInfo.nColsPerPart, pInfo.nCols - pInfo.currentCol );
129-
nRows = qMin( pInfo.nRowsPerPart, pInfo.nRows - pInfo.currentRow );
130-
int typeSize = mInput->dataTypeSize( bandNumber ) / 8;
131-
132-
//get subrectangle
133-
QgsRectangle viewPortExtent = viewPort->mDrawnExtent;
134-
double xmin = viewPortExtent.xMinimum() + pInfo.currentCol / ( double )pInfo.nCols * viewPortExtent.width();
135-
double xmax = viewPortExtent.xMinimum() + ( pInfo.currentCol + nCols ) / ( double )pInfo.nCols * viewPortExtent.width();
136-
double ymin = viewPortExtent.yMaximum() - ( pInfo.currentRow + nRows ) / ( double )pInfo.nRows * viewPortExtent.height();
137-
double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / ( double )pInfo.nRows * viewPortExtent.height();
138-
QgsRectangle blockRect( xmin, ymin, xmax, ymax );
139-
140-
if ( viewPort->mSrcCRS.isValid() && viewPort->mDestCRS.isValid() && viewPort->mSrcCRS != viewPort->mDestCRS )
141-
{
142-
pInfo.prj = new QgsRasterProjector( viewPort->mSrcCRS,
143-
viewPort->mDestCRS, blockRect, nRows, nCols, 0, 0, mInput->extent() );
144-
145-
// If we zoom out too much, projector srcRows / srcCols maybe 0, which can cause problems in providers
146-
if ( pInfo.prj->srcRows() <= 0 || pInfo.prj->srcCols() <= 0 )
147-
{
148-
delete pInfo.prj;
149-
pInfo.prj = 0;
150-
return false;
151-
}
152-
153-
blockRect = pInfo.prj->srcExtent();
154-
}
155-
156-
if ( pInfo.prj )
157-
{
158-
nColsRaster = pInfo.prj->srcCols() * oversamplingX;
159-
nRowsRaster = pInfo.prj->srcRows() * oversamplingY;
160-
}
161-
else
162-
{
163-
nColsRaster = nCols * oversamplingX;
164-
nRowsRaster = nRows * oversamplingY;
165-
}
166-
//pInfo.data = VSIMalloc( typeSize * nColsRaster * nRowsRaster );
167-
//mInput->readBlock( bandNumber, blockRect, nColsRaster, nRowsRaster, pInfo.data );
168-
pInfo.data = mInput->readBlock( bandNumber, blockRect, nColsRaster, nRowsRaster );
169-
170-
*rasterData = pInfo.data;
171-
topLeftCol = pInfo.currentCol;
172-
topLeftRow = pInfo.currentRow;
173-
174-
pInfo.currentCol += nCols;
175-
if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow + nRows == pInfo.nRows ) //end of raster
176-
{
177-
pInfo.currentRow = pInfo.nRows;
178-
}
179-
else if ( pInfo.currentCol == pInfo.nCols ) //start new row
180-
{
181-
pInfo.currentCol = 0;
182-
pInfo.currentRow += pInfo.nRowsPerPart;
183-
}
184-
185-
return true;
186-
}
187-
188-
void QgsRasterRenderer::stopRasterRead( int bandNumber )
189-
{
190-
removePartInfo( bandNumber );
191-
}
192-
193-
void QgsRasterRenderer::removePartInfo( int bandNumber )
194-
{
195-
QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber );
196-
if ( partIt != mRasterPartInfos.end() )
197-
{
198-
RasterPartInfo& pInfo = partIt.value();
199-
CPLFree( pInfo.data );
200-
delete pInfo.prj;
201-
mRasterPartInfos.remove( bandNumber );
202-
}
203-
}
204-
*/
205-
20644
bool QgsRasterRenderer::usesTransparency( QgsCoordinateReferenceSystem& srcSRS, QgsCoordinateReferenceSystem& dstSRS ) const
20745
{
20846
//transparency is always used if on-the-fly reprojection is enabled
@@ -220,89 +58,6 @@ void QgsRasterRenderer::setRasterTransparency( QgsRasterTransparency* t )
22058
mRasterTransparency = t;
22159
}
22260

223-
/*
224-
void QgsRasterRenderer::drawImage( QPainter* p, QgsRasterViewPort* viewPort, const QImage& img, int topLeftCol, int topLeftRow,
225-
int nCols, int nRows, double oversamplingX, double oversamplingY ) const
226-
{
227-
if ( !p || !viewPort )
228-
{
229-
return;
230-
}
231-
232-
//get QgsRasterProjector
233-
QgsRasterProjector* prj = 0;
234-
QMap<int, RasterPartInfo>::const_iterator partInfoIt = mRasterPartInfos.constBegin();
235-
if ( partInfoIt != mRasterPartInfos.constEnd() )
236-
{
237-
prj = partInfoIt->prj;
238-
}
239-
240-
//top left position in device coords
241-
QPoint tlPoint = QPoint( viewPort->topLeftPoint.x() + topLeftCol, viewPort->topLeftPoint.y() + topLeftRow );
242-
243-
//resample and draw image
244-
if (( mZoomedInResampler || mZoomedOutResampler ) && !doubleNear( oversamplingX, 1.0 ) && !doubleNear( oversamplingY, 1.0 ) )
245-
{
246-
QImage dstImg;
247-
if ( prj )
248-
{
249-
dstImg = QImage( prj->srcCols(), prj->srcRows(), QImage::Format_ARGB32_Premultiplied );
250-
}
251-
else
252-
{
253-
dstImg = QImage( nCols, nRows, QImage::Format_ARGB32_Premultiplied );
254-
}
255-
if ( mZoomedInResampler && oversamplingX < 1.0 )
256-
{
257-
mZoomedInResampler->resample( img, dstImg );
258-
}
259-
else if ( mZoomedOutResampler && oversamplingX > 1.0 )
260-
{
261-
mZoomedOutResampler->resample( img, dstImg );
262-
}
263-
264-
if ( prj )
265-
{
266-
QImage projectedImg( nCols, nRows, QImage::Format_ARGB32_Premultiplied );
267-
projectImage( dstImg, projectedImg, prj );
268-
p->drawImage( tlPoint, projectedImg );
269-
}
270-
else
271-
{
272-
p->drawImage( tlPoint, dstImg );
273-
}
274-
}
275-
else //use original image
276-
{
277-
if ( prj )
278-
{
279-
QImage projectedImg( nCols, nRows, QImage::Format_ARGB32_Premultiplied );
280-
projectImage( img, projectedImg, prj );
281-
p->drawImage( tlPoint, projectedImg );
282-
}
283-
else
284-
{
285-
p->drawImage( tlPoint, img );
286-
}
287-
}
288-
}
289-
290-
void QgsRasterRenderer::projectImage( const QImage& srcImg, QImage& dstImage, QgsRasterProjector* prj ) const
291-
{
292-
int nRows = dstImage.height();
293-
int nCols = dstImage.width();
294-
int srcRow, srcCol;
295-
for ( int i = 0; i < nRows; ++i )
296-
{
297-
for ( int j = 0; j < nCols; ++j )
298-
{
299-
prj->srcRowCol( i, j, &srcRow, &srcCol );
300-
dstImage.setPixel( j, i, srcImg.pixel( srcCol, srcRow ) );
301-
}
302-
}
303-
}
304-
*/
305-
30661
void QgsRasterRenderer::_writeXML( QDomDocument& doc, QDomElement& rasterRendererElem ) const
30762
{
30863
if ( rasterRendererElem.isNull() )

0 commit comments

Comments
 (0)
Please sign in to comment.