Skip to content
Permalink
Browse files

pseudocolor renderer GUI min/max support

  • Loading branch information
blazek committed Oct 5, 2012
1 parent b331d45 commit d9c5a68d8028f3b8cdde502ed3e0f8496d7d3d52
@@ -20,5 +20,5 @@ class QgsSingleBandGrayRendererWidget: QgsRasterRendererWidget
int selectedBand( int index = 0 );

public slots:
void loadMinMax( int theBandNo, double theMin, double theMax );
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
};
@@ -26,11 +26,14 @@
#include "qgsbilinearrasterresampler.h"
#include "qgscubicrasterresampler.h"

#include <QCoreApplication>
#include <QDomDocument>
#include <QDomElement>
#include <QImage>
#include <QPainter>

#define tr( sourceText ) QCoreApplication::translate ( "QgsRasterRenderer", sourceText )

QgsRasterRenderer::QgsRasterRenderer( QgsRasterInterface* input, const QString& type )
: QgsRasterInterface( input )
, mType( type ), mOpacity( 1.0 ), mRasterTransparency( 0 )
@@ -140,3 +143,146 @@ void QgsRasterRenderer::readXML( const QDomElement& rendererElem )
mRasterTransparency->readXML( rasterTransparencyElem );
}
}

QString QgsRasterRenderer::minMaxOriginName( int theOrigin )
{
if ( theOrigin == MinMaxUnknown )
{
return "Unknown";
}
else if ( theOrigin == MinMaxUser )
{
return "User";
}

QString name;
if ( theOrigin & MinMaxMinMax )
{
name += "MinMax";
}
else if ( theOrigin & MinMaxCumulativeCut )
{
name += "CumulativeCut";
}
else if ( theOrigin & MinMaxStdDev )
{
name += "StdDev";
}

if ( theOrigin & MinMaxFullExtent )
{
name += "FullExtent";
}
else if ( theOrigin & MinMaxSubExtent )
{
name += "SubExtent";
}

if ( theOrigin & MinMaxEstimated )
{
name += "Estimated";
}
else if ( theOrigin & MinMaxExact )
{
name += "Exact";
}
return name;
}

QString QgsRasterRenderer::minMaxOriginLabel( int theOrigin )
{
if ( theOrigin == MinMaxUnknown )
{
return tr( "Unknown" );
}
else if ( theOrigin == MinMaxUser )
{
return tr( "User defined" );
}

QString name;
if ( theOrigin & MinMaxEstimated )
{
name += tr( "Estimated" );
}
else if ( theOrigin & MinMaxExact )
{
name += tr( "Exact" );
}

name += " ";

if ( theOrigin & MinMaxMinMax )
{
name += tr( "min / max" );
}
else if ( theOrigin & MinMaxCumulativeCut )
{
name += "cumulative cut";
}
else if ( theOrigin & MinMaxStdDev )
{
name += "standard deviation";
}

name += " " + tr( " of " ) + " ";

if ( theOrigin & MinMaxFullExtent )
{
name += "full extent";
}
else if ( theOrigin & MinMaxSubExtent )
{
name += "sub extent";
}

name += ".";

return name;
}

int QgsRasterRenderer::minMaxOriginFromName( QString theName )
{
if ( theName.contains( "Unknown" ) )
{
return MinMaxUnknown;
}
else if ( theName.contains( "User" ) )
{
return MinMaxUser;
}

int origin = 0;

if ( theName.contains( "MinMax" ) )
{
origin |= MinMaxMinMax;
}
else if ( theName.contains( "CumulativeCut" ) )
{
origin |= MinMaxCumulativeCut;
}
else if ( theName.contains( "StdDev" ) )
{
origin |= MinMaxStdDev;
}

if ( theName.contains( "FullExtent" ) )
{
origin |= MinMaxFullExtent;
}
else if ( theName.contains( "SubExtent" ) )
{
origin |= MinMaxSubExtent;
}

if ( theName.contains( "Estimated" ) )
{
origin |= MinMaxEstimated;
}
else if ( theName.contains( "Exact" ) )
{
origin |= MinMaxExact;
}
return origin;
}
@@ -39,6 +39,23 @@ class QDomElement;
class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
{
public:
// Origin of min / max values
enum MinMaxOrigin
{
MinMaxUnknown = 0,
MinMaxUser = 1, // entered by user
// method
MinMaxMinMax = 1 << 1,
MinMaxCumulativeCut = 1 << 2,
MinMaxStdDev = 1 << 3,
// Extent
MinMaxFullExtent = 1 << 4,
MinMaxSubExtent = 1 << 5,
// Precision
MinMaxEstimated = 1 << 6,
MinMaxExact = 1 << 7
};

QgsRasterRenderer( QgsRasterInterface* input = 0, const QString& type = "" );
virtual ~QgsRasterRenderer();

@@ -82,6 +99,10 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
/**Returns a list of band numbers used by the renderer*/
virtual QList<int> usesBands() const { return QList<int>(); }

static QString minMaxOriginName( int theOrigin );
static QString minMaxOriginLabel( int theOrigin );
static int minMaxOriginFromName( QString theName );

protected:

/**Write upper class info into rasterrenderer element (called by writeXML method of subclasses)*/
@@ -24,7 +24,12 @@
#include <QImage>

QgsSingleBandPseudoColorRenderer::QgsSingleBandPseudoColorRenderer( QgsRasterInterface* input, int band, QgsRasterShader* shader ):
QgsRasterRenderer( input, "singlebandpseudocolor" ), mShader( shader ), mBand( band )
QgsRasterRenderer( input, "singlebandpseudocolor" )
, mShader( shader )
, mBand( band )
, mClassificationMin( std::numeric_limits<double>::quiet_NaN() )
, mClassificationMax( std::numeric_limits<double>::quiet_NaN() )
, mClassificationMinMaxOrigin( QgsRasterRenderer::MinMaxUnknown )
{
}

@@ -85,8 +90,16 @@ QgsRasterRenderer* QgsSingleBandPseudoColorRenderer::create( const QDomElement&
shader = new QgsRasterShader();
shader->readXML( rasterShaderElem );
}
QgsRasterRenderer* r = new QgsSingleBandPseudoColorRenderer( input, band, shader );

//QgsRasterRenderer* r = new QgsSingleBandPseudoColorRenderer( input, band, shader );
QgsSingleBandPseudoColorRenderer* r = new QgsSingleBandPseudoColorRenderer( input, band, shader );
r->readXML( elem );

// TODO: add _readXML in superclass?
r->setClassificationMin( elem.attribute( "classificationMin", "NaN" ).toDouble() );
r->setClassificationMax( elem.attribute( "classificationMax", "NaN" ).toDouble() );
r->setClassificationMinMaxOrigin( QgsRasterRenderer::minMaxOriginFromName( elem.attribute( "classificationMinMaxOrigin", "Unknown" ) ) );

return r;
}

@@ -210,6 +223,10 @@ void QgsSingleBandPseudoColorRenderer::writeXML( QDomDocument& doc, QDomElement&
{
mShader->writeXML( doc, rasterRendererElem ); //todo: include color ramp items directly in this renderer
}
rasterRendererElem.setAttribute( "classificationMin", QString::number( mClassificationMin ) );
rasterRendererElem.setAttribute( "classificationMax", QString::number( mClassificationMax ) );
rasterRendererElem.setAttribute( "classificationMinMaxOrigin", QgsRasterRenderer::minMaxOriginName( mClassificationMinMaxOrigin ) );

parentElem.appendChild( rasterRendererElem );
}

@@ -49,9 +49,23 @@ class CORE_EXPORT QgsSingleBandPseudoColorRenderer: public QgsRasterRenderer

QList<int> usesBands() const;

double classificationMin() const { return mClassificationMin; }
double classificationMax() const { return mClassificationMax; }
void setClassificationMin( double min ) { mClassificationMin = min; }
void setClassificationMax( double max ) { mClassificationMax = max; }
int classificationMinMaxOrigin() const { return mClassificationMinMaxOrigin; }
void setClassificationMinMaxOrigin( int origin ) { mClassificationMinMaxOrigin = origin; }

private:
QgsRasterShader* mShader;
int mBand;

// Minimum and maximum values used for automatic classification, these
// values are not used by renderer in rendering process
double mClassificationMin;
double mClassificationMax;

int mClassificationMinMaxOrigin;
};

#endif // QGSSINGLEBANDPSEUDOCOLORRENDERER_H
@@ -44,6 +44,7 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()

foreach ( int myBand, mBands )
{
int origin = QgsRasterRenderer::MinMaxUnknown;
QgsDebugMsg( QString( "myBand = %1" ).arg( myBand ) );
if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
{
@@ -56,37 +57,49 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
if ( mCurrentExtentRadioButton->isChecked() )
{
myExtent = mExtent; // current
origin |= QgsRasterRenderer::MinMaxSubExtent;
}
else
{
origin |= QgsRasterRenderer::MinMaxFullExtent;
}
QgsDebugMsg( QString( "myExtent.isEmpty() = %1" ).arg( myExtent.isEmpty() ) );

int mySampleSize = 0; // 0 == exact
if ( mEstimateRadioButton->isChecked() )
{
mySampleSize = 250000;
origin |= QgsRasterRenderer::MinMaxEstimated;
}
else
{
origin |= QgsRasterRenderer::MinMaxExact;
}

if ( mCumulativeCutRadioButton->isChecked() )
{
double myLower = mCumulativeCutLowerDoubleSpinBox->value() / 100.0;
double myUpper = mCumulativeCutUpperDoubleSpinBox->value() / 100.0;
mLayer->dataProvider()->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, myExtent, mySampleSize );
origin |= QgsRasterRenderer::MinMaxCumulativeCut;
}
else if ( mMinMaxRadioButton->isChecked() )
{
// TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, myExtent, mySampleSize );
myMin = myRasterBandStats.minimumValue;
myMax = myRasterBandStats.maximumValue;
origin |= QgsRasterRenderer::MinMaxMinMax;
}
else if ( mStdDevRadioButton->isChecked() )
{
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, myExtent, mySampleSize );
double myStdDev = mStdDevSpinBox->value();
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );

origin |= QgsRasterRenderer::MinMaxStdDev;
}

emit load( myBand, myMin, myMax );
emit load( myBand, myMin, myMax, origin );
}
}
@@ -34,7 +34,7 @@ class GUI_EXPORT QgsRasterMinMaxWidget: public QWidget, private Ui::QgsRasterMin
void setBands( const QList<int> & theBands ) { mBands = theBands; }

signals:
void load( int theBandNo, double theMin, double theMax );
void load( int theBandNo, double theMin, double theMax, int origin );

private slots:
void on_mLoadPushButton_clicked();
@@ -87,8 +87,9 @@ QgsRasterRenderer* QgsSingleBandGrayRendererWidget::renderer()
return renderer;
}

void QgsSingleBandGrayRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax )
void QgsSingleBandGrayRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
{
Q_UNUSED( theOrigin );
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );

if ( qIsNaN( theMin ) )
@@ -42,7 +42,7 @@ class GUI_EXPORT QgsSingleBandGrayRendererWidget: public QgsRasterRendererWidget
int selectedBand( int index = 0 ) { Q_UNUSED( index ); return mGrayBandComboBox->currentIndex() + 1; }

public slots:
void loadMinMax( int theBandNo, double theMin, double theMax );
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );

private slots:
void on_mGrayBandComboBox_currentIndexChanged( int index );

0 comments on commit d9c5a68

Please sign in to comment.
You can’t perform that action at this time.