Skip to content

Commit

Permalink
Select resampling type from raster properties. Read and write resampl…
Browse files Browse the repository at this point in the history
…ing method to project file
  • Loading branch information
mhugent committed Dec 27, 2011
1 parent 4827820 commit 25f8ec5
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 32 deletions.
34 changes: 34 additions & 0 deletions src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -23,6 +23,8 @@
#include "qgslogger.h"
#include "qgsapplication.h"
#include "qgisapp.h"
#include "qgsbilinearrasterresampler.h"
#include "qgscubicrasterresampler.h"
#include "qgscoordinatetransform.h"
#include "qgsrasterlayerproperties.h"
#include "qgsgenericprojectionselector.h"
Expand Down Expand Up @@ -284,6 +286,22 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
}
tableTransparency->horizontalHeader()->setResizeMode( 0, QHeaderView::Stretch );
tableTransparency->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );

//resampling
const QgsRasterResampler* resampler = mRasterLayer->resampler();
if ( !resampler )
{
mNearestNeighbourRadioButton->setChecked( true );
}
else if ( resampler->type() == "bilinear" )
{
mBilinearRadioButton->setChecked( true );
}
else if ( resampler->type() == "cubic" )
{
mCubicRadioButton->setChecked( true );
}

} // QgsRasterLayerProperties ctor


Expand Down Expand Up @@ -1444,6 +1462,22 @@ void QgsRasterLayerProperties::apply()
pixmapLegend->setScaledContents( true );
pixmapLegend->repaint();

//resampling
if ( mNearestNeighbourRadioButton->isChecked() )
{
mRasterLayer->setResampler( 0 );
}
else if ( mBilinearRadioButton->isChecked() )
{
mRasterLayer->setResampler( new QgsBilinearRasterResampler() );
}
else if ( mCubicRadioButton->isChecked() )
{
mRasterLayer->setResampler( new QgsCubicRasterResampler() );
}



//get the thumbnail for the layer
QPixmap myQPixmap = QPixmap( pixmapThumbnail->width(), pixmapThumbnail->height() );
mRasterLayer->thumbnailAsPixmap( &myQPixmap );
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgsbilinearrasterresampler.h
Expand Up @@ -28,6 +28,7 @@ class QgsBilinearRasterResampler: public QgsRasterResampler
~QgsBilinearRasterResampler();

void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "bilinear"; }

private:
QRgb resampleColorValue( double u, double v, QRgb col1, QRgb col2, QRgb col3, QRgb col4 ) const;
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgscubicrasterresampler.h
Expand Up @@ -26,6 +26,7 @@ class QgsCubicRasterResampler: public QgsRasterResampler
QgsCubicRasterResampler();
~QgsCubicRasterResampler();
void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "cubic"; }

private:
static void xDerivativeMatrix( int nCols, int nRows, double* matrix, const int* colorMatrix );
Expand Down
52 changes: 46 additions & 6 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -100,6 +100,8 @@ QgsRasterLayer::QgsRasterLayer(
, mWidth( std::numeric_limits<int>::max() )
, mHeight( std::numeric_limits<int>::max() )
, mInvertColor( false )
, mResampler( 0 )
, mRenderer( 0 )
{
QgsDebugMsg( "Entered" );

Expand Down Expand Up @@ -185,6 +187,8 @@ QgsRasterLayer::~QgsRasterLayer()
mValid = false;
delete mRasterShader;
delete mDataProvider;
delete mResampler;
delete mRenderer;
}

//////////////////////////////////////////////////////////
Expand Down Expand Up @@ -849,9 +853,7 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
colorArray[( int )colorIt->value] = colorIt->color;
}

//QgsBilinearRasterResampler resampler;
QgsCubicRasterResampler resampler;
QgsPalettedRasterRenderer renderer( mDataProvider, bNumber, colorArray, itemList.size(), 0 /*&resampler*/ );
QgsPalettedRasterRenderer renderer( mDataProvider, bNumber, colorArray, itemList.size(), mResampler );
renderer.setOpacity( mTransparencyLevel / 255.0 );
renderer.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
#if 0
Expand Down Expand Up @@ -943,9 +945,7 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
int red = bandNumber( mRedBandName );
int green = bandNumber( mGreenBandName );
int blue = bandNumber( mBlueBandName );
//QgsBilinearRasterResampler resampler;
QgsCubicRasterResampler resampler;
QgsMultiBandColorRenderer r( mDataProvider, red, green, blue, &resampler );
QgsMultiBandColorRenderer r( mDataProvider, red, green, blue, mResampler );
r.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
#if 0
drawMultiBandColor( theQPainter, theRasterViewPort,
Expand Down Expand Up @@ -2854,6 +2854,18 @@ void QgsRasterLayer::setTransparentBandName( QString const & theBandName )
mTransparencyBandName = validateBandName( theBandName );
}

void QgsRasterLayer::setResampler( QgsRasterResampler* resampler )
{
delete mResampler;
mResampler = resampler;
}

void QgsRasterLayer::setRenderer( QgsRasterRenderer* renderer )
{
delete mRenderer;
mRenderer = renderer;
}

void QgsRasterLayer::showProgress( int theValue )
{
emit progressUpdate( theValue );
Expand Down Expand Up @@ -2989,6 +3001,27 @@ bool QgsRasterLayer::readSymbology( const QDomNode& layer_node, QString& errorMe
{
Q_UNUSED( errorMessage );
QDomNode mnl = layer_node.namedItem( "rasterproperties" );

//resampler
QDomElement resamplerElem = mnl.firstChildElement( "resampler" );
if ( !resamplerElem.isNull() )
{
delete mResampler;
QString rText = resamplerElem.text();
if ( rText == "bilinear" )
{
mResampler = new QgsBilinearRasterResampler();
}
else if ( rText == "cubic" )
{
mResampler = new QgsCubicRasterResampler();
}
else //nearest neighbour
{
mResampler = 0;
}
}

QDomNode snode = mnl.namedItem( "mDrawingStyle" );
QDomElement myElement = snode.toElement();
setDrawingStyle( myElement.text() );
Expand Down Expand Up @@ -3306,6 +3339,13 @@ bool QgsRasterLayer::writeSymbology( QDomNode & layer_node, QDomDocument & docum
QDomElement rasterPropertiesElement = document.createElement( "rasterproperties" );
layer_node.appendChild( rasterPropertiesElement );

// resampler
QString resamplerName = mResampler ? mResampler->type() : "nearest neighbour";
QDomElement resamplerElem = document.createElement( "resampler" );
QDomText resamplerText = document.createTextNode( resamplerName );
resamplerElem.appendChild( resamplerText );
rasterPropertiesElement.appendChild( resamplerElem );

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

Expand Down
19 changes: 16 additions & 3 deletions src/core/raster/qgsrasterlayer.h
Expand Up @@ -50,6 +50,8 @@ class QgsMapToPixel;
class QgsRectangle;
class QgsRasterBandStats;
class QgsRasterPyramid;
class QgsRasterRenderer;
class QgsRasterResampler;
class QImage;
class QPixmap;
class QSlider;
Expand Down Expand Up @@ -391,13 +393,21 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
/** \brief Mutator for mUserDefinedRGBMinimumMaximum */
void setUserDefinedRGBMinimumMaximum( bool theBool ) { mUserDefinedRGBMinimumMaximum = theBool; }

/** Set raster resampler. Uses nearest neighbour resampling per default. Takes ownership of the resampler object*/
void setResampler( QgsRasterResampler* resampler );
const QgsRasterResampler* resampler() const { return mResampler; }

/**Set raster renderer. Takes ownership of the renderer object*/
void setRenderer( QgsRasterRenderer* renderer );
const QgsRasterRenderer* renderer() const { return mRenderer; }

/** \brief Accessor to find out how many standard deviations are being plotted */
double standardDeviations() const { return mStandardDeviations; }

/** \brief Accessor for transparent band name mapping */
QString transparentBandName() const { return mTransparencyBandName; }

/** \brief [ data provider interface ] Does this layer use a provider for setting/retrieving data?
/** \brief [ data provider interface ] Does this layer use a provider for setting/retrieving data?
* @deprecated in 2.0
*/
Q_DECL_DEPRECATED bool usesProvider();
Expand Down Expand Up @@ -548,12 +558,12 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
/** \brief Get an 100x100 pixmap of the color palette. If the layer has no palette a white pixmap will be returned */
QPixmap paletteAsPixmap( int theBandNumber = 1 );

/** \brief [ data provider interface ] Which provider is being used for this Raster Layer?
/** \brief [ data provider interface ] Which provider is being used for this Raster Layer?
* @note added in 2.0
*/
QString providerType() const;

/** \brief [ data provider interface ] Which provider is being used for this Raster Layer?
/** \brief [ data provider interface ] Which provider is being used for this Raster Layer?
* @deprecated use providerType()
*/
Q_DECL_DEPRECATED QString providerKey() const { return providerType(); }
Expand Down Expand Up @@ -926,6 +936,9 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
QStringList mStyles;
QString mFormat;
QString mCrs;

QgsRasterResampler* mResampler;
QgsRasterRenderer* mRenderer;
};

/*#include <QColor>
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterrenderer.cpp
Expand Up @@ -63,7 +63,7 @@ void QgsRasterRenderer::startRasterRead( int bandNumber, QgsRasterViewPort* view
pInfo.nCols = viewPort->drawableAreaXDim * oversampling;
pInfo.nRows = viewPort->drawableAreaYDim * oversampling;
int totalMemoryUsage = pInfo.nCols * pInfo.nRows * mProvider->dataTypeSize( bandNumber );
int parts = totalMemoryUsage / /*100000000*/ 100000 + 1;
int parts = totalMemoryUsage / 100000000 + 1;
pInfo.nPartsPerDimension = sqrt( parts );
pInfo.nColsPerPart = pInfo.nCols / pInfo.nPartsPerDimension;
pInfo.nRowsPerPart = pInfo.nRows / pInfo.nPartsPerDimension;
Expand Down
3 changes: 3 additions & 0 deletions src/core/raster/qgsrasterresampler.h
Expand Up @@ -18,13 +18,16 @@
#ifndef QGSRASTERRESAMPLER_H
#define QGSRASTERRESAMPLER_H

#include <QString>

class QImage;

/**Interface for resampling rasters (e.g. to have a smoother appearance)*/
class QgsRasterResampler
{
public:
virtual void resample( const QImage& srcImage, QImage& dstImage ) = 0;
virtual QString type() const = 0;
};

#endif // QGSRASTERRESAMPLER_H

0 comments on commit 25f8ec5

Please sign in to comment.