Skip to content

Commit 6641652

Browse files
committed
Possibility to set resampling modes differently for zoomed-in and zoomed-out
1 parent 2883fbc commit 6641652

16 files changed

+156
-87
lines changed

src/app/qgsrasterlayerproperties.cpp

+68-26
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "qgscubicrasterresampler.h"
2828
#include "qgscoordinatetransform.h"
2929
#include "qgsrasterlayerproperties.h"
30+
#include "qgsrasterrenderer.h"
3031
#include "qgsgenericprojectionselector.h"
3132
#include "qgsproject.h"
3233
#include "qgsrasterbandstats.h"
@@ -288,20 +289,45 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
288289
tableTransparency->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
289290

290291
//resampling
291-
const QgsRasterResampler* resampler = mRasterLayer->resampler();
292-
if ( !resampler )
292+
const QgsRasterRenderer* renderer = mRasterLayer->renderer();
293+
mZoomedInResamplingComboBox->insertItem( 0, tr( "Nearest neighbour" ) );
294+
mZoomedInResamplingComboBox->insertItem( 1, tr( "Bilinear" ) );
295+
mZoomedInResamplingComboBox->insertItem( 2, tr( "Cubic" ) );
296+
mZoomedOutResamplingComboBox->insertItem( 0, tr( "Nearest neighbour" ) );
297+
mZoomedOutResamplingComboBox->insertItem( 1, tr( "Average" ) );
298+
//set combo boxes to current resampling types
299+
if ( renderer )
293300
{
294-
mNearestNeighbourRadioButton->setChecked( true );
295-
}
296-
else if ( resampler->type() == "bilinear" )
297-
{
298-
mBilinearRadioButton->setChecked( true );
299-
}
300-
else if ( resampler->type() == "cubic" )
301-
{
302-
mCubicRadioButton->setChecked( true );
303-
}
301+
const QgsRasterResampler* zoomedInResampler = renderer->zoomedInResampler();
302+
if ( zoomedInResampler )
303+
{
304+
if ( zoomedInResampler->type() == "bilinear" )
305+
{
306+
mZoomedInResamplingComboBox->setCurrentIndex( 1 );
307+
}
308+
else if ( zoomedInResampler->type() == "cubic" )
309+
{
310+
mZoomedInResamplingComboBox->setCurrentIndex( 2 );
311+
}
312+
}
313+
else
314+
{
315+
mZoomedInResamplingComboBox->setCurrentIndex( 0 );
316+
}
304317

318+
const QgsRasterResampler* zoomedOutResampler = renderer->zoomedOutResampler();
319+
if ( zoomedOutResampler )
320+
{
321+
if ( zoomedOutResampler->type() == "bilinear" ) //bilinear resampler does averaging when zooming out
322+
{
323+
mZoomedOutResamplingComboBox->setCurrentIndex( 1 );
324+
}
325+
}
326+
else
327+
{
328+
mZoomedOutResamplingComboBox->setCurrentIndex( 0 );
329+
}
330+
}
305331
} // QgsRasterLayerProperties ctor
306332

307333

@@ -1370,20 +1396,6 @@ void QgsRasterLayerProperties::apply()
13701396
pixmapLegend->setScaledContents( true );
13711397
pixmapLegend->repaint();
13721398

1373-
//resampling
1374-
if ( mNearestNeighbourRadioButton->isChecked() )
1375-
{
1376-
mRasterLayer->setResampler( 0 );
1377-
}
1378-
else if ( mBilinearRadioButton->isChecked() )
1379-
{
1380-
mRasterLayer->setResampler( new QgsBilinearRasterResampler() );
1381-
}
1382-
else if ( mCubicRadioButton->isChecked() )
1383-
{
1384-
mRasterLayer->setResampler( new QgsCubicRasterResampler() );
1385-
}
1386-
13871399
//set the appropriate render style
13881400
if ( rbtnSingleBand->isChecked() )
13891401
{
@@ -1478,6 +1490,36 @@ void QgsRasterLayerProperties::apply()
14781490
//set render style finished
14791491

14801492

1493+
//resampling
1494+
QgsRasterRenderer* rasterRenderer = mRasterLayer->renderer();
1495+
QgsRasterResampler* zoomedInResampler = 0;
1496+
QString zoomedInResamplingMethod = mZoomedInResamplingComboBox->currentText();
1497+
if ( zoomedInResamplingMethod == tr( "Bilinear" ) )
1498+
{
1499+
zoomedInResampler = new QgsBilinearRasterResampler();
1500+
}
1501+
else if ( zoomedInResamplingMethod == tr( "Cubic" ) )
1502+
{
1503+
zoomedInResampler = new QgsCubicRasterResampler();
1504+
}
1505+
1506+
if ( rasterRenderer )
1507+
{
1508+
rasterRenderer->setZoomedInResampler( zoomedInResampler );
1509+
}
1510+
1511+
QgsRasterResampler* zoomedOutResampler = 0;
1512+
QString zoomedOutResamplingMethod = mZoomedOutResamplingComboBox->currentText();
1513+
if ( zoomedOutResamplingMethod == tr( "Average" ) )
1514+
{
1515+
zoomedOutResampler = new QgsBilinearRasterResampler();
1516+
}
1517+
1518+
if ( rasterRenderer )
1519+
{
1520+
rasterRenderer->setZoomedOutResampler( zoomedOutResampler );
1521+
}
1522+
14811523

14821524
//get the thumbnail for the layer
14831525
QPixmap myQPixmap = QPixmap( pixmapThumbnail->width(), pixmapThumbnail->height() );

src/core/raster/qgsmultibandcolorrenderer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#include <QImage>
2121
#include <QSet>
2222

23-
QgsMultiBandColorRenderer::QgsMultiBandColorRenderer( QgsRasterDataProvider* provider, int redBand, int greenBand, int blueBand, QgsRasterResampler* resampler ):
24-
QgsRasterRenderer( provider, resampler ), mRedBand( redBand ), mGreenBand( greenBand ), mBlueBand( blueBand ), mContrastEnhancement( 0 )
23+
QgsMultiBandColorRenderer::QgsMultiBandColorRenderer( QgsRasterDataProvider* provider, int redBand, int greenBand, int blueBand ):
24+
QgsRasterRenderer( provider ), mRedBand( redBand ), mGreenBand( greenBand ), mBlueBand( blueBand ), mContrastEnhancement( 0 )
2525
{
2626
}
2727

src/core/raster/qgsmultibandcolorrenderer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class QgsContrastEnhancement;
2626
class QgsMultiBandColorRenderer: public QgsRasterRenderer
2727
{
2828
public:
29-
QgsMultiBandColorRenderer( QgsRasterDataProvider* provider, int redBand, int greenBand, int blueBand, QgsRasterResampler* resampler = 0 );
29+
QgsMultiBandColorRenderer( QgsRasterDataProvider* provider, int redBand, int greenBand, int blueBand );
3030
~QgsMultiBandColorRenderer();
3131

3232
void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel );

src/core/raster/qgspalettedrasterrenderer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
#include <QImage>
2323

2424
QgsPalettedRasterRenderer::QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber,
25-
QColor* colorArray, int nColors, QgsRasterResampler* resampler ):
26-
QgsRasterRenderer( provider, resampler ), mBandNumber( bandNumber ), mColors( colorArray ), mNColors( nColors )
25+
QColor* colorArray, int nColors ):
26+
QgsRasterRenderer( provider ), mBandNumber( bandNumber ), mColors( colorArray ), mNColors( nColors )
2727
{
2828
}
2929

src/core/raster/qgspalettedrasterrenderer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class QgsPalettedRasterRenderer: public QgsRasterRenderer
2626
{
2727
public:
2828
/**Renderer owns color array*/
29-
QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber, QColor* colorArray, int nColors, QgsRasterResampler* resampler = 0 );
29+
QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber, QColor* colorArray, int nColors );
3030
~QgsPalettedRasterRenderer();
3131
void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel );
3232

src/core/raster/qgsrasterlayer.cpp

+9-17
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ email : tim at linfiniti.com
3838

3939
//renderers
4040
#include "qgspalettedrasterrenderer.h"
41-
#include "qgsbilinearrasterresampler.h"
42-
#include "qgscubicrasterresampler.h"
4341
#include "qgsmultibandcolorrenderer.h"
4442
#include "qgssinglebandcolordatarenderer.h"
4543
#include "qgssinglebandpseudocolorrenderer.h"
@@ -103,7 +101,6 @@ QgsRasterLayer::QgsRasterLayer(
103101
, mWidth( std::numeric_limits<int>::max() )
104102
, mHeight( std::numeric_limits<int>::max() )
105103
, mInvertColor( false )
106-
, mResampler( 0 )
107104
, mRenderer( 0 )
108105
{
109106
QgsDebugMsg( "Entered" );
@@ -153,7 +150,6 @@ QgsRasterLayer::QgsRasterLayer( int dummy,
153150
, mStyles( styles )
154151
, mFormat( format )
155152
, mCrs( crs )
156-
, mResampler( 0 )
157153
, mRenderer( 0 )
158154
{
159155
Q_UNUSED( dummy );
@@ -192,7 +188,6 @@ QgsRasterLayer::~QgsRasterLayer()
192188
mValid = false;
193189
delete mRasterShader;
194190
delete mDataProvider;
195-
delete mResampler;
196191
delete mRenderer;
197192
}
198193

@@ -610,15 +605,14 @@ void QgsRasterLayer::setRendererForDrawingStyle( const DrawingStyle & theDrawin
610605
renderer = new QgsPalettedRasterRenderer( mDataProvider,
611606
grayBand,
612607
colorArray,
613-
itemList.size(),
614-
mResampler );
608+
itemList.size() );
615609
break;
616610
}
617611
case MultiBandSingleBandGray:
618612
case SingleBandGray:
619613
{
620614
int grayBand = bandNumber( mGrayBandName );
621-
renderer = new QgsSingleBandGrayRenderer( mDataProvider, grayBand, mResampler );
615+
renderer = new QgsSingleBandGrayRenderer( mDataProvider, grayBand );
622616
if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedGrayMinimumMaximum && mStandardDeviations > 0 )
623617
{
624618
mGrayMinimumMaximumEstimated = false;
@@ -656,20 +650,20 @@ void QgsRasterLayer::setRendererForDrawingStyle( const DrawingStyle & theDrawin
656650
mRasterShader->setMinimumValue( myMinimumValue );
657651
mRasterShader->setMaximumValue( myMaximumValue );
658652

659-
renderer = new QgsSingleBandPseudoColorRenderer( mDataProvider, bandNo, mRasterShader, mResampler );
653+
renderer = new QgsSingleBandPseudoColorRenderer( mDataProvider, bandNo, mRasterShader );
660654
break;
661655
}
662656
case MultiBandColor:
663657
{
664658
int red = bandNumber( mRedBandName );
665659
int green = bandNumber( mGreenBandName );
666660
int blue = bandNumber( mBlueBandName );
667-
renderer = new QgsMultiBandColorRenderer( mDataProvider, red, green, blue, mResampler );
661+
renderer = new QgsMultiBandColorRenderer( mDataProvider, red, green, blue );
668662
break;
669663
}
670664
case SingleBandColorDataStyle:
671665
{
672-
renderer = new QgsSingleBandColorDataRenderer( mDataProvider, bandNumber( mGrayBandName ), mResampler );
666+
renderer = new QgsSingleBandColorDataRenderer( mDataProvider, bandNumber( mGrayBandName ) );
673667
break;
674668
}
675669
default:
@@ -2802,12 +2796,6 @@ void QgsRasterLayer::setTransparentBandName( QString const & theBandName )
28022796
mTransparencyBandName = validateBandName( theBandName );
28032797
}
28042798

2805-
void QgsRasterLayer::setResampler( QgsRasterResampler* resampler )
2806-
{
2807-
delete mResampler;
2808-
mResampler = resampler;
2809-
}
2810-
28112799
void QgsRasterLayer::setRenderer( QgsRasterRenderer* renderer )
28122800
{
28132801
delete mRenderer;
@@ -2950,6 +2938,7 @@ bool QgsRasterLayer::readSymbology( const QDomNode& layer_node, QString& errorMe
29502938
Q_UNUSED( errorMessage );
29512939
QDomNode mnl = layer_node.namedItem( "rasterproperties" );
29522940

2941+
#if 0
29532942
//resampler
29542943
QDomElement resamplerElem = mnl.firstChildElement( "resampler" );
29552944
if ( !resamplerElem.isNull() )
@@ -2969,6 +2958,7 @@ bool QgsRasterLayer::readSymbology( const QDomNode& layer_node, QString& errorMe
29692958
mResampler = 0;
29702959
}
29712960
}
2961+
#endif //0
29722962

29732963
QDomNode snode = mnl.namedItem( "mDrawingStyle" );
29742964
QDomElement myElement = snode.toElement();
@@ -3287,12 +3277,14 @@ bool QgsRasterLayer::writeSymbology( QDomNode & layer_node, QDomDocument & docum
32873277
QDomElement rasterPropertiesElement = document.createElement( "rasterproperties" );
32883278
layer_node.appendChild( rasterPropertiesElement );
32893279

3280+
#if 0
32903281
// resampler
32913282
QString resamplerName = mResampler ? mResampler->type() : "nearest neighbour";
32923283
QDomElement resamplerElem = document.createElement( "resampler" );
32933284
QDomText resamplerText = document.createTextNode( resamplerName );
32943285
resamplerElem.appendChild( resamplerText );
32953286
rasterPropertiesElement.appendChild( resamplerElem );
3287+
#endif //0
32963288

32973289
QStringList sl = subLayers();
32983290
QStringList sls = mDataProvider->subLayerStyles();

src/core/raster/qgsrasterlayer.h

+1-7
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ class QgsRectangle;
5151
class QgsRasterBandStats;
5252
class QgsRasterPyramid;
5353
class QgsRasterRenderer;
54-
class QgsRasterResampler;
5554
class QImage;
5655
class QPixmap;
5756
class QSlider;
@@ -393,14 +392,10 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
393392
/** \brief Mutator for mUserDefinedRGBMinimumMaximum */
394393
void setUserDefinedRGBMinimumMaximum( bool theBool ) { mUserDefinedRGBMinimumMaximum = theBool; }
395394

396-
/** Set raster resampler. Uses nearest neighbour resampling per default. Takes ownership of the resampler object*/
397-
void setResampler( QgsRasterResampler* resampler );
398-
QgsRasterResampler* resampler() { return mResampler; }
399-
const QgsRasterResampler* resampler() const { return mResampler; }
400-
401395
/**Set raster renderer. Takes ownership of the renderer object*/
402396
void setRenderer( QgsRasterRenderer* renderer );
403397
const QgsRasterRenderer* renderer() const { return mRenderer; }
398+
QgsRasterRenderer* renderer() { return mRenderer; }
404399

405400
/** \brief Accessor to find out how many standard deviations are being plotted */
406401
double standardDeviations() const { return mStandardDeviations; }
@@ -940,7 +935,6 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
940935
QString mFormat;
941936
QString mCrs;
942937

943-
QgsRasterResampler* mResampler;
944938
QgsRasterRenderer* mRenderer;
945939
};
946940

src/core/raster/qgsrasterrenderer.cpp

+36-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <QImage>
2424
#include <QPainter>
2525

26-
QgsRasterRenderer::QgsRasterRenderer( QgsRasterDataProvider* provider, QgsRasterResampler* resampler ): mProvider( provider ), mResampler( resampler ),
26+
QgsRasterRenderer::QgsRasterRenderer( QgsRasterDataProvider* provider ): mProvider( provider ), mZoomedInResampler( 0 ), mZoomedOutResampler( 0 ),
2727
mOpacity( 1.0 ), mRasterTransparency( 0 ), mAlphaBand( -1 ), mInvertColor( false )
2828
{
2929
}
@@ -36,6 +36,21 @@ QgsRasterRenderer::~QgsRasterRenderer()
3636
{
3737
CPLFree( partIt.value().data );
3838
}
39+
40+
delete mZoomedInResampler;
41+
delete mZoomedOutResampler;
42+
}
43+
44+
void QgsRasterRenderer::setZoomedInResampler( QgsRasterResampler* r )
45+
{
46+
delete mZoomedInResampler;
47+
mZoomedInResampler = r;
48+
}
49+
50+
void QgsRasterRenderer::setZoomedOutResampler( QgsRasterResampler* r )
51+
{
52+
delete mZoomedOutResampler;
53+
mZoomedOutResampler = r;
3954
}
4055

4156
void QgsRasterRenderer::startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double& oversamplingX, double& oversamplingY )
@@ -50,7 +65,8 @@ void QgsRasterRenderer::startRasterRead( int bandNumber, QgsRasterViewPort* view
5065

5166
//calculate oversampling factor
5267
double oversampling = 1.0; //approximate global oversampling factor
53-
if ( mResampler )
68+
69+
if ( mZoomedInResampler || mZoomedOutResampler )
5470
{
5571
QgsRectangle providerExtent = mProvider->extent();
5672
if ( viewPort->mSrcCRS.isValid() && viewPort->mDestCRS.isValid() && viewPort->mSrcCRS != viewPort->mDestCRS )
@@ -62,6 +78,12 @@ void QgsRasterRenderer::startRasterRead( int bandNumber, QgsRasterViewPort* view
6278
oversampling = ( pixelRatio > 4.0 ) ? 4.0 : pixelRatio;
6379
}
6480

81+
//set oversampling back to 1.0 if no resampler for zoomed in / zoomed out (nearest neighbour)
82+
if (( oversampling < 1.0 && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) )
83+
{
84+
oversampling = 1.0;
85+
}
86+
6587
//split raster into small portions if necessary
6688
RasterPartInfo pInfo;
6789
pInfo.nCols = viewPort->drawableAreaXDim * oversampling;
@@ -178,13 +200,21 @@ void QgsRasterRenderer::drawImage( QPainter* p, QgsRasterViewPort* viewPort, con
178200

179201
//top left position in device coords
180202
QPointF tlPoint = QPointF( viewPort->topLeftPoint.x(), viewPort->topLeftPoint.y() );
181-
tlPoint += QPointF( topLeftCol / oversamplingX, topLeftRow / oversamplingY );
182203

183-
//draw image
184-
if ( mResampler && !( doubleNear( oversamplingX, 1.0 ) && doubleNear( oversamplingY, 1.0 ) ) ) //resampling with factor 1.0 not useful
204+
//resample and draw image
205+
if (( mZoomedInResampler || mZoomedOutResampler ) && !doubleNear( oversamplingX, 1.0 ) && !doubleNear( oversamplingY, 1.0 ) )
185206
{
186207
QImage dstImg( nCols / oversamplingX + 1.0, nRows / oversamplingY + 1.0, QImage::Format_ARGB32_Premultiplied );
187-
mResampler->resample( img, dstImg );
208+
if ( mZoomedInResampler && oversamplingX < 1.0 )
209+
{
210+
mZoomedInResampler->resample( img, dstImg );
211+
}
212+
else if ( mZoomedOutResampler && oversamplingX > 1.0 )
213+
{
214+
mZoomedOutResampler->resample( img, dstImg );
215+
}
216+
217+
tlPoint += QPointF( topLeftCol / oversamplingX, topLeftRow / oversamplingY );
188218
p->drawImage( tlPoint, dstImg );
189219
}
190220
else //use original image

0 commit comments

Comments
 (0)