mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Merge pull request #3871 from rouault/auto_stretch
[FEATURE] Implement raster auto-stretching when updating canvas
This commit is contained in:
commit
792873af5c
@ -1313,6 +1313,14 @@ QgsProject {#qgis_api_break_3_0_QgsProject}
|
||||
- clearProperties() was removed. Use clear() instead.
|
||||
|
||||
|
||||
QgsRaster {#qgis_api_break_3_0_QgsRaster}
|
||||
---------
|
||||
|
||||
- QgsRaster::ContrastEnhancementLimits has been removed, use QgsRasterMinMaxOrigin::Limits
|
||||
- QgsRaster::contrastEnhancementLimitsAsString() has been removed, use QgsRasterMinMaxOrigin::limitsString()
|
||||
- QgsRaster::contrastEnhancementLimitsFromString() has been removed, use QgsRasterMinMaxOrigin::limitsFromString()
|
||||
|
||||
|
||||
QgsRasterCalcNode {#qgis_api_break_3_0_QgsRasterCalcNode}
|
||||
-----------------
|
||||
|
||||
@ -1343,13 +1351,18 @@ QgsRasterLayer {#qgis_api_break_3_0_QgsRasterLayer}
|
||||
- setDrawingStyle() was removed. Use setRendererForDrawingStyle() or setRenderer() instead.
|
||||
- previewAsPixmap() was removed. Use previewAsImage() instead.
|
||||
- updateProgress() had no effect and was removed.
|
||||
|
||||
- CUMULATIVE_CUT_LOWER and CUMULATIVE_CUT_UPPER have been moved to QgsRasterMinMaxOrigin
|
||||
- the second parameter of setContrastEnhancement() has changed type. It is now QgsRasterMinMaxOrigin::Limits
|
||||
|
||||
QgsRasterProjector {#qgis_api_break_3_0_QgsRasterProjector}
|
||||
------------------
|
||||
|
||||
- extentSize() now takes a QgsCoordinateTransform reference, not a pointer. An invalid QgsCoordinateTransform should be used instead of a null pointer if no transformation is required.
|
||||
|
||||
QgsRasterRenderer
|
||||
-----------------
|
||||
|
||||
- MinMaxOrigin enum, minMaxOriginName(), minMaxOriginLabel(), minMaxOriginFromName() removed. Use minMaxOrigin() instead
|
||||
|
||||
QgsRelation {#qgis_api_break_3_0_QgsRelation}
|
||||
-----------
|
||||
@ -1430,6 +1443,12 @@ QgsSimpleMarkerSymbolLayerWidget {#qgis_api_break_3_0_QgsSimpleMarkerSymb
|
||||
- setName() was removed.
|
||||
|
||||
|
||||
QgsSingleBandPseudoColorRenderer {#qgis_api_break_3_0_QgsSingleBandPseudoColorRenderer}
|
||||
--------------------------------
|
||||
|
||||
- classificationMinMaxOrigin() and setClassificationMinMaxOrigin() removed. Use minMaxOrigin() and setMinMaxOrigin()
|
||||
|
||||
|
||||
QgsSingleSymbolRendererWidget {#qgis_api_break_3_0_QgsSingleSymbolRendererWidget}
|
||||
-----------------------------
|
||||
|
||||
|
@ -274,6 +274,7 @@
|
||||
%Include raster/qgsrasterinterface.sip
|
||||
%Include raster/qgsrasteriterator.sip
|
||||
%Include raster/qgsrasterlayer.sip
|
||||
%Include raster/qgsrasterminmaxorigin.sip
|
||||
%Include raster/qgsrasternuller.sip
|
||||
%Include raster/qgsrasterpipe.sip
|
||||
%Include raster/qgsrasterprojector.sip
|
||||
|
@ -62,14 +62,6 @@ class QgsRaster
|
||||
PyramidsErdas,
|
||||
};
|
||||
|
||||
/** \brief Contrast enhancement limits */
|
||||
enum ContrastEnhancementLimits
|
||||
{
|
||||
ContrastEnhancementNone,
|
||||
ContrastEnhancementMinMax,
|
||||
ContrastEnhancementStdDev,
|
||||
ContrastEnhancementCumulativeCut
|
||||
};
|
||||
|
||||
/** \brief This enumerator describes the different kinds of drawing we can do */
|
||||
enum DrawingStyle
|
||||
@ -87,9 +79,6 @@ class QgsRaster
|
||||
SingleBandColorDataStyle // ARGB values rendered directly
|
||||
};
|
||||
|
||||
static QString contrastEnhancementLimitsAsString( QgsRaster::ContrastEnhancementLimits theLimits );
|
||||
static ContrastEnhancementLimits contrastEnhancementLimitsFromString( const QString& theLimits );
|
||||
|
||||
/** Get value representable by given data type.
|
||||
* Supported are numerical types Byte, UInt16, Int16, UInt32, Int32, Float32, Float64.
|
||||
* @param value
|
||||
|
@ -10,11 +10,6 @@ class QgsRasterLayer : QgsMapLayer
|
||||
%End
|
||||
|
||||
public:
|
||||
/** \brief Default cumulative cut lower limit */
|
||||
static const double CUMULATIVE_CUT_LOWER;
|
||||
|
||||
/** \brief Default cumulative cut upper limit */
|
||||
static const double CUMULATIVE_CUT_UPPER;
|
||||
|
||||
/** \brief Default sample size (number of pixels) for estimated statistics/histogram calculation */
|
||||
static const double SAMPLE_SIZE;
|
||||
@ -165,7 +160,7 @@ class QgsRasterLayer : QgsMapLayer
|
||||
|
||||
|
||||
void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
|
||||
QgsRaster::ContrastEnhancementLimits theLimits = QgsRaster::ContrastEnhancementMinMax,
|
||||
QgsRasterMinMaxOrigin::Limits theLimits = QgsRasterMinMaxOrigin::MinMax,
|
||||
const QgsRectangle& theExtent = QgsRectangle(),
|
||||
int theSampleSize = QgsRasterLayer::SAMPLE_SIZE,
|
||||
bool theGenerateLookupTableFlag = true );
|
||||
|
127
python/core/raster/qgsrasterminmaxorigin.sip
Normal file
127
python/core/raster/qgsrasterminmaxorigin.sip
Normal file
@ -0,0 +1,127 @@
|
||||
/** \class QgsRasterMinMaxOrigin
|
||||
* This class describes the origin of min/max values. It does not store by
|
||||
* itself the min/max values.
|
||||
*/
|
||||
|
||||
class QgsRasterMinMaxOrigin
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsrasterminmaxorigin.h>
|
||||
%End
|
||||
public:
|
||||
//! \brief Default cumulative cut lower limit
|
||||
static const double CUMULATIVE_CUT_LOWER;
|
||||
|
||||
//! \brief Default cumulative cut upper limit
|
||||
static const double CUMULATIVE_CUT_UPPER;
|
||||
|
||||
//! \brief Default standard deviation factor
|
||||
static const double DEFAULT_STDDEV_FACTOR;
|
||||
|
||||
//! \brief This enumerator describes the limits used to compute min/max values
|
||||
enum Limits
|
||||
{
|
||||
//! User defined.
|
||||
None /PyName=None_/,
|
||||
//! Real min-max values
|
||||
MinMax,
|
||||
//! Range is [ mean - stdDevFactor() * stddev, mean + stdDevFactor() * stddev ]
|
||||
StdDev,
|
||||
//! Range is [ min + cumulativeCutLower() * (max - min), min + cumulativeCutUpper() * (max - min) ]
|
||||
CumulativeCut
|
||||
};
|
||||
|
||||
//! \brief This enumerator describes the extent used to compute min/max values
|
||||
enum Extent
|
||||
{
|
||||
//! Whole raster is used to compute statistics.
|
||||
WholeRaster,
|
||||
//! Current extent of the canvas (at the time of computation) is used to compute statistics.
|
||||
CurrentCanvas,
|
||||
//! Constantly updated extent of the canvas is used to compute statistics.
|
||||
UpdatedCanvas
|
||||
};
|
||||
|
||||
//! \brief This enumerator describes the accuracy used to compute statistics.
|
||||
enum StatAccuracy
|
||||
{
|
||||
//! Exact statistics.
|
||||
Exact,
|
||||
//! Approximated statistics.
|
||||
Estimated
|
||||
};
|
||||
|
||||
//! \brief Default constructor.
|
||||
QgsRasterMinMaxOrigin();
|
||||
|
||||
//! \brief Equality operator.
|
||||
bool operator ==( const QgsRasterMinMaxOrigin& other ) const;
|
||||
|
||||
//////// Getter methods /////////////////////
|
||||
|
||||
//! \brief Return limits.
|
||||
QgsRasterMinMaxOrigin::Limits limits() const;
|
||||
|
||||
//! \brief Return extent.
|
||||
QgsRasterMinMaxOrigin::Extent extent() const;
|
||||
|
||||
//! \brief Return statistic accuracy.
|
||||
QgsRasterMinMaxOrigin::StatAccuracy statAccuracy() const;
|
||||
|
||||
//! \brief Return lower bound of cumulative cut method (between 0 and 1).
|
||||
double cumulativeCutLower() const;
|
||||
|
||||
//! \brief Return upper bound of cumulative cut method (between 0 and 1).
|
||||
double cumulativeCutUpper() const;
|
||||
|
||||
//! \brief Return factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ]
|
||||
double stdDevFactor() const;
|
||||
|
||||
//////// Setter methods /////////////////////
|
||||
|
||||
//! \brief Set limits.
|
||||
void setLimits(QgsRasterMinMaxOrigin::Limits theLimits);
|
||||
|
||||
//! \brief Set extent.
|
||||
void setExtent(QgsRasterMinMaxOrigin::Extent theExtent);
|
||||
|
||||
//! \brief Set statistics accuracy.
|
||||
void setStatAccuracy(QgsRasterMinMaxOrigin::StatAccuracy theAccuracy);
|
||||
|
||||
//! \brief Set lower bound of cumulative cut method (between 0 and 1).
|
||||
void setCumulativeCutLower(double val);
|
||||
|
||||
//! \brief Set upper bound of cumulative cut method (between 0 and 1).
|
||||
void setCumulativeCutUpper(double val);
|
||||
|
||||
//! \brief Set factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ]
|
||||
void setStdDevFactor(double val);
|
||||
|
||||
//////// XML serialization /////////////////////
|
||||
|
||||
//! \brief Serialize object.
|
||||
void writeXml( QDomDocument& doc, QDomElement& parentElem ) const;
|
||||
|
||||
//! \brief Deserialize object.
|
||||
void readXml( const QDomElement& elem );
|
||||
|
||||
//////// Static methods /////////////////////
|
||||
|
||||
//! \brief Return a string to serialize Limits
|
||||
static QString limitsString( QgsRasterMinMaxOrigin::Limits theLimits );
|
||||
|
||||
//! \brief Deserialize Limits
|
||||
static QgsRasterMinMaxOrigin::Limits limitsFromString( const QString& theLimits );
|
||||
|
||||
//! \brief Return a string to serialize Extent
|
||||
static QString extentString( QgsRasterMinMaxOrigin::Extent theExtent );
|
||||
|
||||
//! \brief Deserialize Extent
|
||||
static QgsRasterMinMaxOrigin::Extent extentFromString( const QString& theExtent );
|
||||
|
||||
//! \brief Return a string to serialize StatAccuracy
|
||||
static QString statAccuracyString( QgsRasterMinMaxOrigin::StatAccuracy theAccuracy );
|
||||
|
||||
//! \brief Deserialize StatAccuracy
|
||||
static QgsRasterMinMaxOrigin::StatAccuracy statAccuracyFromString( const QString& theAccuracy );
|
||||
};
|
@ -6,22 +6,6 @@ class QgsRasterRenderer : QgsRasterInterface
|
||||
%End
|
||||
|
||||
public:
|
||||
// Origin of min / max values
|
||||
enum MinMaxOrigin
|
||||
{
|
||||
MinMaxUnknown,
|
||||
MinMaxUser, // entered by user
|
||||
// method
|
||||
MinMaxMinMax,
|
||||
MinMaxCumulativeCut,
|
||||
MinMaxStdDev,
|
||||
// Extent
|
||||
MinMaxFullExtent,
|
||||
MinMaxSubExtent,
|
||||
// Precision
|
||||
MinMaxEstimated,
|
||||
MinMaxExact
|
||||
};
|
||||
|
||||
static const QRgb NODATA_COLOR;
|
||||
|
||||
@ -60,14 +44,16 @@ class QgsRasterRenderer : QgsRasterInterface
|
||||
/** Copies common properties like opacity / transparency data from other renderer.
|
||||
* Useful when cloning renderers.
|
||||
* @note added in 2.16 */
|
||||
void copyCommonProperties( const QgsRasterRenderer* other );
|
||||
void copyCommonProperties( const QgsRasterRenderer* other, bool copyMinMaxOrigin = true );
|
||||
|
||||
/** Returns a list of band numbers used by the renderer*/
|
||||
virtual QList<int> usesBands() const;
|
||||
|
||||
static QString minMaxOriginName( int theOrigin );
|
||||
static QString minMaxOriginLabel( int theOrigin );
|
||||
static int minMaxOriginFromName( const QString& theName );
|
||||
//! Returns const reference to origin of min/max values
|
||||
const QgsRasterMinMaxOrigin& minMaxOrigin() const;
|
||||
|
||||
//! Sets origin of min/max values
|
||||
void setMinMaxOrigin( const QgsRasterMinMaxOrigin& theOrigin );
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -40,8 +40,6 @@ class QgsSingleBandPseudoColorRenderer: QgsRasterRenderer
|
||||
double classificationMax() const;
|
||||
void setClassificationMin( double min );
|
||||
void setClassificationMax( double max );
|
||||
int classificationMinMaxOrigin() const;
|
||||
void setClassificationMinMaxOrigin( int origin );
|
||||
|
||||
private:
|
||||
|
||||
|
@ -19,7 +19,8 @@ class QgsMultiBandColorRendererWidget: QgsRasterRendererWidget
|
||||
void setMin( const QString& value, int index = 0 );
|
||||
void setMax( const QString& value, int index = 0 );
|
||||
int selectedBand( int index = 0 );
|
||||
void doComputations();
|
||||
|
||||
public slots:
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax );
|
||||
};
|
||||
|
@ -37,9 +37,34 @@ class QgsRasterMinMaxWidget: QWidget
|
||||
/** Return the selected sample size. */
|
||||
int sampleSize();
|
||||
|
||||
// Load programmaticaly with current values
|
||||
void load();
|
||||
//! \brief Set the "source" of min/max values.
|
||||
void setFromMinMaxOrigin( const QgsRasterMinMaxOrigin& );
|
||||
|
||||
//! \brief Return a QgsRasterMinMaxOrigin object with the widget values.
|
||||
QgsRasterMinMaxOrigin minMaxOrigin();
|
||||
|
||||
//! Hide updated extent radio button
|
||||
void hideUpdatedExtent();
|
||||
|
||||
//! Load programmaticaly with current values
|
||||
void doComputations();
|
||||
|
||||
//! Uncheck cumulative cut, min/max, std-dev radio buttons
|
||||
void userHasSetManualMinMaxValues();
|
||||
|
||||
//! Return if the widget is collaped.
|
||||
bool isCollapsed() const;
|
||||
|
||||
//! Set collapsed state of widget
|
||||
void setCollapsed(bool b);
|
||||
|
||||
signals:
|
||||
void load( int theBandNo, double theMin, double theMax, int origin );
|
||||
/**
|
||||
* Emitted when something on the widget has changed.
|
||||
* All widgets will fire this event to notify of an internal change.
|
||||
*/
|
||||
void widgetChanged();
|
||||
|
||||
//! signal emitted when new min/max values are computed from statistics.
|
||||
void load( int theBandNo, double theMin, double theMax );
|
||||
};
|
||||
|
@ -7,14 +7,6 @@ class QgsRasterRendererWidget: QWidget
|
||||
QgsRasterRendererWidget( QgsRasterLayer* layer, const QgsRectangle &extent );
|
||||
virtual ~QgsRasterRendererWidget();
|
||||
|
||||
enum LoadMinMaxAlgo
|
||||
{
|
||||
Estimate,
|
||||
Actual,
|
||||
CurrentExtent,
|
||||
CumulativeCut // 2 - 98% cumulative cut
|
||||
};
|
||||
|
||||
virtual QgsRasterRenderer* renderer() = 0 /Factory/;
|
||||
|
||||
void setRasterLayer( QgsRasterLayer* layer );
|
||||
@ -42,6 +34,8 @@ class QgsRasterRendererWidget: QWidget
|
||||
virtual QString stdDev();
|
||||
virtual void setStdDev( const QString& value );
|
||||
virtual int selectedBand( int index = 0 );
|
||||
virtual void doComputations();
|
||||
virtual QgsRasterMinMaxWidget* minMaxWidget();
|
||||
|
||||
signals:
|
||||
/**
|
||||
|
@ -19,7 +19,8 @@ class QgsSingleBandGrayRendererWidget: QgsRasterRendererWidget
|
||||
void setMin( const QString& value, int index = 0 );
|
||||
void setMax( const QString& value, int index = 0 );
|
||||
int selectedBand( int index = 0 );
|
||||
void doComputations();
|
||||
|
||||
public slots:
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax );
|
||||
};
|
||||
|
@ -21,12 +21,14 @@ class QgsSingleBandPseudoColorRendererWidget : QgsRasterRendererWidget
|
||||
|
||||
void setFromRenderer( const QgsRasterRenderer* r );
|
||||
|
||||
void doComputations();
|
||||
|
||||
public slots:
|
||||
|
||||
/** Executes the single band pseudo raster classficiation
|
||||
*/
|
||||
void classify();
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax );
|
||||
|
||||
};
|
||||
|
||||
|
@ -8845,11 +8845,9 @@ void QgisApp::legendLayerStretchUsingCurrentExtent()
|
||||
QgsRasterLayer *layer = qobject_cast<QgsRasterLayer *>( currentLayer );
|
||||
if ( layer )
|
||||
{
|
||||
QgsContrastEnhancement::ContrastEnhancementAlgorithm contrastEnhancementAlgorithm = QgsContrastEnhancement::StretchToMinimumMaximum;
|
||||
|
||||
QgsRectangle myRectangle;
|
||||
myRectangle = mMapCanvas->mapSettings().outputExtentToLayerExtent( layer, mMapCanvas->extent() );
|
||||
layer->setContrastEnhancement( contrastEnhancementAlgorithm, QgsRaster::ContrastEnhancementMinMax, myRectangle );
|
||||
layer->refreshContrastEnhancement( myRectangle );
|
||||
|
||||
mLayerTreeView->refreshLayerSymbology( layer->id() );
|
||||
mMapCanvas->refresh();
|
||||
@ -9176,25 +9174,25 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString& currentPage )
|
||||
|
||||
void QgisApp::fullHistogramStretch()
|
||||
{
|
||||
histogramStretch( false, QgsRaster::ContrastEnhancementMinMax );
|
||||
histogramStretch( false, QgsRasterMinMaxOrigin::MinMax );
|
||||
}
|
||||
|
||||
void QgisApp::localHistogramStretch()
|
||||
{
|
||||
histogramStretch( true, QgsRaster::ContrastEnhancementMinMax );
|
||||
histogramStretch( true, QgsRasterMinMaxOrigin::MinMax );
|
||||
}
|
||||
|
||||
void QgisApp::fullCumulativeCutStretch()
|
||||
{
|
||||
histogramStretch( false, QgsRaster::ContrastEnhancementCumulativeCut );
|
||||
histogramStretch( false, QgsRasterMinMaxOrigin::CumulativeCut );
|
||||
}
|
||||
|
||||
void QgisApp::localCumulativeCutStretch()
|
||||
{
|
||||
histogramStretch( true, QgsRaster::ContrastEnhancementCumulativeCut );
|
||||
histogramStretch( true, QgsRasterMinMaxOrigin::CumulativeCut );
|
||||
}
|
||||
|
||||
void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRaster::ContrastEnhancementLimits theLimits )
|
||||
void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRasterMinMaxOrigin::Limits theLimits )
|
||||
{
|
||||
QgsMapLayer * myLayer = mLayerTreeView->currentLayer();
|
||||
|
||||
|
@ -125,6 +125,7 @@ class QgsDiagramProperties;
|
||||
#include "qgsmimedatautils.h"
|
||||
#include "qgswelcomepageitemsmodel.h"
|
||||
#include "qgsraster.h"
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
|
||||
#include "ui_qgisapp.h"
|
||||
|
||||
@ -1526,7 +1527,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
void createDecorations();
|
||||
|
||||
//! Do histogram stretch for singleband gray / multiband color rasters
|
||||
void histogramStretch( bool visibleAreaOnly = false, QgsRaster::ContrastEnhancementLimits theLimits = QgsRaster::ContrastEnhancementMinMax );
|
||||
void histogramStretch( bool visibleAreaOnly = false, QgsRasterMinMaxOrigin::Limits theLimits = QgsRasterMinMaxOrigin::MinMax );
|
||||
|
||||
//! Apply raster brightness
|
||||
void adjustBrightnessContrast( int delta, bool updateBrightness = true );
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "qgsmaplayerconfigwidget.h"
|
||||
#include "qgsmaplayerstylemanagerwidget.h"
|
||||
#include "qgsruntimeprofiler.h"
|
||||
#include "qgsrasterminmaxwidget.h"
|
||||
|
||||
|
||||
QgsLayerStylingWidget::QgsLayerStylingWidget( QgsMapCanvas* canvas, const QList<QgsMapLayerConfigWidgetFactory*>& pages, QWidget *parent )
|
||||
@ -378,15 +379,47 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
||||
else if ( mCurrentLayer->type() == QgsMapLayer::RasterLayer )
|
||||
{
|
||||
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer*>( mCurrentLayer );
|
||||
bool hasMinMaxCollapsedState = false;
|
||||
bool minMaxCollapsed = false;
|
||||
|
||||
switch ( row )
|
||||
{
|
||||
case 0: // Style
|
||||
{
|
||||
// Backup collapsed state of min/max group so as to restore it
|
||||
// on the new widget.
|
||||
if ( mRasterStyleWidget )
|
||||
{
|
||||
QgsRasterRendererWidget* currentRenderWidget = mRasterStyleWidget->currentRenderWidget();
|
||||
if ( currentRenderWidget )
|
||||
{
|
||||
QgsRasterMinMaxWidget* mmWidget = currentRenderWidget->minMaxWidget();
|
||||
if ( mmWidget )
|
||||
{
|
||||
hasMinMaxCollapsedState = true;
|
||||
minMaxCollapsed = mmWidget->isCollapsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
mRasterStyleWidget = new QgsRendererRasterPropertiesWidget( rlayer, mMapCanvas, mWidgetStack );
|
||||
if ( hasMinMaxCollapsedState )
|
||||
{
|
||||
QgsRasterRendererWidget* currentRenderWidget = mRasterStyleWidget->currentRenderWidget();
|
||||
if ( currentRenderWidget )
|
||||
{
|
||||
QgsRasterMinMaxWidget* mmWidget = currentRenderWidget->minMaxWidget();
|
||||
if ( mmWidget )
|
||||
{
|
||||
mmWidget->setCollapsed( minMaxCollapsed );
|
||||
}
|
||||
}
|
||||
}
|
||||
mRasterStyleWidget->setDockMode( true );
|
||||
connect( mRasterStyleWidget, SIGNAL( widgetChanged() ), this, SLOT( autoApply() ) );
|
||||
mWidgetStack->setMainPanel( mRasterStyleWidget );
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // Transparency
|
||||
{
|
||||
QgsRasterTransparencyWidget* transwidget = new QgsRasterTransparencyWidget( rlayer, mMapCanvas, mWidgetStack );
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "qgsproject.h"
|
||||
#include "qgsdualview.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
#include "qgscontrastenhancement.h"
|
||||
|
||||
#include "qgsattributetablefiltermodel.h"
|
||||
#include "qgsrasterformatsaveoptionswidget.h"
|
||||
@ -653,22 +655,24 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )
|
||||
spnGreen->setValue( mSettings->value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt() );
|
||||
spnBlue->setValue( mSettings->value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt() );
|
||||
|
||||
initContrastEnhancement( cboxContrastEnhancementAlgorithmSingleBand, QStringLiteral( "singleBand" ), QStringLiteral( "StretchToMinimumMaximum" ) );
|
||||
initContrastEnhancement( cboxContrastEnhancementAlgorithmMultiBandSingleByte, QStringLiteral( "multiBandSingleByte" ), QStringLiteral( "NoEnhancement" ) );
|
||||
initContrastEnhancement( cboxContrastEnhancementAlgorithmMultiBandMultiByte, QStringLiteral( "multiBandMultiByte" ), QStringLiteral( "StretchToMinimumMaximum" ) );
|
||||
initContrastEnhancement( cboxContrastEnhancementAlgorithmSingleBand, QStringLiteral( "singleBand" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsRasterLayer::SINGLE_BAND_ENHANCEMENT_ALGORITHM ) );
|
||||
initContrastEnhancement( cboxContrastEnhancementAlgorithmMultiBandSingleByte, QStringLiteral( "multiBandSingleByte" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsRasterLayer::MULTIPLE_BAND_SINGLE_BYTE_ENHANCEMENT_ALGORITHM ) );
|
||||
initContrastEnhancement( cboxContrastEnhancementAlgorithmMultiBandMultiByte, QStringLiteral( "multiBandMultiByte" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsRasterLayer::MULTIPLE_BAND_MULTI_BYTE_ENHANCEMENT_ALGORITHM ) );
|
||||
|
||||
cboxContrastEnhancementLimits->addItem( tr( "Cumulative pixel count cut" ), "CumulativeCut" );
|
||||
cboxContrastEnhancementLimits->addItem( tr( "Minimum / maximum" ), "MinMax" );
|
||||
cboxContrastEnhancementLimits->addItem( tr( "Mean +/- standard deviation" ), "StdDev" );
|
||||
initMinMaxLimits( cboxContrastEnhancementLimitsSingleBand, QStringLiteral( "singleBand" ),
|
||||
QgsRasterMinMaxOrigin::limitsString( QgsRasterLayer::SINGLE_BAND_MIN_MAX_LIMITS ) );
|
||||
initMinMaxLimits( cboxContrastEnhancementLimitsMultiBandSingleByte, QStringLiteral( "multiBandSingleByte" ),
|
||||
QgsRasterMinMaxOrigin::limitsString( QgsRasterLayer::MULTIPLE_BAND_SINGLE_BYTE_MIN_MAX_LIMITS ) );
|
||||
initMinMaxLimits( cboxContrastEnhancementLimitsMultiBandMultiByte, QStringLiteral( "multiBandMultiByte" ),
|
||||
QgsRasterMinMaxOrigin::limitsString( QgsRasterLayer::MULTIPLE_BAND_MULTI_BYTE_MIN_MAX_LIMITS ) );
|
||||
|
||||
QString contrastEnchacementLimits = mSettings->value( QStringLiteral( "/Raster/defaultContrastEnhancementLimits" ), "CumulativeCut" ).toString();
|
||||
spnThreeBandStdDev->setValue( mSettings->value( QStringLiteral( "/Raster/defaultStandardDeviation" ), QgsRasterMinMaxOrigin::DEFAULT_STDDEV_FACTOR ).toDouble() );
|
||||
|
||||
cboxContrastEnhancementLimits->setCurrentIndex( cboxContrastEnhancementLimits->findData( contrastEnchacementLimits ) );
|
||||
|
||||
spnThreeBandStdDev->setValue( mSettings->value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble() );
|
||||
|
||||
mRasterCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * mSettings->value( QStringLiteral( "/Raster/cumulativeCutLower" ), QString::number( QgsRasterLayer::CUMULATIVE_CUT_LOWER ) ).toDouble() );
|
||||
mRasterCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * mSettings->value( QStringLiteral( "/Raster/cumulativeCutUpper" ), QString::number( QgsRasterLayer::CUMULATIVE_CUT_UPPER ) ).toDouble() );
|
||||
mRasterCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * mSettings->value( QStringLiteral( "/Raster/cumulativeCutLower" ), QString::number( QgsRasterMinMaxOrigin::CUMULATIVE_CUT_LOWER ) ).toDouble() );
|
||||
mRasterCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * mSettings->value( QStringLiteral( "/Raster/cumulativeCutUpper" ), QString::number( QgsRasterMinMaxOrigin::CUMULATIVE_CUT_UPPER ) ).toDouble() );
|
||||
|
||||
//set the color for selections
|
||||
int myRed = mSettings->value( QStringLiteral( "/qgis/default_selection_color_red" ), 255 ).toInt();
|
||||
@ -1268,8 +1272,9 @@ void QgsOptions::saveOptions()
|
||||
saveContrastEnhancement( cboxContrastEnhancementAlgorithmMultiBandSingleByte, QStringLiteral( "multiBandSingleByte" ) );
|
||||
saveContrastEnhancement( cboxContrastEnhancementAlgorithmMultiBandMultiByte, QStringLiteral( "multiBandMultiByte" ) );
|
||||
|
||||
QString contrastEnhancementLimits = cboxContrastEnhancementLimits->currentData().toString();
|
||||
mSettings->setValue( QStringLiteral( "/Raster/defaultContrastEnhancementLimits" ), contrastEnhancementLimits );
|
||||
saveMinMaxLimits( cboxContrastEnhancementLimitsSingleBand, QStringLiteral( "singleBand" ) );
|
||||
saveMinMaxLimits( cboxContrastEnhancementLimitsMultiBandSingleByte, QStringLiteral( "multiBandSingleByte" ) );
|
||||
saveMinMaxLimits( cboxContrastEnhancementLimitsMultiBandMultiByte, QStringLiteral( "multiBandMultiByte" ) );
|
||||
|
||||
mSettings->setValue( QStringLiteral( "/Raster/defaultStandardDeviation" ), spnThreeBandStdDev->value() );
|
||||
|
||||
@ -2071,14 +2076,18 @@ void QgsOptions::initContrastEnhancement( QComboBox *cbox, const QString& name,
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
//add items to the color enhanceContrast combo box
|
||||
cbox->addItem( tr( "No Stretch" ), "NoEnhancement" );
|
||||
cbox->addItem( tr( "Stretch To MinMax" ), "StretchToMinimumMaximum" );
|
||||
cbox->addItem( tr( "Stretch And Clip To MinMax" ), "StretchAndClipToMinimumMaximum" );
|
||||
cbox->addItem( tr( "Clip To MinMax" ), "ClipToMinimumMaximum" );
|
||||
//add items to the color enhanceContrast combo boxes
|
||||
cbox->addItem( tr( "No Stretch" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsContrastEnhancement::NoEnhancement ) );
|
||||
cbox->addItem( tr( "Stretch To MinMax" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsContrastEnhancement::StretchToMinimumMaximum ) );
|
||||
cbox->addItem( tr( "Stretch And Clip To MinMax" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsContrastEnhancement::StretchAndClipToMinimumMaximum ) );
|
||||
cbox->addItem( tr( "Clip To MinMax" ),
|
||||
QgsContrastEnhancement::contrastEnhancementAlgorithmString( QgsContrastEnhancement::ClipToMinimumMaximum ) );
|
||||
|
||||
QString contrastEnchacement = mSettings->value( "/Raster/defaultContrastEnhancementAlgorithm/" + name, defaultVal ).toString();
|
||||
cbox->setCurrentIndex( cbox->findData( contrastEnchacement ) );
|
||||
QString contrastEnhancement = mSettings->value( "/Raster/defaultContrastEnhancementAlgorithm/" + name, defaultVal ).toString();
|
||||
cbox->setCurrentIndex( cbox->findData( contrastEnhancement ) );
|
||||
}
|
||||
|
||||
void QgsOptions::saveContrastEnhancement( QComboBox *cbox, const QString& name )
|
||||
@ -2088,6 +2097,29 @@ void QgsOptions::saveContrastEnhancement( QComboBox *cbox, const QString& name )
|
||||
mSettings->setValue( "/Raster/defaultContrastEnhancementAlgorithm/" + name, value );
|
||||
}
|
||||
|
||||
void QgsOptions::initMinMaxLimits( QComboBox *cbox, const QString& name, const QString& defaultVal )
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
//add items to the color limitsContrast combo boxes
|
||||
cbox->addItem( tr( "Cumulative pixel count cut" ),
|
||||
QgsRasterMinMaxOrigin::limitsString( QgsRasterMinMaxOrigin::CumulativeCut ) );
|
||||
cbox->addItem( tr( "Minimum / maximum" ),
|
||||
QgsRasterMinMaxOrigin::limitsString( QgsRasterMinMaxOrigin::MinMax ) );
|
||||
cbox->addItem( tr( "Mean +/- standard deviation" ),
|
||||
QgsRasterMinMaxOrigin::limitsString( QgsRasterMinMaxOrigin::StdDev ) );
|
||||
|
||||
QString contrastLimits = mSettings->value( "/Raster/defaultContrastEnhancementLimits/" + name, defaultVal ).toString();
|
||||
cbox->setCurrentIndex( cbox->findData( contrastLimits ) );
|
||||
}
|
||||
|
||||
void QgsOptions::saveMinMaxLimits( QComboBox *cbox, const QString& name )
|
||||
{
|
||||
QSettings settings;
|
||||
QString value = cbox->currentData().toString();
|
||||
mSettings->setValue( "/Raster/defaultContrastEnhancementLimits/" + name, value );
|
||||
}
|
||||
|
||||
void QgsOptions::on_mRemoveDefaultTransformButton_clicked()
|
||||
{
|
||||
QList<QTreeWidgetItem*> items = mDefaultDatumTransformTreeWidget->selectedItems();
|
||||
|
@ -206,6 +206,8 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
|
||||
QStringList i18nList();
|
||||
void initContrastEnhancement( QComboBox *cbox, const QString& name, const QString& defaultVal );
|
||||
void saveContrastEnhancement( QComboBox *cbox, const QString& name );
|
||||
void initMinMaxLimits( QComboBox *cbox, const QString& name, const QString& defaultVal );
|
||||
void saveMinMaxLimits( QComboBox *cbox, const QString& name );
|
||||
QgsCoordinateReferenceSystem mDefaultCrs;
|
||||
QgsCoordinateReferenceSystem mLayerDefaultCrs;
|
||||
bool mLoadedGdalDriverList;
|
||||
|
@ -855,6 +855,8 @@ void QgsRasterLayerProperties::apply()
|
||||
QgsRasterRendererWidget* rendererWidget = dynamic_cast<QgsRasterRendererWidget*>( mRendererStackedWidget->currentWidget() );
|
||||
if ( rendererWidget )
|
||||
{
|
||||
rendererWidget->doComputations();
|
||||
|
||||
mRasterLayer->setRenderer( rendererWidget->renderer() );
|
||||
}
|
||||
|
||||
|
@ -318,6 +318,7 @@ SET(QGIS_CORE_SRCS
|
||||
raster/qgsrasteriterator.cpp
|
||||
raster/qgsrasterlayer.cpp
|
||||
raster/qgsrasterlayerrenderer.cpp
|
||||
raster/qgsrasterminmaxorigin.cpp
|
||||
raster/qgsrasternuller.cpp
|
||||
raster/qgsrasterpipe.cpp
|
||||
raster/qgsrasterprojector.cpp
|
||||
@ -800,6 +801,7 @@ SET(QGIS_CORE_HDRS
|
||||
raster/qgsrasteridentifyresult.h
|
||||
raster/qgsrasterinterface.h
|
||||
raster/qgsrasteriterator.h
|
||||
raster/qgsrasterminmaxorigin.h
|
||||
raster/qgsrasternuller.h
|
||||
raster/qgsrasterpipe.h
|
||||
raster/qgsrasterprojector.h
|
||||
|
@ -32,6 +32,15 @@
|
||||
QVERIFY( qgsDoubleNear( value, expected, epsilon ) ); \
|
||||
}
|
||||
|
||||
#define QGSCOMPARENOTNEAR(value,not_expected,epsilon) { \
|
||||
bool _xxxresult = qgsDoubleNear( value, not_expected, epsilon ); \
|
||||
if ( _xxxresult ) \
|
||||
{ \
|
||||
qDebug( "Expecting %f to be differerent from %f (diff %f > %f)", static_cast< double >( value ), static_cast< double >( not_expected ), qAbs( static_cast< double >( not_expected ) - value ), static_cast< double >( epsilon ) ); \
|
||||
} \
|
||||
QVERIFY( !qgsDoubleNear( value, not_expected, epsilon ) ); \
|
||||
}
|
||||
|
||||
#define QGSCOMPARENEARPOINT(point1,point2,epsilon) { \
|
||||
QGSCOMPARENEAR( point1.x(), point2.x(), epsilon ); \
|
||||
QGSCOMPARENEAR( point1.y(), point2.y(), epsilon ); \
|
||||
|
@ -24,6 +24,7 @@ class originally created circa 2004 by T.Sutton, Gary E.Sherman, Steve Halasz
|
||||
#include <limits>
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgsraster.h"
|
||||
|
||||
class QgsContrastEnhancementFunction;
|
||||
class QDomDocument;
|
||||
@ -65,6 +66,12 @@ class CORE_EXPORT QgsContrastEnhancement
|
||||
//! \brief Helper function that returns the minimum possible value for a GDAL data type
|
||||
static double minimumValuePossible( Qgis::DataType );
|
||||
|
||||
//! \brief Return a string to serialize ContrastEnhancementAlgorithm
|
||||
static QString contrastEnhancementAlgorithmString( ContrastEnhancementAlgorithm algorithm );
|
||||
|
||||
//! \brief Deserialize ContrastEnhancementAlgorithm
|
||||
static ContrastEnhancementAlgorithm contrastEnhancementAlgorithmFromString( const QString& contrastEnhancementString );
|
||||
|
||||
/*
|
||||
*
|
||||
* Non-Static Inline methods
|
||||
@ -78,10 +85,6 @@ class CORE_EXPORT QgsContrastEnhancement
|
||||
|
||||
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const { return mContrastEnhancementAlgorithm; }
|
||||
|
||||
static QString contrastEnhancementAlgorithmString( ContrastEnhancementAlgorithm algorithm );
|
||||
|
||||
static ContrastEnhancementAlgorithm contrastEnhancementAlgorithmFromString( const QString& contrastEnhancementString );
|
||||
|
||||
/*
|
||||
*
|
||||
* Non-Static methods
|
||||
@ -137,8 +140,6 @@ class CORE_EXPORT QgsContrastEnhancement
|
||||
//! \brief Maximum range of values for a given data type
|
||||
double mRasterDataTypeRange;
|
||||
|
||||
|
||||
|
||||
//! \brief Method to generate a new lookup table
|
||||
bool generateLookupTable();
|
||||
|
||||
|
@ -19,39 +19,6 @@
|
||||
|
||||
#include "qgsraster.h"
|
||||
|
||||
QString QgsRaster::contrastEnhancementLimitsAsString( ContrastEnhancementLimits theLimits )
|
||||
{
|
||||
switch ( theLimits )
|
||||
{
|
||||
case QgsRaster::ContrastEnhancementMinMax:
|
||||
return QStringLiteral( "MinMax" );
|
||||
case QgsRaster::ContrastEnhancementStdDev:
|
||||
return QStringLiteral( "StdDev" );
|
||||
case QgsRaster::ContrastEnhancementCumulativeCut:
|
||||
return QStringLiteral( "CumulativeCut" );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QStringLiteral( "None" );
|
||||
}
|
||||
|
||||
QgsRaster::ContrastEnhancementLimits QgsRaster::contrastEnhancementLimitsFromString( const QString& theLimits )
|
||||
{
|
||||
if ( theLimits == QLatin1String( "MinMax" ) )
|
||||
{
|
||||
return ContrastEnhancementMinMax;
|
||||
}
|
||||
else if ( theLimits == QLatin1String( "StdDev" ) )
|
||||
{
|
||||
return ContrastEnhancementStdDev;
|
||||
}
|
||||
else if ( theLimits == QLatin1String( "CumulativeCut" ) )
|
||||
{
|
||||
return ContrastEnhancementCumulativeCut;
|
||||
}
|
||||
return ContrastEnhancementNone;
|
||||
}
|
||||
|
||||
bool QgsRaster::isRepresentableValue( double value, Qgis::DataType dataType )
|
||||
{
|
||||
switch ( dataType )
|
||||
|
@ -99,15 +99,6 @@ class CORE_EXPORT QgsRaster
|
||||
PyramidsErdas = 2
|
||||
};
|
||||
|
||||
//! \brief Contrast enhancement limits
|
||||
enum ContrastEnhancementLimits
|
||||
{
|
||||
ContrastEnhancementNone,
|
||||
ContrastEnhancementMinMax,
|
||||
ContrastEnhancementStdDev,
|
||||
ContrastEnhancementCumulativeCut
|
||||
};
|
||||
|
||||
//! \brief This enumerator describes the different kinds of drawing we can do
|
||||
enum DrawingStyle
|
||||
{
|
||||
@ -124,9 +115,6 @@ class CORE_EXPORT QgsRaster
|
||||
SingleBandColorDataStyle // ARGB values rendered directly
|
||||
};
|
||||
|
||||
static QString contrastEnhancementLimitsAsString( QgsRaster::ContrastEnhancementLimits theLimits );
|
||||
static ContrastEnhancementLimits contrastEnhancementLimitsFromString( const QString& theLimits );
|
||||
|
||||
/** Check if the specified value is representable in the given data type.
|
||||
* Supported are numerical types Byte, UInt16, Int16, UInt32, Int32, Float32, Float64.
|
||||
* @param value
|
||||
|
@ -78,10 +78,22 @@ typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QStrin
|
||||
|
||||
#define ERR(message) QGS_ERROR_MESSAGE(message,"Raster layer")
|
||||
|
||||
const double QgsRasterLayer::CUMULATIVE_CUT_LOWER = 0.02;
|
||||
const double QgsRasterLayer::CUMULATIVE_CUT_UPPER = 0.98;
|
||||
const double QgsRasterLayer::SAMPLE_SIZE = 250000;
|
||||
|
||||
const QgsContrastEnhancement::ContrastEnhancementAlgorithm
|
||||
QgsRasterLayer::SINGLE_BAND_ENHANCEMENT_ALGORITHM = QgsContrastEnhancement::StretchToMinimumMaximum;
|
||||
const QgsContrastEnhancement::ContrastEnhancementAlgorithm
|
||||
QgsRasterLayer::MULTIPLE_BAND_SINGLE_BYTE_ENHANCEMENT_ALGORITHM = QgsContrastEnhancement::NoEnhancement;
|
||||
const QgsContrastEnhancement::ContrastEnhancementAlgorithm
|
||||
QgsRasterLayer::MULTIPLE_BAND_MULTI_BYTE_ENHANCEMENT_ALGORITHM = QgsContrastEnhancement::StretchToMinimumMaximum;
|
||||
|
||||
const QgsRasterMinMaxOrigin::Limits
|
||||
QgsRasterLayer::SINGLE_BAND_MIN_MAX_LIMITS = QgsRasterMinMaxOrigin::MinMax;
|
||||
const QgsRasterMinMaxOrigin::Limits
|
||||
QgsRasterLayer::MULTIPLE_BAND_SINGLE_BYTE_MIN_MAX_LIMITS = QgsRasterMinMaxOrigin::MinMax;
|
||||
const QgsRasterMinMaxOrigin::Limits
|
||||
QgsRasterLayer::MULTIPLE_BAND_MULTI_BYTE_MIN_MAX_LIMITS = QgsRasterMinMaxOrigin::CumulativeCut;
|
||||
|
||||
QgsRasterLayer::QgsRasterLayer()
|
||||
: QgsMapLayer( RasterLayer )
|
||||
, QSTRING_NOT_SET( QStringLiteral( "Not Set" ) )
|
||||
@ -835,30 +847,86 @@ void QgsRasterLayer::closeDataProvider()
|
||||
mDataProvider = nullptr;
|
||||
}
|
||||
|
||||
void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, QgsRaster::ContrastEnhancementLimits theLimits, const QgsRectangle& theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
|
||||
void QgsRasterLayer::computeMinMax( int band,
|
||||
const QgsRasterMinMaxOrigin& mmo,
|
||||
QgsRasterMinMaxOrigin::Limits limits,
|
||||
const QgsRectangle& extent,
|
||||
int sampleSize,
|
||||
double& min, double& max )
|
||||
{
|
||||
|
||||
min = std::numeric_limits<double>::quiet_NaN();
|
||||
max = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
if ( limits == QgsRasterMinMaxOrigin::MinMax )
|
||||
{
|
||||
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( band, QgsRasterBandStats::Min | QgsRasterBandStats::Max, extent, sampleSize );
|
||||
min = myRasterBandStats.minimumValue;
|
||||
max = myRasterBandStats.maximumValue;
|
||||
}
|
||||
else if ( limits == QgsRasterMinMaxOrigin::StdDev )
|
||||
{
|
||||
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( band, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, extent, sampleSize );
|
||||
min = myRasterBandStats.mean - ( mmo.stdDevFactor() * myRasterBandStats.stdDev );
|
||||
max = myRasterBandStats.mean + ( mmo.stdDevFactor() * myRasterBandStats.stdDev );
|
||||
}
|
||||
else if ( limits == QgsRasterMinMaxOrigin::CumulativeCut )
|
||||
{
|
||||
const double myLower = mmo.cumulativeCutLower();
|
||||
const double myUpper = mmo.cumulativeCutUpper();
|
||||
QgsDebugMsgLevel( QString( "myLower = %1 myUpper = %2" ).arg( myLower ).arg( myUpper ), 4 );
|
||||
mDataProvider->cumulativeCut( band, myLower, myUpper, min, max, extent, sampleSize );
|
||||
}
|
||||
QgsDebugMsgLevel( QString( "band = %1 min = %2 max = %3" ).arg( band ).arg( min ).arg( max ), 4 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, QgsRasterMinMaxOrigin::Limits theLimits, const QgsRectangle& theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
|
||||
{
|
||||
setContrastEnhancement( theAlgorithm,
|
||||
theLimits,
|
||||
theExtent,
|
||||
theSampleSize,
|
||||
theGenerateLookupTableFlag,
|
||||
mPipe.renderer() );
|
||||
}
|
||||
|
||||
void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
|
||||
QgsRasterMinMaxOrigin::Limits theLimits,
|
||||
const QgsRectangle& theExtent,
|
||||
int theSampleSize,
|
||||
bool theGenerateLookupTableFlag,
|
||||
QgsRasterRenderer* rasterRenderer )
|
||||
{
|
||||
QgsDebugMsgLevel( QString( "theAlgorithm = %1 theLimits = %2 theExtent.isEmpty() = %3" ).arg( theAlgorithm ).arg( theLimits ).arg( theExtent.isEmpty() ), 4 );
|
||||
if ( !mPipe.renderer() || !mDataProvider )
|
||||
if ( !rasterRenderer || !mDataProvider )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<int> myBands;
|
||||
QList<QgsContrastEnhancement*> myEnhancements;
|
||||
QgsRasterMinMaxOrigin myMinMaxOrigin;
|
||||
QgsRasterRenderer* myRasterRenderer = nullptr;
|
||||
QgsSingleBandGrayRenderer* myGrayRenderer = nullptr;
|
||||
QgsMultiBandColorRenderer* myMultiBandRenderer = nullptr;
|
||||
QString rendererType = mPipe.renderer()->type();
|
||||
QString rendererType = rasterRenderer->type();
|
||||
if ( rendererType == QLatin1String( "singlebandgray" ) )
|
||||
{
|
||||
myGrayRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( mPipe.renderer() );
|
||||
myGrayRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( rasterRenderer );
|
||||
if ( !myGrayRenderer ) return;
|
||||
myBands << myGrayRenderer->grayBand();
|
||||
myRasterRenderer = myGrayRenderer;
|
||||
myMinMaxOrigin = myGrayRenderer->minMaxOrigin();
|
||||
}
|
||||
else if ( rendererType == QLatin1String( "multibandcolor" ) )
|
||||
{
|
||||
myMultiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( mPipe.renderer() );
|
||||
myMultiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( rasterRenderer );
|
||||
if ( !myMultiBandRenderer ) return;
|
||||
myBands << myMultiBandRenderer->redBand() << myMultiBandRenderer->greenBand() << myMultiBandRenderer->blueBand();
|
||||
myRasterRenderer = myMultiBandRenderer;
|
||||
myMinMaxOrigin = myMultiBandRenderer->minMaxOrigin();
|
||||
}
|
||||
|
||||
Q_FOREACH ( int myBand, myBands )
|
||||
@ -869,34 +937,12 @@ void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnh
|
||||
QgsContrastEnhancement* myEnhancement = new QgsContrastEnhancement( static_cast< Qgis::DataType >( myType ) );
|
||||
myEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
|
||||
|
||||
double myMin = std::numeric_limits<double>::quiet_NaN();
|
||||
double myMax = std::numeric_limits<double>::quiet_NaN();
|
||||
double min;
|
||||
double max;
|
||||
computeMinMax( myBand, myMinMaxOrigin, theLimits, theExtent, theSampleSize, min, max );
|
||||
|
||||
if ( theLimits == QgsRaster::ContrastEnhancementMinMax )
|
||||
{
|
||||
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, theExtent, theSampleSize );
|
||||
myMin = myRasterBandStats.minimumValue;
|
||||
myMax = myRasterBandStats.maximumValue;
|
||||
}
|
||||
else if ( theLimits == QgsRaster::ContrastEnhancementStdDev )
|
||||
{
|
||||
double myStdDev = 1; // make optional?
|
||||
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, theExtent, theSampleSize );
|
||||
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
|
||||
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
|
||||
}
|
||||
else if ( theLimits == QgsRaster::ContrastEnhancementCumulativeCut )
|
||||
{
|
||||
QSettings mySettings;
|
||||
double myLower = mySettings.value( QStringLiteral( "/Raster/cumulativeCutLower" ), QString::number( CUMULATIVE_CUT_LOWER ) ).toDouble();
|
||||
double myUpper = mySettings.value( QStringLiteral( "/Raster/cumulativeCutUpper" ), QString::number( CUMULATIVE_CUT_UPPER ) ).toDouble();
|
||||
QgsDebugMsgLevel( QString( "myLower = %1 myUpper = %2" ).arg( myLower ).arg( myUpper ), 4 );
|
||||
mDataProvider->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, theExtent, theSampleSize );
|
||||
}
|
||||
|
||||
QgsDebugMsgLevel( QString( "myBand = %1 myMin = %2 myMax = %3" ).arg( myBand ).arg( myMin ).arg( myMax ), 4 );
|
||||
myEnhancement->setMinimumValue( myMin );
|
||||
myEnhancement->setMaximumValue( myMax );
|
||||
myEnhancement->setMinimumValue( min );
|
||||
myEnhancement->setMaximumValue( max );
|
||||
myEnhancements.append( myEnhancement );
|
||||
}
|
||||
else
|
||||
@ -919,57 +965,208 @@ void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnh
|
||||
//delete all remaining unused enhancements
|
||||
qDeleteAll( myEnhancements );
|
||||
|
||||
emit repaintRequested();
|
||||
emit styleChanged();
|
||||
myMinMaxOrigin.setLimits( theLimits );
|
||||
if ( theExtent != QgsRectangle() &&
|
||||
myMinMaxOrigin.extent() == QgsRasterMinMaxOrigin::WholeRaster )
|
||||
{
|
||||
myMinMaxOrigin.setExtent( QgsRasterMinMaxOrigin::CurrentCanvas );
|
||||
}
|
||||
if ( myRasterRenderer )
|
||||
{
|
||||
myRasterRenderer->setMinMaxOrigin( myMinMaxOrigin );
|
||||
}
|
||||
|
||||
if ( rasterRenderer == renderer() )
|
||||
{
|
||||
emit repaintRequested();
|
||||
emit styleChanged();
|
||||
emit rendererChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterLayer::refreshContrastEnhancement( const QgsRectangle& theExtent )
|
||||
{
|
||||
QgsSingleBandGrayRenderer* singleBandRenderer = nullptr;
|
||||
QgsMultiBandColorRenderer* multiBandRenderer = nullptr;
|
||||
const QgsContrastEnhancement* ce = nullptr;
|
||||
if (( singleBandRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( renderer() ) ) )
|
||||
{
|
||||
ce = singleBandRenderer->contrastEnhancement();
|
||||
}
|
||||
else if (( multiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( renderer() ) ) )
|
||||
{
|
||||
ce = multiBandRenderer->redContrastEnhancement();
|
||||
}
|
||||
|
||||
if ( ce )
|
||||
{
|
||||
setContrastEnhancement( ce->contrastEnhancementAlgorithm() == QgsContrastEnhancement::NoEnhancement ?
|
||||
QgsContrastEnhancement::StretchToMinimumMaximum : ce->contrastEnhancementAlgorithm(),
|
||||
renderer()->minMaxOrigin().limits() == QgsRasterMinMaxOrigin::None ?
|
||||
QgsRasterMinMaxOrigin::MinMax : renderer()->minMaxOrigin().limits(),
|
||||
theExtent,
|
||||
SAMPLE_SIZE,
|
||||
true,
|
||||
renderer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsContrastEnhancement::ContrastEnhancementAlgorithm myAlgorithm;
|
||||
QgsRasterMinMaxOrigin::Limits myLimits;
|
||||
if ( defaultContrastEnhancementSettings( myAlgorithm, myLimits ) )
|
||||
{
|
||||
setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum,
|
||||
myLimits,
|
||||
theExtent,
|
||||
SAMPLE_SIZE,
|
||||
true,
|
||||
renderer() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterLayer::refreshRendererIfNeeded( QgsRasterRenderer* rasterRenderer,
|
||||
const QgsRectangle& theExtent )
|
||||
{
|
||||
if ( !( mDataProvider &&
|
||||
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded != theExtent &&
|
||||
rasterRenderer->minMaxOrigin().limits() != QgsRasterMinMaxOrigin::None &&
|
||||
rasterRenderer->minMaxOrigin().extent() == QgsRasterMinMaxOrigin::UpdatedCanvas ) )
|
||||
return;
|
||||
|
||||
QgsSingleBandGrayRenderer* singleBandRenderer = nullptr;
|
||||
QgsMultiBandColorRenderer* multiBandRenderer = nullptr;
|
||||
QgsSingleBandPseudoColorRenderer* sbpcr = nullptr;
|
||||
const QgsContrastEnhancement* ce = nullptr;
|
||||
if (( singleBandRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( rasterRenderer ) ) )
|
||||
{
|
||||
ce = singleBandRenderer->contrastEnhancement();
|
||||
}
|
||||
else if (( multiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( rasterRenderer ) ) )
|
||||
{
|
||||
ce = multiBandRenderer->redContrastEnhancement();
|
||||
}
|
||||
else if (( sbpcr = dynamic_cast<QgsSingleBandPseudoColorRenderer*>( rasterRenderer ) ) )
|
||||
{
|
||||
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = theExtent;
|
||||
double min;
|
||||
double max;
|
||||
computeMinMax( sbpcr->band(),
|
||||
rasterRenderer->minMaxOrigin(),
|
||||
rasterRenderer->minMaxOrigin().limits(), theExtent,
|
||||
SAMPLE_SIZE, min, max );
|
||||
sbpcr->setClassificationMin( min );
|
||||
sbpcr->setClassificationMax( max );
|
||||
dynamic_cast<QgsSingleBandPseudoColorRenderer*>( renderer() )->setClassificationMin( min );
|
||||
dynamic_cast<QgsSingleBandPseudoColorRenderer*>( renderer() )->setClassificationMax( max );
|
||||
emit styleChanged();
|
||||
emit rendererChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ce &&
|
||||
ce->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement )
|
||||
{
|
||||
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = theExtent;
|
||||
|
||||
setContrastEnhancement( ce->contrastEnhancementAlgorithm(),
|
||||
rasterRenderer->minMaxOrigin().limits(),
|
||||
theExtent,
|
||||
SAMPLE_SIZE,
|
||||
true,
|
||||
rasterRenderer );
|
||||
|
||||
// Update main renderer so that the legends get updated
|
||||
if ( singleBandRenderer )
|
||||
dynamic_cast<QgsSingleBandGrayRenderer*>( renderer() )->setContrastEnhancement( new QgsContrastEnhancement( * singleBandRenderer->contrastEnhancement() ) );
|
||||
else if ( multiBandRenderer )
|
||||
{
|
||||
if ( multiBandRenderer->redContrastEnhancement() )
|
||||
{
|
||||
dynamic_cast<QgsMultiBandColorRenderer*>( renderer() )->setRedContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->redContrastEnhancement() ) );
|
||||
}
|
||||
if ( multiBandRenderer->greenContrastEnhancement() )
|
||||
{
|
||||
dynamic_cast<QgsMultiBandColorRenderer*>( renderer() )->setGreenContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->greenContrastEnhancement() ) );
|
||||
}
|
||||
if ( multiBandRenderer->blueContrastEnhancement() )
|
||||
{
|
||||
dynamic_cast<QgsMultiBandColorRenderer*>( renderer() )->setBlueContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->blueContrastEnhancement() ) );
|
||||
}
|
||||
}
|
||||
|
||||
emit styleChanged();
|
||||
emit rendererChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsRasterLayer::defaultContrastEnhancementSettings(
|
||||
QgsContrastEnhancement::ContrastEnhancementAlgorithm& myAlgorithm,
|
||||
QgsRasterMinMaxOrigin::Limits& myLimits ) const
|
||||
{
|
||||
QSettings mySettings;
|
||||
|
||||
QString key;
|
||||
QString defaultAlg;
|
||||
QString defaultLimits;
|
||||
|
||||
// TODO: we should not test renderer class here, move it somehow to renderers
|
||||
if ( dynamic_cast<QgsSingleBandGrayRenderer*>( renderer() ) )
|
||||
{
|
||||
key = QStringLiteral( "singleBand" );
|
||||
defaultAlg = QgsContrastEnhancement::contrastEnhancementAlgorithmString(
|
||||
SINGLE_BAND_ENHANCEMENT_ALGORITHM );
|
||||
defaultLimits = QgsRasterMinMaxOrigin::limitsString(
|
||||
SINGLE_BAND_MIN_MAX_LIMITS );
|
||||
}
|
||||
else if ( dynamic_cast<QgsMultiBandColorRenderer*>( renderer() ) )
|
||||
{
|
||||
if ( QgsRasterBlock::typeSize( dataProvider()->sourceDataType( 1 ) ) == 1 )
|
||||
{
|
||||
key = QStringLiteral( "multiBandSingleByte" );
|
||||
defaultAlg = QgsContrastEnhancement::contrastEnhancementAlgorithmString(
|
||||
MULTIPLE_BAND_SINGLE_BYTE_ENHANCEMENT_ALGORITHM );
|
||||
defaultLimits = QgsRasterMinMaxOrigin::limitsString(
|
||||
MULTIPLE_BAND_SINGLE_BYTE_MIN_MAX_LIMITS );
|
||||
}
|
||||
else
|
||||
{
|
||||
key = QStringLiteral( "multiBandMultiByte" );
|
||||
defaultAlg = QgsContrastEnhancement::contrastEnhancementAlgorithmString(
|
||||
MULTIPLE_BAND_MULTI_BYTE_ENHANCEMENT_ALGORITHM );
|
||||
defaultLimits = QgsRasterMinMaxOrigin::limitsString(
|
||||
MULTIPLE_BAND_MULTI_BYTE_MIN_MAX_LIMITS );
|
||||
}
|
||||
}
|
||||
|
||||
if ( key.isEmpty() )
|
||||
{
|
||||
QgsDebugMsg( "No default contrast enhancement for this drawing style" );
|
||||
myAlgorithm = QgsContrastEnhancement::contrastEnhancementAlgorithmFromString( QString() );
|
||||
myLimits = QgsRasterMinMaxOrigin::limitsFromString( QString() );
|
||||
return false;
|
||||
}
|
||||
QgsDebugMsgLevel( "key = " + key, 4 );
|
||||
|
||||
QString myAlgorithmString = mySettings.value( "/Raster/defaultContrastEnhancementAlgorithm/" + key, defaultAlg ).toString();
|
||||
QgsDebugMsgLevel( "myAlgorithmString = " + myAlgorithmString, 4 );
|
||||
|
||||
myAlgorithm = QgsContrastEnhancement::contrastEnhancementAlgorithmFromString( myAlgorithmString );
|
||||
|
||||
QString myLimitsString = mySettings.value( "/Raster/defaultContrastEnhancementLimits/" + key, defaultLimits ).toString();
|
||||
QgsDebugMsgLevel( "myLimitsString = " + myLimitsString, 4 );
|
||||
myLimits = QgsRasterMinMaxOrigin::limitsFromString( myLimitsString );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsRasterLayer::setDefaultContrastEnhancement()
|
||||
{
|
||||
QgsDebugMsgLevel( "Entered", 4 );
|
||||
|
||||
QSettings mySettings;
|
||||
|
||||
QString myKey;
|
||||
QString myDefault;
|
||||
|
||||
// TODO: we should not test renderer class here, move it somehow to renderers
|
||||
if ( dynamic_cast<QgsSingleBandGrayRenderer*>( renderer() ) )
|
||||
{
|
||||
myKey = QStringLiteral( "singleBand" );
|
||||
myDefault = QStringLiteral( "StretchToMinimumMaximum" );
|
||||
}
|
||||
else if ( dynamic_cast<QgsMultiBandColorRenderer*>( renderer() ) )
|
||||
{
|
||||
if ( QgsRasterBlock::typeSize( dataProvider()->sourceDataType( 1 ) ) == 1 )
|
||||
{
|
||||
myKey = QStringLiteral( "multiBandSingleByte" );
|
||||
myDefault = QStringLiteral( "NoEnhancement" );
|
||||
}
|
||||
else
|
||||
{
|
||||
myKey = QStringLiteral( "multiBandMultiByte" );
|
||||
myDefault = QStringLiteral( "StretchToMinimumMaximum" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( myKey.isEmpty() )
|
||||
{
|
||||
QgsDebugMsg( "No default contrast enhancement for this drawing style" );
|
||||
}
|
||||
QgsDebugMsgLevel( "myKey = " + myKey, 4 );
|
||||
|
||||
QString myAlgorithmString = mySettings.value( "/Raster/defaultContrastEnhancementAlgorithm/" + myKey, myDefault ).toString();
|
||||
QgsDebugMsgLevel( "myAlgorithmString = " + myAlgorithmString, 4 );
|
||||
|
||||
QgsContrastEnhancement::ContrastEnhancementAlgorithm myAlgorithm = QgsContrastEnhancement::contrastEnhancementAlgorithmFromString( myAlgorithmString );
|
||||
|
||||
if ( myAlgorithm == QgsContrastEnhancement::NoEnhancement )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString myLimitsString = mySettings.value( QStringLiteral( "/Raster/defaultContrastEnhancementLimits" ), "CumulativeCut" ).toString();
|
||||
QgsRaster::ContrastEnhancementLimits myLimits = QgsRaster::contrastEnhancementLimitsFromString( myLimitsString );
|
||||
QgsContrastEnhancement::ContrastEnhancementAlgorithm myAlgorithm;
|
||||
QgsRasterMinMaxOrigin::Limits myLimits;
|
||||
defaultContrastEnhancementSettings( myAlgorithm, myLimits );
|
||||
|
||||
setContrastEnhancement( myAlgorithm, myLimits );
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "qgsraster.h"
|
||||
#include "qgsrasterpipe.h"
|
||||
#include "qgsrasterviewport.h"
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
#include "qgscontrastenhancement.h"
|
||||
|
||||
class QgsMapToPixel;
|
||||
@ -136,15 +137,28 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//! \brief Default cumulative cut lower limit
|
||||
static const double CUMULATIVE_CUT_LOWER;
|
||||
|
||||
//! \brief Default cumulative cut upper limit
|
||||
static const double CUMULATIVE_CUT_UPPER;
|
||||
|
||||
//! \brief Default sample size (number of pixels) for estimated statistics/histogram calculation
|
||||
static const double SAMPLE_SIZE;
|
||||
|
||||
//! \brief Default enhancement algorithm for single band raster
|
||||
static const QgsContrastEnhancement::ContrastEnhancementAlgorithm SINGLE_BAND_ENHANCEMENT_ALGORITHM;
|
||||
|
||||
//! \brief Default enhancement algorithm for multiple band raster of type Byte
|
||||
static const QgsContrastEnhancement::ContrastEnhancementAlgorithm MULTIPLE_BAND_SINGLE_BYTE_ENHANCEMENT_ALGORITHM;
|
||||
|
||||
//! \brief Default enhancement algorithm for multiple band raster of type different from Byte
|
||||
static const QgsContrastEnhancement::ContrastEnhancementAlgorithm MULTIPLE_BAND_MULTI_BYTE_ENHANCEMENT_ALGORITHM;
|
||||
|
||||
//! \brief Default enhancement limits for single band raster
|
||||
static const QgsRasterMinMaxOrigin::Limits SINGLE_BAND_MIN_MAX_LIMITS;
|
||||
|
||||
//! \brief Default enhancement limits for multiple band raster of type Byte
|
||||
static const QgsRasterMinMaxOrigin::Limits MULTIPLE_BAND_SINGLE_BYTE_MIN_MAX_LIMITS;
|
||||
|
||||
//! \brief Default enhancement limits for multiple band raster of type different from Byte
|
||||
static const QgsRasterMinMaxOrigin::Limits MULTIPLE_BAND_MULTI_BYTE_MIN_MAX_LIMITS;
|
||||
|
||||
//! \brief Constructor. Provider is not set.
|
||||
QgsRasterLayer();
|
||||
|
||||
@ -291,11 +305,30 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
||||
|
||||
|
||||
void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
|
||||
QgsRaster::ContrastEnhancementLimits theLimits = QgsRaster::ContrastEnhancementMinMax,
|
||||
QgsRasterMinMaxOrigin::Limits theLimits = QgsRasterMinMaxOrigin::MinMax,
|
||||
const QgsRectangle& theExtent = QgsRectangle(),
|
||||
int theSampleSize = SAMPLE_SIZE,
|
||||
bool theGenerateLookupTableFlag = true );
|
||||
|
||||
/** \brief Refresh contrast enhancement with new extent.
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
// Used by QgisApp::legendLayerStretchUsingCurrentExtent()
|
||||
void refreshContrastEnhancement( const QgsRectangle& theExtent );
|
||||
|
||||
/** \brief Refresh renderer with new extent, if needed
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
// Used by QgsRasterLayerRenderer
|
||||
void refreshRendererIfNeeded( QgsRasterRenderer* rasterRenderer, const QgsRectangle& theExtent );
|
||||
|
||||
/** \brief Return default contrast enhancemnt settings for that type of raster.
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
bool defaultContrastEnhancementSettings(
|
||||
QgsContrastEnhancement::ContrastEnhancementAlgorithm& myAlgorithm,
|
||||
QgsRasterMinMaxOrigin::Limits& myLimits ) const;
|
||||
|
||||
//! \brief Set default contrast enhancement
|
||||
void setDefaultContrastEnhancement();
|
||||
|
||||
@ -368,6 +401,20 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
||||
//! Sets corresponding renderer for style
|
||||
void setRendererForDrawingStyle( QgsRaster::DrawingStyle theDrawingStyle );
|
||||
|
||||
void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
|
||||
QgsRasterMinMaxOrigin::Limits theLimits,
|
||||
const QgsRectangle& theExtent,
|
||||
int theSampleSize,
|
||||
bool theGenerateLookupTableFlag,
|
||||
QgsRasterRenderer* rasterRenderer );
|
||||
|
||||
void computeMinMax( int band,
|
||||
const QgsRasterMinMaxOrigin& mmo,
|
||||
QgsRasterMinMaxOrigin::Limits limits,
|
||||
const QgsRectangle& extent,
|
||||
int sampleSize,
|
||||
double& min, double& max );
|
||||
|
||||
//! \brief Constant defining flag for XML and a constant that signals property not used
|
||||
const QString QSTRING_NOT_SET;
|
||||
const QString TRSTRING_NOT_SET;
|
||||
@ -386,6 +433,9 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
||||
LayerType mRasterType;
|
||||
|
||||
QgsRasterPipe mPipe;
|
||||
|
||||
//! To save computations and possible infinite cycle of notifications
|
||||
QgsRectangle mLastRectangleUsedByRefreshContrastEnhancementIfNeeded;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -177,6 +177,9 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer* layer, QgsRender
|
||||
|
||||
// copy the whole raster pipe!
|
||||
mPipe = new QgsRasterPipe( *layer->pipe() );
|
||||
QgsRasterRenderer* rasterRenderer = mPipe->renderer();
|
||||
if ( rasterRenderer )
|
||||
layer->refreshRendererIfNeeded( rasterRenderer, myRasterExtent );
|
||||
}
|
||||
|
||||
QgsRasterLayerRenderer::~QgsRasterLayerRenderer()
|
||||
|
205
src/core/raster/qgsrasterminmaxorigin.cpp
Normal file
205
src/core/raster/qgsrasterminmaxorigin.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/***************************************************************************
|
||||
qgsrasterminmaxorigin.h - Origin of min/max values
|
||||
--------------------------------------
|
||||
Date : Dec 2016
|
||||
Copyright : (C) 2016 by Even Rouault
|
||||
email : even.rouault at spatialys.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QSettings>
|
||||
|
||||
QgsRasterMinMaxOrigin::QgsRasterMinMaxOrigin()
|
||||
: mLimits( None )
|
||||
, mExtent( WholeRaster )
|
||||
, mAccuracy( Estimated )
|
||||
, mCumulativeCutLower( CUMULATIVE_CUT_LOWER )
|
||||
, mCumulativeCutUpper( CUMULATIVE_CUT_UPPER )
|
||||
, mStdDevFactor( DEFAULT_STDDEV_FACTOR )
|
||||
{
|
||||
QSettings mySettings;
|
||||
mCumulativeCutLower = mySettings.value( QStringLiteral( "/Raster/cumulativeCutLower" ), CUMULATIVE_CUT_LOWER ).toDouble();
|
||||
mCumulativeCutUpper = mySettings.value( QStringLiteral( "/Raster/cumulativeCutUpper" ), CUMULATIVE_CUT_UPPER ).toDouble();
|
||||
mStdDevFactor = mySettings.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), DEFAULT_STDDEV_FACTOR ).toDouble();
|
||||
}
|
||||
|
||||
bool QgsRasterMinMaxOrigin::operator ==( const QgsRasterMinMaxOrigin& other ) const
|
||||
{
|
||||
return mLimits == other.mLimits &&
|
||||
mExtent == other.mExtent &&
|
||||
mAccuracy == other.mAccuracy &&
|
||||
qAbs( mCumulativeCutLower - other.mCumulativeCutLower ) < 1e-5 &&
|
||||
qAbs( mCumulativeCutUpper - other.mCumulativeCutUpper ) < 1e-5 &&
|
||||
qAbs( mStdDevFactor - other.mStdDevFactor ) < 1e-5;
|
||||
}
|
||||
|
||||
QString QgsRasterMinMaxOrigin::limitsString( Limits theLimits )
|
||||
{
|
||||
switch ( theLimits )
|
||||
{
|
||||
case MinMax:
|
||||
return QStringLiteral( "MinMax" );
|
||||
case StdDev:
|
||||
return QStringLiteral( "StdDev" );
|
||||
case CumulativeCut:
|
||||
return QStringLiteral( "CumulativeCut" );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QStringLiteral( "None" );
|
||||
}
|
||||
|
||||
QgsRasterMinMaxOrigin::Limits QgsRasterMinMaxOrigin::limitsFromString( const QString& theLimits )
|
||||
{
|
||||
if ( theLimits == QLatin1String( "MinMax" ) )
|
||||
{
|
||||
return MinMax;
|
||||
}
|
||||
else if ( theLimits == QLatin1String( "StdDev" ) )
|
||||
{
|
||||
return StdDev;
|
||||
}
|
||||
else if ( theLimits == QLatin1String( "CumulativeCut" ) )
|
||||
{
|
||||
return CumulativeCut;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
QString QgsRasterMinMaxOrigin::extentString( Extent minMaxExtent )
|
||||
{
|
||||
switch ( minMaxExtent )
|
||||
{
|
||||
case WholeRaster:
|
||||
return QStringLiteral( "WholeRaster" );
|
||||
case CurrentCanvas:
|
||||
return QStringLiteral( "CurrentCanvas" );
|
||||
case UpdatedCanvas:
|
||||
return QStringLiteral( "UpdatedCanvas" );
|
||||
}
|
||||
return QStringLiteral( "WholeRaster" );
|
||||
}
|
||||
|
||||
QgsRasterMinMaxOrigin::Extent QgsRasterMinMaxOrigin::extentFromString( const QString& theExtent )
|
||||
{
|
||||
if ( theExtent == QLatin1String( "WholeRaster" ) )
|
||||
{
|
||||
return WholeRaster;
|
||||
}
|
||||
else if ( theExtent == QLatin1String( "CurrentCanvas" ) )
|
||||
{
|
||||
return CurrentCanvas;
|
||||
}
|
||||
else if ( theExtent == QLatin1String( "UpdatedCanvas" ) )
|
||||
{
|
||||
return UpdatedCanvas;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WholeRaster;
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsRasterMinMaxOrigin::statAccuracyString( StatAccuracy theAccuracy )
|
||||
{
|
||||
if ( theAccuracy == Exact )
|
||||
return QStringLiteral( "Exact" );
|
||||
return QStringLiteral( "Estimated" );
|
||||
}
|
||||
|
||||
QgsRasterMinMaxOrigin::StatAccuracy QgsRasterMinMaxOrigin::statAccuracyFromString( const QString& theAccuracy )
|
||||
{
|
||||
if ( theAccuracy == QLatin1String( "Exact" ) )
|
||||
return Exact;
|
||||
return Estimated;
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxOrigin::writeXml( QDomDocument& doc, QDomElement& parentElem ) const
|
||||
{
|
||||
// limits
|
||||
QDomElement limitsElem = doc.createElement( QStringLiteral( "limits" ) );
|
||||
QDomText limitsText = doc.createTextNode( limitsString( mLimits ) );
|
||||
limitsElem.appendChild( limitsText );
|
||||
parentElem.appendChild( limitsElem );
|
||||
|
||||
// extent
|
||||
QDomElement extentElem = doc.createElement( QStringLiteral( "extent" ) );
|
||||
QDomText extentText = doc.createTextNode( extentString( mExtent ) );
|
||||
extentElem.appendChild( extentText );
|
||||
parentElem.appendChild( extentElem );
|
||||
|
||||
// statAccuracy
|
||||
QDomElement statAccuracyElem = doc.createElement( QStringLiteral( "statAccuracy" ) );
|
||||
QDomText statAccuracyText = doc.createTextNode( statAccuracyString( mAccuracy ) );
|
||||
statAccuracyElem.appendChild( statAccuracyText );
|
||||
parentElem.appendChild( statAccuracyElem );
|
||||
|
||||
// mCumulativeCutLower
|
||||
QDomElement cumulativeCutLowerElem = doc.createElement( QStringLiteral( "cumulativeCutLower" ) );
|
||||
QDomText cumulativeCutLowerText = doc.createTextNode( QString::number( mCumulativeCutLower ) );
|
||||
cumulativeCutLowerElem.appendChild( cumulativeCutLowerText );
|
||||
parentElem.appendChild( cumulativeCutLowerElem );
|
||||
|
||||
// mCumulativeCutUpper
|
||||
QDomElement cumulativeCutUpperElem = doc.createElement( QStringLiteral( "cumulativeCutUpper" ) );
|
||||
QDomText cumulativeCutUpperText = doc.createTextNode( QString::number( mCumulativeCutUpper ) );
|
||||
cumulativeCutUpperElem.appendChild( cumulativeCutUpperText );
|
||||
parentElem.appendChild( cumulativeCutUpperElem );
|
||||
|
||||
// mCumulativeCutUpper
|
||||
QDomElement stdDevFactorElem = doc.createElement( QStringLiteral( "stdDevFactor" ) );
|
||||
QDomText stdDevFactorText = doc.createTextNode( QString::number( mStdDevFactor ) );
|
||||
stdDevFactorElem.appendChild( stdDevFactorText );
|
||||
parentElem.appendChild( stdDevFactorElem );
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxOrigin::readXml( const QDomElement& elem )
|
||||
{
|
||||
QDomElement limitsElem = elem.firstChildElement( QStringLiteral( "limits" ) );
|
||||
if ( !limitsElem.isNull() )
|
||||
{
|
||||
mLimits = limitsFromString( limitsElem.text() );
|
||||
}
|
||||
|
||||
QDomElement extentElem = elem.firstChildElement( QStringLiteral( "extent" ) );
|
||||
if ( !extentElem.isNull() )
|
||||
{
|
||||
mExtent = extentFromString( extentElem.text() );
|
||||
}
|
||||
|
||||
QDomElement statAccuracyElem = elem.firstChildElement( QStringLiteral( "statAccuracy" ) );
|
||||
if ( !statAccuracyElem.isNull() )
|
||||
{
|
||||
mAccuracy = statAccuracyFromString( statAccuracyElem.text() );
|
||||
}
|
||||
|
||||
QDomElement cumulativeCutLowerElem = elem.firstChildElement( QStringLiteral( "cumulativeCutLower" ) );
|
||||
if ( !cumulativeCutLowerElem.isNull() )
|
||||
{
|
||||
mCumulativeCutLower = cumulativeCutLowerElem.text().toDouble();
|
||||
}
|
||||
|
||||
QDomElement cumulativeCutUpperElem = elem.firstChildElement( QStringLiteral( "cumulativeCutUpper" ) );
|
||||
if ( !cumulativeCutUpperElem.isNull() )
|
||||
{
|
||||
mCumulativeCutUpper = cumulativeCutUpperElem.text().toDouble();
|
||||
}
|
||||
|
||||
QDomElement stdDevFactorElem = elem.firstChildElement( QStringLiteral( "stdDevFactor" ) );
|
||||
if ( !stdDevFactorElem.isNull() )
|
||||
{
|
||||
mStdDevFactor = stdDevFactorElem.text().toDouble();
|
||||
}
|
||||
}
|
159
src/core/raster/qgsrasterminmaxorigin.h
Normal file
159
src/core/raster/qgsrasterminmaxorigin.h
Normal file
@ -0,0 +1,159 @@
|
||||
/***************************************************************************
|
||||
qgsrasterminmaxorigin.h - Origin of min/max values
|
||||
--------------------------------------
|
||||
Date : Dec 2016
|
||||
Copyright : (C) 2016 by Even Rouault
|
||||
email : even.rouault at spatialys.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSRASTERMINMAXORIGIN_H
|
||||
#define QGSRASTERMINMAXORIGIN_H
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
|
||||
/** \ingroup core
|
||||
* This class describes the origin of min/max values. It does not store by
|
||||
* itself the min/max values.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsRasterMinMaxOrigin
|
||||
{
|
||||
public:
|
||||
|
||||
//! \brief Default cumulative cut lower limit
|
||||
static constexpr double CUMULATIVE_CUT_LOWER = 0.02;
|
||||
|
||||
//! \brief Default cumulative cut upper limit
|
||||
static constexpr double CUMULATIVE_CUT_UPPER = 0.98;
|
||||
|
||||
//! \brief Default standard deviation factor
|
||||
static constexpr double DEFAULT_STDDEV_FACTOR = 2.0;
|
||||
|
||||
//! \brief This enumerator describes the limits used to compute min/max values
|
||||
enum Limits
|
||||
{
|
||||
//! User defined.
|
||||
None,
|
||||
//! Real min-max values
|
||||
MinMax,
|
||||
//! Range is [ mean - stdDevFactor() * stddev, mean + stdDevFactor() * stddev ]
|
||||
StdDev,
|
||||
//! Range is [ min + cumulativeCutLower() * (max - min), min + cumulativeCutUpper() * (max - min) ]
|
||||
CumulativeCut
|
||||
};
|
||||
|
||||
//! \brief This enumerator describes the extent used to compute min/max values
|
||||
enum Extent
|
||||
{
|
||||
//! Whole raster is used to compute statistics.
|
||||
WholeRaster,
|
||||
//! Current extent of the canvas (at the time of computation) is used to compute statistics.
|
||||
CurrentCanvas,
|
||||
//! Constantly updated extent of the canvas is used to compute statistics.
|
||||
UpdatedCanvas
|
||||
};
|
||||
|
||||
//! \brief This enumerator describes the accuracy used to compute statistics.
|
||||
enum StatAccuracy
|
||||
{
|
||||
//! Exact statistics.
|
||||
Exact,
|
||||
//! Approximated statistics.
|
||||
Estimated
|
||||
};
|
||||
|
||||
//! \brief Default constructor.
|
||||
QgsRasterMinMaxOrigin();
|
||||
|
||||
//! \brief Equality operator.
|
||||
bool operator ==( const QgsRasterMinMaxOrigin& other ) const;
|
||||
|
||||
//////// Getter methods /////////////////////
|
||||
|
||||
//! \brief Return limits.
|
||||
Limits limits() const { return mLimits; }
|
||||
|
||||
//! \brief Return extent.
|
||||
Extent extent() const { return mExtent; }
|
||||
|
||||
//! \brief Return statistic accuracy.
|
||||
StatAccuracy statAccuracy() const { return mAccuracy; }
|
||||
|
||||
//! \brief Return lower bound of cumulative cut method (between 0 and 1).
|
||||
double cumulativeCutLower() const { return mCumulativeCutLower; }
|
||||
|
||||
//! \brief Return upper bound of cumulative cut method (between 0 and 1).
|
||||
double cumulativeCutUpper() const { return mCumulativeCutUpper; }
|
||||
|
||||
//! \brief Return factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ]
|
||||
double stdDevFactor() const { return mStdDevFactor; }
|
||||
|
||||
//////// Setter methods /////////////////////
|
||||
|
||||
//! \brief Set limits.
|
||||
void setLimits( Limits theLimits ) { mLimits = theLimits; }
|
||||
|
||||
//! \brief Set extent.
|
||||
void setExtent( Extent theExtent ) { mExtent = theExtent; }
|
||||
|
||||
//! \brief Set statistics accuracy.
|
||||
void setStatAccuracy( StatAccuracy theAccuracy ) { mAccuracy = theAccuracy; }
|
||||
|
||||
//! \brief Set lower bound of cumulative cut method (between 0 and 1).
|
||||
void setCumulativeCutLower( double val ) { mCumulativeCutLower = val; }
|
||||
|
||||
//! \brief Set upper bound of cumulative cut method (between 0 and 1).
|
||||
void setCumulativeCutUpper( double val ) { mCumulativeCutUpper = val; }
|
||||
|
||||
//! \brief Set factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ]
|
||||
void setStdDevFactor( double val ) { mStdDevFactor = val; }
|
||||
|
||||
//////// XML serialization /////////////////////
|
||||
|
||||
//! \brief Serialize object.
|
||||
void writeXml( QDomDocument& doc, QDomElement& parentElem ) const;
|
||||
|
||||
//! \brief Deserialize object.
|
||||
void readXml( const QDomElement& elem );
|
||||
|
||||
//////// Static methods /////////////////////
|
||||
|
||||
//! \brief Return a string to serialize Limits
|
||||
static QString limitsString( Limits theLimits );
|
||||
|
||||
//! \brief Deserialize Limits
|
||||
static Limits limitsFromString( const QString& theLimits );
|
||||
|
||||
//! \brief Return a string to serialize Extent
|
||||
static QString extentString( Extent theExtent );
|
||||
|
||||
//! \brief Deserialize Extent
|
||||
static Extent extentFromString( const QString& theExtent );
|
||||
|
||||
//! \brief Return a string to serialize StatAccuracy
|
||||
static QString statAccuracyString( StatAccuracy theAccuracy );
|
||||
|
||||
//! \brief Deserialize StatAccuracy
|
||||
static StatAccuracy statAccuracyFromString( const QString& theAccuracy );
|
||||
|
||||
private:
|
||||
|
||||
Limits mLimits;
|
||||
Extent mExtent;
|
||||
StatAccuracy mAccuracy;
|
||||
double mCumulativeCutLower;
|
||||
double mCumulativeCutUpper;
|
||||
double mStdDevFactor;
|
||||
};
|
||||
|
||||
#endif // QGSRASTERMINMAXORIGIN_H
|
@ -112,6 +112,10 @@ void QgsRasterRenderer::_writeXml( QDomDocument& doc, QDomElement& rasterRendere
|
||||
{
|
||||
mRasterTransparency->writeXml( doc, rasterRendererElem );
|
||||
}
|
||||
|
||||
QDomElement minMaxOriginElem = doc.createElement( QStringLiteral( "minMaxOrigin" ) );
|
||||
mMinMaxOrigin.writeXml( doc, minMaxOriginElem );
|
||||
rasterRendererElem.appendChild( minMaxOriginElem );
|
||||
}
|
||||
|
||||
void QgsRasterRenderer::readXml( const QDomElement& rendererElem )
|
||||
@ -132,9 +136,15 @@ void QgsRasterRenderer::readXml( const QDomElement& rendererElem )
|
||||
mRasterTransparency = new QgsRasterTransparency();
|
||||
mRasterTransparency->readXml( rasterTransparencyElem );
|
||||
}
|
||||
|
||||
QDomElement minMaxOriginElem = rendererElem.firstChildElement( QStringLiteral( "minMaxOrigin" ) );
|
||||
if ( !minMaxOriginElem.isNull() )
|
||||
{
|
||||
mMinMaxOrigin.readXml( minMaxOriginElem );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer* other )
|
||||
void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer* other, bool copyMinMaxOrigin )
|
||||
{
|
||||
if ( !other )
|
||||
return;
|
||||
@ -142,150 +152,6 @@ void QgsRasterRenderer::copyCommonProperties( const QgsRasterRenderer* other )
|
||||
setOpacity( other->opacity() );
|
||||
setAlphaBand( other->alphaBand() );
|
||||
setRasterTransparency( other->rasterTransparency() ? new QgsRasterTransparency( *other->rasterTransparency() ) : nullptr );
|
||||
}
|
||||
|
||||
QString QgsRasterRenderer::minMaxOriginName( int theOrigin )
|
||||
{
|
||||
if ( theOrigin == MinMaxUnknown )
|
||||
{
|
||||
return QStringLiteral( "Unknown" );
|
||||
}
|
||||
else if ( theOrigin == MinMaxUser )
|
||||
{
|
||||
return QStringLiteral( "User" );
|
||||
}
|
||||
|
||||
QString name;
|
||||
if ( theOrigin & MinMaxMinMax )
|
||||
{
|
||||
name += QLatin1String( "MinMax" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxCumulativeCut )
|
||||
{
|
||||
name += QLatin1String( "CumulativeCut" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxStdDev )
|
||||
{
|
||||
name += QLatin1String( "StdDev" );
|
||||
}
|
||||
|
||||
if ( theOrigin & MinMaxFullExtent )
|
||||
{
|
||||
name += QLatin1String( "FullExtent" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxSubExtent )
|
||||
{
|
||||
name += QLatin1String( "SubExtent" );
|
||||
}
|
||||
|
||||
if ( theOrigin & MinMaxEstimated )
|
||||
{
|
||||
name += QLatin1String( "Estimated" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxExact )
|
||||
{
|
||||
name += QLatin1String( "Exact" );
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
QString QgsRasterRenderer::minMaxOriginLabel( int theOrigin )
|
||||
{
|
||||
if ( theOrigin == MinMaxUnknown )
|
||||
{
|
||||
return tr( "Unknown" );
|
||||
}
|
||||
else if ( theOrigin == MinMaxUser )
|
||||
{
|
||||
return tr( "User defined" );
|
||||
}
|
||||
|
||||
QString label;
|
||||
QString est_exact;
|
||||
QString values;
|
||||
QString extent;
|
||||
|
||||
if ( theOrigin & MinMaxEstimated )
|
||||
{
|
||||
est_exact = tr( "Estimated" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxExact )
|
||||
{
|
||||
est_exact = tr( "Exact" );
|
||||
}
|
||||
|
||||
if ( theOrigin & MinMaxMinMax )
|
||||
{
|
||||
values = tr( "min / max" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxCumulativeCut )
|
||||
{
|
||||
values = tr( "cumulative cut" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxStdDev )
|
||||
{
|
||||
values = tr( "standard deviation" );
|
||||
}
|
||||
|
||||
if ( theOrigin & MinMaxFullExtent )
|
||||
{
|
||||
extent = tr( "full extent" );
|
||||
}
|
||||
else if ( theOrigin & MinMaxSubExtent )
|
||||
{
|
||||
extent = tr( "sub extent" );
|
||||
}
|
||||
|
||||
label = QCoreApplication::translate( "QgsRasterRenderer", "%1 %2 of %3.",
|
||||
"min/max origin label in raster properties, where %1 - estimated/exact, %2 - values (min/max, stddev, etc.), %3 - extent" )
|
||||
.arg( est_exact,
|
||||
values,
|
||||
extent );
|
||||
return label;
|
||||
}
|
||||
|
||||
int QgsRasterRenderer::minMaxOriginFromName( const QString& theName )
|
||||
{
|
||||
if ( theName.contains( QLatin1String( "Unknown" ) ) )
|
||||
{
|
||||
return MinMaxUnknown;
|
||||
}
|
||||
else if ( theName.contains( QLatin1String( "User" ) ) )
|
||||
{
|
||||
return MinMaxUser;
|
||||
}
|
||||
|
||||
int origin = 0;
|
||||
|
||||
if ( theName.contains( QLatin1String( "MinMax" ) ) )
|
||||
{
|
||||
origin |= MinMaxMinMax;
|
||||
}
|
||||
else if ( theName.contains( QLatin1String( "CumulativeCut" ) ) )
|
||||
{
|
||||
origin |= MinMaxCumulativeCut;
|
||||
}
|
||||
else if ( theName.contains( QLatin1String( "StdDev" ) ) )
|
||||
{
|
||||
origin |= MinMaxStdDev;
|
||||
}
|
||||
|
||||
if ( theName.contains( QLatin1String( "FullExtent" ) ) )
|
||||
{
|
||||
origin |= MinMaxFullExtent;
|
||||
}
|
||||
else if ( theName.contains( QLatin1String( "SubExtent" ) ) )
|
||||
{
|
||||
origin |= MinMaxSubExtent;
|
||||
}
|
||||
|
||||
if ( theName.contains( QLatin1String( "Estimated" ) ) )
|
||||
{
|
||||
origin |= MinMaxEstimated;
|
||||
}
|
||||
else if ( theName.contains( QLatin1String( "Exact" ) ) )
|
||||
{
|
||||
origin |= MinMaxExact;
|
||||
}
|
||||
return origin;
|
||||
if ( copyMinMaxOrigin )
|
||||
setMinMaxOrigin( other->minMaxOrigin() );
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <QPair>
|
||||
|
||||
#include "qgsrasterinterface.h"
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
|
||||
class QDomElement;
|
||||
|
||||
@ -36,22 +37,6 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
|
||||
Q_DECLARE_TR_FUNCTIONS( QgsRasterRenderer );
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
static const QRgb NODATA_COLOR;
|
||||
|
||||
@ -90,14 +75,16 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
|
||||
/** Copies common properties like opacity / transparency data from other renderer.
|
||||
* Useful when cloning renderers.
|
||||
* @note added in 2.16 */
|
||||
void copyCommonProperties( const QgsRasterRenderer* other );
|
||||
void copyCommonProperties( const QgsRasterRenderer* other, bool copyMinMaxOrigin = true );
|
||||
|
||||
//! 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( const QString& theName );
|
||||
//! Returns const reference to origin of min/max values
|
||||
const QgsRasterMinMaxOrigin& minMaxOrigin() const { return mMinMaxOrigin; }
|
||||
|
||||
//! Sets origin of min/max values
|
||||
void setMinMaxOrigin( const QgsRasterMinMaxOrigin& theOrigin ) { mMinMaxOrigin = theOrigin; }
|
||||
|
||||
protected:
|
||||
|
||||
@ -115,6 +102,9 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
|
||||
Default: -1 (not set)*/
|
||||
int mAlphaBand;
|
||||
|
||||
//! Origin of min/max values
|
||||
QgsRasterMinMaxOrigin mMinMaxOrigin;
|
||||
|
||||
private:
|
||||
|
||||
QgsRasterRenderer( const QgsRasterRenderer& );
|
||||
|
@ -30,7 +30,6 @@ QgsSingleBandPseudoColorRenderer::QgsSingleBandPseudoColorRenderer( QgsRasterInt
|
||||
, mBand( band )
|
||||
, mClassificationMin( std::numeric_limits<double>::quiet_NaN() )
|
||||
, mClassificationMax( std::numeric_limits<double>::quiet_NaN() )
|
||||
, mClassificationMinMaxOrigin( QgsRasterRenderer::MinMaxUnknown )
|
||||
{
|
||||
}
|
||||
|
||||
@ -107,7 +106,50 @@ QgsRasterRenderer* QgsSingleBandPseudoColorRenderer::create( const QDomElement&
|
||||
// TODO: add _readXML in superclass?
|
||||
r->setClassificationMin( elem.attribute( QStringLiteral( "classificationMin" ), QStringLiteral( "NaN" ) ).toDouble() );
|
||||
r->setClassificationMax( elem.attribute( QStringLiteral( "classificationMax" ), QStringLiteral( "NaN" ) ).toDouble() );
|
||||
r->setClassificationMinMaxOrigin( QgsRasterRenderer::minMaxOriginFromName( elem.attribute( QStringLiteral( "classificationMinMaxOrigin" ), QStringLiteral( "Unknown" ) ) ) );
|
||||
|
||||
// Backward compatibility with serialization of QGIS 2.X era
|
||||
QString minMaxOrigin = elem.attribute( QStringLiteral( "classificationMinMaxOrigin" ) );
|
||||
if ( !minMaxOrigin.isEmpty() )
|
||||
{
|
||||
if ( minMaxOrigin.contains( QLatin1String( "MinMax" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setLimits( QgsRasterMinMaxOrigin::MinMax );
|
||||
}
|
||||
else if ( minMaxOrigin.contains( QLatin1String( "CumulativeCut" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setLimits( QgsRasterMinMaxOrigin::CumulativeCut );
|
||||
}
|
||||
else if ( minMaxOrigin.contains( QLatin1String( "StdDev" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setLimits( QgsRasterMinMaxOrigin::StdDev );
|
||||
}
|
||||
else
|
||||
{
|
||||
r->mMinMaxOrigin.setLimits( QgsRasterMinMaxOrigin::None );
|
||||
}
|
||||
|
||||
if ( minMaxOrigin.contains( QLatin1String( "FullExtent" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setExtent( QgsRasterMinMaxOrigin::WholeRaster );
|
||||
}
|
||||
else if ( minMaxOrigin.contains( QLatin1String( "SubExtent" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setExtent( QgsRasterMinMaxOrigin::CurrentCanvas );
|
||||
}
|
||||
else
|
||||
{
|
||||
r->mMinMaxOrigin.setExtent( QgsRasterMinMaxOrigin::WholeRaster );
|
||||
}
|
||||
|
||||
if ( minMaxOrigin.contains( QLatin1String( "Estimated" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setStatAccuracy( QgsRasterMinMaxOrigin::Estimated );
|
||||
}
|
||||
else // if ( minMaxOrigin.contains( QLatin1String( "Exact" ) ) )
|
||||
{
|
||||
r->mMinMaxOrigin.setStatAccuracy( QgsRasterMinMaxOrigin::Exact );
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -228,7 +270,6 @@ void QgsSingleBandPseudoColorRenderer::writeXml( QDomDocument& doc, QDomElement&
|
||||
}
|
||||
rasterRendererElem.setAttribute( QStringLiteral( "classificationMin" ), QgsRasterBlock::printValue( mClassificationMin ) );
|
||||
rasterRendererElem.setAttribute( QStringLiteral( "classificationMax" ), QgsRasterBlock::printValue( mClassificationMax ) );
|
||||
rasterRendererElem.setAttribute( QStringLiteral( "classificationMinMaxOrigin" ), QgsRasterRenderer::minMaxOriginName( mClassificationMinMaxOrigin ) );
|
||||
|
||||
parentElem.appendChild( rasterRendererElem );
|
||||
}
|
||||
|
@ -65,8 +65,6 @@ class CORE_EXPORT QgsSingleBandPseudoColorRenderer: public QgsRasterRenderer
|
||||
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;
|
||||
@ -77,8 +75,6 @@ class CORE_EXPORT QgsSingleBandPseudoColorRenderer: public QgsRasterRenderer
|
||||
double mClassificationMin;
|
||||
double mClassificationMax;
|
||||
|
||||
int mClassificationMinMaxOrigin;
|
||||
|
||||
QgsSingleBandPseudoColorRenderer( const QgsSingleBandPseudoColorRenderer& );
|
||||
const QgsSingleBandPseudoColorRenderer& operator=( const QgsSingleBandPseudoColorRenderer& );
|
||||
};
|
||||
|
@ -24,6 +24,7 @@
|
||||
QgsMultiBandColorRendererWidget::QgsMultiBandColorRendererWidget( QgsRasterLayer* layer, const QgsRectangle &extent )
|
||||
: QgsRasterRendererWidget( layer, extent )
|
||||
, mMinMaxWidget( nullptr )
|
||||
, mDisableMinMaxWidgetRefresh( false )
|
||||
{
|
||||
setupUi( this );
|
||||
createValidators();
|
||||
@ -43,8 +44,11 @@ QgsMultiBandColorRendererWidget::QgsMultiBandColorRendererWidget( QgsRasterLayer
|
||||
layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
mMinMaxContainerWidget->setLayout( layout );
|
||||
layout->addWidget( mMinMaxWidget );
|
||||
connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
|
||||
this, SLOT( loadMinMax( int, double, double, int ) ) );
|
||||
|
||||
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged,
|
||||
this, &QgsMultiBandColorRendererWidget::widgetChanged );
|
||||
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::load,
|
||||
this, &QgsMultiBandColorRendererWidget::loadMinMax );
|
||||
|
||||
connect( mRedBandComboBox, SIGNAL( currentIndexChanged( int ) ),
|
||||
this, SLOT( onBandChanged( int ) ) );
|
||||
@ -108,9 +112,17 @@ QgsRasterRenderer* QgsMultiBandColorRendererWidget::renderer()
|
||||
|
||||
QgsMultiBandColorRenderer* r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
|
||||
setCustomMinMaxValues( r, provider, redBand, greenBand, blueBand );
|
||||
|
||||
r->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::doComputations()
|
||||
{
|
||||
mMinMaxWidget->doComputations();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setMapCanvas( QgsMapCanvas* canvas )
|
||||
{
|
||||
QgsRasterRendererWidget::setMapCanvas( canvas );
|
||||
@ -214,9 +226,51 @@ void QgsMultiBandColorRendererWidget::onBandChanged( int index )
|
||||
emit widgetChanged();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
|
||||
void QgsMultiBandColorRendererWidget::on_mRedMinLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::on_mRedMaxLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::on_mGreenMinLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::on_mGreenMaxLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::on_mBlueMinLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::on_mBlueMaxLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::minMaxModified()
|
||||
{
|
||||
if ( !mDisableMinMaxWidgetRefresh )
|
||||
{
|
||||
if (( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
|
||||
{
|
||||
mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
|
||||
mContrastEnhancementAlgorithmComboBox->findData(( int ) QgsContrastEnhancement::StretchToMinimumMaximum ) );
|
||||
}
|
||||
mMinMaxWidget->userHasSetManualMinMaxValues();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax )
|
||||
{
|
||||
Q_UNUSED( theOrigin );
|
||||
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
|
||||
|
||||
QLineEdit *myMinLineEdit, *myMaxLineEdit;
|
||||
@ -242,6 +296,7 @@ void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin,
|
||||
return;
|
||||
}
|
||||
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
if ( qIsNaN( theMin ) )
|
||||
{
|
||||
myMinLineEdit->clear();
|
||||
@ -259,13 +314,7 @@ void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin,
|
||||
{
|
||||
myMaxLineEdit->setText( QString::number( theMax ) );
|
||||
}
|
||||
|
||||
//automaticlly activate contrast enhancement algorithm if set to none
|
||||
if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() == QgsContrastEnhancement::NoEnhancement )
|
||||
{
|
||||
mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
|
||||
mContrastEnhancementAlgorithmComboBox->findData( QgsContrastEnhancement::StretchToMinimumMaximum ) );
|
||||
}
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setMinMaxValue( const QgsContrastEnhancement* ce, QLineEdit* minEdit, QLineEdit* maxEdit )
|
||||
@ -300,9 +349,13 @@ void QgsMultiBandColorRendererWidget::setFromRenderer( const QgsRasterRenderer*
|
||||
mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findData( mbcr->greenBand() ) );
|
||||
mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findData( mbcr->blueBand() ) );
|
||||
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
|
||||
setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
|
||||
setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
|
||||
mMinMaxWidget->setFromMinMaxOrigin( mbcr->minMaxOrigin() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -356,6 +409,7 @@ QString QgsMultiBandColorRendererWidget::max( int index )
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setMin( const QString& value, int index )
|
||||
{
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
@ -370,10 +424,12 @@ void QgsMultiBandColorRendererWidget::setMin( const QString& value, int index )
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setMax( const QString& value, int index )
|
||||
{
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
@ -388,6 +444,7 @@ void QgsMultiBandColorRendererWidget::setMax( const QString& value, int index )
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
||||
|
||||
int QgsMultiBandColorRendererWidget::selectedBand( int index )
|
||||
|
@ -50,13 +50,22 @@ class GUI_EXPORT QgsMultiBandColorRendererWidget: public QgsRasterRendererWidget
|
||||
void setMin( const QString& value, int index = 0 ) override;
|
||||
void setMax( const QString& value, int index = 0 ) override;
|
||||
int selectedBand( int index = 0 ) override;
|
||||
void doComputations() override;
|
||||
QgsRasterMinMaxWidget* minMaxWidget() override { return mMinMaxWidget; }
|
||||
|
||||
public slots:
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
|
||||
//! called when new min/max values are loaded
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax );
|
||||
|
||||
private slots:
|
||||
//void on_mLoadPushButton_clicked();
|
||||
void onBandChanged( int );
|
||||
void on_mRedMinLineEdit_textChanged( const QString & );
|
||||
void on_mRedMaxLineEdit_textChanged( const QString & );
|
||||
void on_mGreenMinLineEdit_textChanged( const QString & );
|
||||
void on_mGreenMaxLineEdit_textChanged( const QString & );
|
||||
void on_mBlueMinLineEdit_textChanged( const QString & );
|
||||
void on_mBlueMaxLineEdit_textChanged( const QString & );
|
||||
|
||||
private:
|
||||
void createValidators();
|
||||
@ -65,6 +74,9 @@ class GUI_EXPORT QgsMultiBandColorRendererWidget: public QgsRasterRendererWidget
|
||||
//! Reads min/max values from contrast enhancement and fills values into the min/max line edits
|
||||
void setMinMaxValue( const QgsContrastEnhancement* ce, QLineEdit* minEdit, QLineEdit* maxEdit );
|
||||
QgsRasterMinMaxWidget * mMinMaxWidget;
|
||||
bool mDisableMinMaxWidgetRefresh;
|
||||
|
||||
void minMaxModified();
|
||||
};
|
||||
|
||||
#endif // QGSMULTIBANDCOLORRENDERERWIDGET_H
|
||||
|
@ -23,31 +23,23 @@
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsrasterrenderer.h"
|
||||
#include "qgsrasterdataprovider.h"
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
|
||||
const int IDX_WHOLE_RASTER = 0;
|
||||
const int IDX_CURRENT_CANVAS = 1;
|
||||
const int IDX_UPDATED_CANVAS = 2;
|
||||
|
||||
QgsRasterMinMaxWidget::QgsRasterMinMaxWidget( QgsRasterLayer* theLayer, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
, mLayer( theLayer )
|
||||
, mCanvas( nullptr )
|
||||
, mLastRectangleValid( false )
|
||||
{
|
||||
QgsDebugMsg( "Entered." );
|
||||
setupUi( this );
|
||||
|
||||
QSettings mySettings;
|
||||
|
||||
// set contrast enhancement setting to default
|
||||
// ideally we should set it actual method last used to get min/max, but there is no way to know currently
|
||||
QString contrastEnchacementLimits = mySettings.value( QStringLiteral( "/Raster/defaultContrastEnhancementLimits" ), "CumulativeCut" ).toString();
|
||||
if ( contrastEnchacementLimits == QLatin1String( "MinMax" ) )
|
||||
mMinMaxRadioButton->setChecked( true );
|
||||
else if ( contrastEnchacementLimits == QLatin1String( "StdDev" ) )
|
||||
mStdDevRadioButton->setChecked( true );
|
||||
|
||||
double myLower = 100.0 * mySettings.value( QStringLiteral( "/Raster/cumulativeCutLower" ), QString::number( QgsRasterLayer::CUMULATIVE_CUT_LOWER ) ).toDouble();
|
||||
double myUpper = 100.0 * mySettings.value( QStringLiteral( "/Raster/cumulativeCutUpper" ), QString::number( QgsRasterLayer::CUMULATIVE_CUT_UPPER ) ).toDouble();
|
||||
mCumulativeCutLowerDoubleSpinBox->setValue( myLower );
|
||||
mCumulativeCutUpperDoubleSpinBox->setValue( myUpper );
|
||||
|
||||
mStdDevSpinBox->setValue( mySettings.value( QStringLiteral( "/Raster/defaultStandardDeviation" ), 2.0 ).toDouble() );
|
||||
QgsRasterMinMaxOrigin defaultMinMaxOrigin;
|
||||
setFromMinMaxOrigin( defaultMinMaxOrigin );
|
||||
}
|
||||
|
||||
QgsRasterMinMaxWidget::~QgsRasterMinMaxWidget()
|
||||
@ -66,7 +58,8 @@ QgsMapCanvas* QgsRasterMinMaxWidget::mapCanvas()
|
||||
|
||||
QgsRectangle QgsRasterMinMaxWidget::extent()
|
||||
{
|
||||
if ( !cbxClipExtent->isChecked() )
|
||||
const int nExtentIdx = mStatisticsExtentCombo->currentIndex();
|
||||
if ( nExtentIdx != IDX_CURRENT_CANVAS && nExtentIdx != IDX_UPDATED_CANVAS )
|
||||
return QgsRectangle();
|
||||
|
||||
if ( mLayer && mCanvas )
|
||||
@ -77,13 +70,126 @@ QgsRectangle QgsRasterMinMaxWidget::extent()
|
||||
return QgsRectangle();
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
|
||||
void QgsRasterMinMaxWidget::userHasSetManualMinMaxValues()
|
||||
{
|
||||
mUserDefinedRadioButton->setChecked( true );
|
||||
mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxWidget::on_mUserDefinedRadioButton_toggled( bool toggled )
|
||||
{
|
||||
mStatisticsExtentCombo->setEnabled( !toggled );
|
||||
cboAccuracy->setEnabled( !toggled );
|
||||
emit widgetChanged();
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxWidget::setFromMinMaxOrigin( const QgsRasterMinMaxOrigin& minMaxOrigin )
|
||||
{
|
||||
switch ( minMaxOrigin.limits() )
|
||||
{
|
||||
case QgsRasterMinMaxOrigin::None:
|
||||
default:
|
||||
mUserDefinedRadioButton->setChecked( true );
|
||||
break;
|
||||
|
||||
case QgsRasterMinMaxOrigin::MinMax:
|
||||
mMinMaxRadioButton->setChecked( true );
|
||||
break;
|
||||
|
||||
case QgsRasterMinMaxOrigin::StdDev:
|
||||
mStdDevRadioButton->setChecked( true );
|
||||
break;
|
||||
|
||||
case QgsRasterMinMaxOrigin::CumulativeCut:
|
||||
mCumulativeCutRadioButton->setChecked( true );
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( minMaxOrigin.extent() )
|
||||
{
|
||||
default:
|
||||
case QgsRasterMinMaxOrigin::WholeRaster:
|
||||
mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
|
||||
break;
|
||||
|
||||
case QgsRasterMinMaxOrigin::CurrentCanvas:
|
||||
mStatisticsExtentCombo->setCurrentIndex( IDX_CURRENT_CANVAS );
|
||||
break;
|
||||
|
||||
case QgsRasterMinMaxOrigin::UpdatedCanvas:
|
||||
mStatisticsExtentCombo->setCurrentIndex( IDX_UPDATED_CANVAS );
|
||||
break;
|
||||
}
|
||||
|
||||
mCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutLower() );
|
||||
mCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutUpper() );
|
||||
mStdDevSpinBox->setValue( minMaxOrigin.stdDevFactor() );
|
||||
|
||||
cboAccuracy->setCurrentIndex( minMaxOrigin.statAccuracy() == QgsRasterMinMaxOrigin::Estimated ? 0 : 1 );
|
||||
}
|
||||
|
||||
QgsRasterMinMaxOrigin QgsRasterMinMaxWidget::minMaxOrigin()
|
||||
{
|
||||
QgsRasterMinMaxOrigin minMaxOrigin;
|
||||
|
||||
if ( mMinMaxRadioButton->isChecked() )
|
||||
minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::MinMax );
|
||||
else if ( mStdDevRadioButton->isChecked() )
|
||||
minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::StdDev );
|
||||
else if ( mCumulativeCutRadioButton->isChecked() )
|
||||
minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::CumulativeCut );
|
||||
else
|
||||
minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::None );
|
||||
|
||||
switch ( mStatisticsExtentCombo->currentIndex() )
|
||||
{
|
||||
case IDX_WHOLE_RASTER:
|
||||
default:
|
||||
minMaxOrigin.setExtent( QgsRasterMinMaxOrigin::WholeRaster );
|
||||
break;
|
||||
case IDX_CURRENT_CANVAS:
|
||||
minMaxOrigin.setExtent( QgsRasterMinMaxOrigin::CurrentCanvas );
|
||||
break;
|
||||
case IDX_UPDATED_CANVAS:
|
||||
minMaxOrigin.setExtent( QgsRasterMinMaxOrigin::UpdatedCanvas );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( cboAccuracy->currentIndex() == 0 )
|
||||
minMaxOrigin.setStatAccuracy( QgsRasterMinMaxOrigin::Estimated );
|
||||
else
|
||||
minMaxOrigin.setStatAccuracy( QgsRasterMinMaxOrigin::Exact );
|
||||
|
||||
minMaxOrigin.setCumulativeCutLower(
|
||||
mCumulativeCutLowerDoubleSpinBox->value() / 100.0 );
|
||||
minMaxOrigin.setCumulativeCutUpper(
|
||||
mCumulativeCutUpperDoubleSpinBox->value() / 100.0 );
|
||||
minMaxOrigin.setStdDevFactor( mStdDevSpinBox->value() );
|
||||
|
||||
return minMaxOrigin;
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxWidget::doComputations()
|
||||
{
|
||||
QgsDebugMsg( "Entered." );
|
||||
|
||||
QgsRectangle myExtent = extent(); // empty == full
|
||||
int mySampleSize = sampleSize(); // 0 == exact
|
||||
|
||||
QgsRasterMinMaxOrigin newMinMaxOrigin = minMaxOrigin();
|
||||
if ( mLastRectangleValid && mLastRectangle == myExtent &&
|
||||
mLastMinMaxOrigin == newMinMaxOrigin )
|
||||
{
|
||||
QgsDebugMsg( "Does not need to redo statistics computations" );
|
||||
return;
|
||||
}
|
||||
|
||||
mLastRectangleValid = true;
|
||||
mLastRectangle = myExtent;
|
||||
mLastMinMaxOrigin = newMinMaxOrigin;
|
||||
|
||||
Q_FOREACH ( int myBand, mBands )
|
||||
{
|
||||
int origin = QgsRasterRenderer::MinMaxUnknown;
|
||||
QgsDebugMsg( QString( "myBand = %1" ).arg( myBand ) );
|
||||
if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
|
||||
{
|
||||
@ -92,56 +198,37 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
|
||||
double myMin = std::numeric_limits<double>::quiet_NaN();
|
||||
double myMax = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
QgsRectangle myExtent = extent(); // empty == full
|
||||
if ( cbxClipExtent->isChecked() )
|
||||
{
|
||||
origin |= QgsRasterRenderer::MinMaxSubExtent;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin |= QgsRasterRenderer::MinMaxFullExtent;
|
||||
}
|
||||
QgsDebugMsg( QString( "myExtent.isEmpty() = %1" ).arg( myExtent.isEmpty() ) );
|
||||
|
||||
int mySampleSize = sampleSize(); // 0 == exact
|
||||
if ( cboAccuracy->currentIndex() == 0 )
|
||||
{
|
||||
origin |= QgsRasterRenderer::MinMaxEstimated;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin |= QgsRasterRenderer::MinMaxExact;
|
||||
}
|
||||
|
||||
bool updateMinMax = false;
|
||||
if ( mCumulativeCutRadioButton->isChecked() )
|
||||
{
|
||||
updateMinMax = true;
|
||||
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() )
|
||||
{
|
||||
updateMinMax = true;
|
||||
// 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() )
|
||||
{
|
||||
updateMinMax = true;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning( this, tr( "No option selected" ), tr( "Please select an option to load min/max values." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
emit load( myBand, myMin, myMax, origin );
|
||||
if ( updateMinMax )
|
||||
emit load( myBand, myMin, myMax );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterMinMaxWidget::hideUpdatedExtent()
|
||||
{
|
||||
mStatisticsExtentCombo->removeItem( IDX_UPDATED_CANVAS );
|
||||
}
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include "ui_qgsrasterminmaxwidgetbase.h"
|
||||
#include "qgsrectangle.h"
|
||||
|
||||
#include "qgsraster.h"
|
||||
#include "qgsrasterminmaxorigin.h"
|
||||
#include "qgscontrastenhancement.h"
|
||||
|
||||
class QgsMapCanvas;
|
||||
class QgsRasterLayer;
|
||||
|
||||
@ -67,14 +71,49 @@ class GUI_EXPORT QgsRasterMinMaxWidget: public QWidget, private Ui::QgsRasterMin
|
||||
//! Return the selected sample size.
|
||||
int sampleSize() { return cboAccuracy->currentIndex() == 0 ? 250000 : 0; }
|
||||
|
||||
// Load programmaticaly with current values
|
||||
void load() { on_mLoadPushButton_clicked(); }
|
||||
//! \brief Set the "source" of min/max values.
|
||||
void setFromMinMaxOrigin( const QgsRasterMinMaxOrigin& );
|
||||
|
||||
//! \brief Return a QgsRasterMinMaxOrigin object with the widget values.
|
||||
QgsRasterMinMaxOrigin minMaxOrigin();
|
||||
|
||||
//! Hide updated extent choice
|
||||
void hideUpdatedExtent();
|
||||
|
||||
//! Load programmaticaly with current values
|
||||
void doComputations();
|
||||
|
||||
//! Uncheck cumulative cut, min/max, std-dev radio buttons
|
||||
void userHasSetManualMinMaxValues();
|
||||
|
||||
//! Return if the widget is collaped.
|
||||
bool isCollapsed() const { return mLoadMinMaxValuesGroupBox->isCollapsed(); }
|
||||
|
||||
//! Set collapsed state of widget
|
||||
void setCollapsed( bool b ) { mLoadMinMaxValuesGroupBox->setCollapsed( b ); }
|
||||
|
||||
signals:
|
||||
void load( int theBandNo, double theMin, double theMax, int origin );
|
||||
|
||||
/**
|
||||
* Emitted when something on the widget has changed.
|
||||
* All widgets will fire this event to notify of an internal change.
|
||||
*/
|
||||
void widgetChanged();
|
||||
|
||||
//! signal emitted when new min/max values are computed from statistics.
|
||||
void load( int theBandNo, double theMin, double theMax );
|
||||
|
||||
private slots:
|
||||
void on_mLoadPushButton_clicked();
|
||||
|
||||
void on_mUserDefinedRadioButton_toggled( bool );
|
||||
void on_mMinMaxRadioButton_toggled( bool b ) { if ( b ) emit widgetChanged(); }
|
||||
void on_mStdDevRadioButton_toggled( bool b ) { if ( b ) emit widgetChanged(); }
|
||||
void on_mCumulativeCutRadioButton_toggled( bool b ) { if ( b ) emit widgetChanged(); }
|
||||
void on_mStatisticsExtentCombo_currentIndexChanged( int ) { emit widgetChanged(); }
|
||||
void on_mCumulativeCutLowerDoubleSpinBox_valueChanged( double ) { emit widgetChanged(); }
|
||||
void on_mCumulativeCutUpperDoubleSpinBox_valueChanged( double ) { emit widgetChanged(); }
|
||||
void on_mStdDevSpinBox_valueChanged( double ) { emit widgetChanged(); }
|
||||
void on_cboAccuracy_currentIndexChanged( int ) { emit widgetChanged(); }
|
||||
|
||||
private:
|
||||
QgsRasterLayer* mLayer;
|
||||
@ -82,6 +121,10 @@ class GUI_EXPORT QgsRasterMinMaxWidget: public QWidget, private Ui::QgsRasterMin
|
||||
QgsRectangle mExtent;
|
||||
|
||||
QgsMapCanvas* mCanvas;
|
||||
|
||||
bool mLastRectangleValid;
|
||||
QgsRectangle mLastRectangle;
|
||||
QgsRasterMinMaxOrigin mLastMinMaxOrigin;
|
||||
};
|
||||
|
||||
#endif // QGSRASTERMINMAXWIDGET_H
|
||||
|
@ -25,6 +25,7 @@
|
||||
class QgsRasterLayer;
|
||||
class QgsRasterRenderer;
|
||||
class QgsMapCanvas;
|
||||
class QgsRasterMinMaxWidget;
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsRasterRendererWidget
|
||||
@ -44,14 +45,6 @@ class GUI_EXPORT QgsRasterRendererWidget: public QWidget
|
||||
|
||||
virtual ~QgsRasterRendererWidget() {}
|
||||
|
||||
enum LoadMinMaxAlgo
|
||||
{
|
||||
Estimate,
|
||||
Actual,
|
||||
CurrentExtent,
|
||||
CumulativeCut // 2 - 98% cumulative cut
|
||||
};
|
||||
|
||||
virtual QgsRasterRenderer* renderer() = 0;
|
||||
|
||||
void setRasterLayer( QgsRasterLayer* layer ) { mRasterLayer = layer; }
|
||||
@ -80,6 +73,12 @@ class GUI_EXPORT QgsRasterRendererWidget: public QWidget
|
||||
virtual void setStdDev( const QString& value ) { Q_UNUSED( value ); }
|
||||
virtual int selectedBand( int index = 0 ) { Q_UNUSED( index ); return -1; }
|
||||
|
||||
//! Load programmaticaly with current values
|
||||
virtual void doComputations() { }
|
||||
|
||||
//! Return min/max widget when it exists.
|
||||
virtual QgsRasterMinMaxWidget* minMaxWidget() { return nullptr; }
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "qgsrasterresamplefilter.h"
|
||||
#include "qgsbilinearrasterresampler.h"
|
||||
#include "qgscubicrasterresampler.h"
|
||||
#include "qgsmultibandcolorrenderer.h"
|
||||
#include "qgssinglebandgrayrenderer.h"
|
||||
|
||||
|
||||
static void _initRendererWidgetFunctions()
|
||||
@ -103,6 +105,8 @@ QgsRendererRasterPropertiesWidget::QgsRendererRasterPropertiesWidget( QgsMapLaye
|
||||
// finally sync to the layer - even though some actions may emit widgetChanged signal,
|
||||
// this is not a problem - nobody is listening to our signals yet
|
||||
syncToLayer( mRasterLayer );
|
||||
|
||||
connect( mRasterLayer, SIGNAL( styleChanged() ), this, SLOT( refreshAfterSyleChanged() ) );
|
||||
}
|
||||
|
||||
QgsRendererRasterPropertiesWidget::~QgsRendererRasterPropertiesWidget()
|
||||
@ -130,14 +134,15 @@ void QgsRendererRasterPropertiesWidget::apply()
|
||||
QgsRasterRendererWidget* rendererWidget = dynamic_cast<QgsRasterRendererWidget*>( stackedWidget->currentWidget() );
|
||||
if ( rendererWidget )
|
||||
{
|
||||
rendererWidget->doComputations();
|
||||
|
||||
QgsRasterRenderer* newRenderer = rendererWidget->renderer();
|
||||
|
||||
// there are transparency related data stored in renderer instances, but they
|
||||
// are not configured in the widget, so we need to copy them over from existing renderer
|
||||
QgsRasterRenderer* oldRenderer = mRasterLayer->renderer();
|
||||
if ( oldRenderer )
|
||||
newRenderer->copyCommonProperties( oldRenderer );
|
||||
|
||||
newRenderer->copyCommonProperties( oldRenderer, false );
|
||||
mRasterLayer->setRenderer( newRenderer );
|
||||
}
|
||||
|
||||
@ -360,3 +365,41 @@ void QgsRendererRasterPropertiesWidget::setRendererWidget( const QString &render
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QgsRendererRasterPropertiesWidget::refreshAfterSyleChanged()
|
||||
{
|
||||
if ( mRendererWidget )
|
||||
{
|
||||
QgsRasterRenderer* renderer = mRasterLayer->renderer();
|
||||
if ( QgsMultiBandColorRenderer* mbcr = dynamic_cast<QgsMultiBandColorRenderer*>( renderer ) )
|
||||
{
|
||||
const QgsContrastEnhancement* redCe = mbcr->redContrastEnhancement();
|
||||
if ( redCe )
|
||||
{
|
||||
mRendererWidget->setMin( QString::number( redCe->minimumValue() ), 0 );
|
||||
mRendererWidget->setMax( QString::number( redCe->maximumValue() ), 0 );
|
||||
}
|
||||
const QgsContrastEnhancement* greenCe = mbcr->greenContrastEnhancement();
|
||||
if ( greenCe )
|
||||
{
|
||||
mRendererWidget->setMin( QString::number( greenCe->minimumValue() ), 1 );
|
||||
mRendererWidget->setMax( QString::number( greenCe->maximumValue() ), 1 );
|
||||
}
|
||||
const QgsContrastEnhancement* blueCe = mbcr->blueContrastEnhancement();
|
||||
if ( blueCe )
|
||||
{
|
||||
mRendererWidget->setMin( QString::number( blueCe->minimumValue() ), 2 );
|
||||
mRendererWidget->setMax( QString::number( blueCe->maximumValue() ), 2 );
|
||||
}
|
||||
}
|
||||
else if ( QgsSingleBandGrayRenderer* sbgr = dynamic_cast<QgsSingleBandGrayRenderer*>( renderer ) )
|
||||
{
|
||||
const QgsContrastEnhancement* ce = sbgr->contrastEnhancement();
|
||||
if ( ce )
|
||||
{
|
||||
mRendererWidget->setMin( QString::number( ce->minimumValue() ) );
|
||||
mRendererWidget->setMax( QString::number( ce->maximumValue() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,9 @@ class GUI_EXPORT QgsRendererRasterPropertiesWidget : public QgsMapLayerConfigWid
|
||||
|
||||
//! Enable or disable colorize controls depending on checkbox
|
||||
void toggleColorizeControls( bool colorizeEnabled );
|
||||
|
||||
void refreshAfterSyleChanged();
|
||||
|
||||
private:
|
||||
void setRendererWidget( const QString& rendererName );
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
QgsSingleBandGrayRendererWidget::QgsSingleBandGrayRendererWidget( QgsRasterLayer* layer, const QgsRectangle &extent )
|
||||
: QgsRasterRendererWidget( layer, extent )
|
||||
, mMinMaxWidget( nullptr )
|
||||
, mDisableMinMaxWidgetRefresh( false )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
@ -50,8 +51,11 @@ QgsSingleBandGrayRendererWidget::QgsSingleBandGrayRendererWidget( QgsRasterLayer
|
||||
mMinMaxContainerWidget->setLayout( layout );
|
||||
layout->addWidget( mMinMaxWidget );
|
||||
|
||||
connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
|
||||
this, SLOT( loadMinMax( int, double, double, int ) ) );
|
||||
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged,
|
||||
this, &QgsSingleBandGrayRendererWidget::widgetChanged );
|
||||
|
||||
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::load,
|
||||
this, &QgsSingleBandGrayRendererWidget::loadMinMax );
|
||||
|
||||
//fill available bands into combo box
|
||||
int nBands = provider->bandCount();
|
||||
@ -98,27 +102,57 @@ QgsRasterRenderer* QgsSingleBandGrayRendererWidget::renderer()
|
||||
e->setMaximumValue( mMaxLineEdit->text().toDouble() );
|
||||
e->setContrastEnhancementAlgorithm(( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementComboBox->currentData().toInt() ) );
|
||||
|
||||
|
||||
QgsSingleBandGrayRenderer* renderer = new QgsSingleBandGrayRenderer( provider, band );
|
||||
renderer->setContrastEnhancement( e );
|
||||
|
||||
renderer->setGradient(( QgsSingleBandGrayRenderer::Gradient ) mGradientComboBox->currentData().toInt() );
|
||||
renderer->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::doComputations()
|
||||
{
|
||||
mMinMaxWidget->doComputations();
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::setMapCanvas( QgsMapCanvas* canvas )
|
||||
{
|
||||
QgsRasterRendererWidget::setMapCanvas( canvas );
|
||||
mMinMaxWidget->setMapCanvas( canvas );
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
|
||||
void QgsSingleBandGrayRendererWidget::on_mMinLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::on_mMaxLineEdit_textChanged( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::minMaxModified()
|
||||
{
|
||||
if ( !mDisableMinMaxWidgetRefresh )
|
||||
{
|
||||
if (( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
|
||||
{
|
||||
mContrastEnhancementComboBox->setCurrentIndex(
|
||||
mContrastEnhancementComboBox->findData(( int ) QgsContrastEnhancement::StretchToMinimumMaximum ) );
|
||||
}
|
||||
mMinMaxWidget->userHasSetManualMinMaxValues();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax )
|
||||
{
|
||||
Q_UNUSED( theBandNo );
|
||||
Q_UNUSED( theOrigin );
|
||||
|
||||
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
|
||||
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
if ( qIsNaN( theMin ) )
|
||||
{
|
||||
mMinLineEdit->clear();
|
||||
@ -136,12 +170,7 @@ void QgsSingleBandGrayRendererWidget::loadMinMax( int theBandNo, double theMin,
|
||||
{
|
||||
mMaxLineEdit->setText( QString::number( theMax ) );
|
||||
}
|
||||
|
||||
//automaticlly activate contrast enhancement algorithm if set to none
|
||||
if ( mContrastEnhancementComboBox->currentData().toInt() == QgsContrastEnhancement::NoEnhancement )
|
||||
{
|
||||
mContrastEnhancementComboBox->setCurrentIndex( mContrastEnhancementComboBox->findData( QgsContrastEnhancement::StretchToMinimumMaximum ) );
|
||||
}
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::on_mGrayBandComboBox_currentIndexChanged( int index )
|
||||
@ -163,10 +192,28 @@ void QgsSingleBandGrayRendererWidget::setFromRenderer( const QgsRasterRenderer*
|
||||
|
||||
mGradientComboBox->setCurrentIndex( mGradientComboBox->findData( gr->gradient() ) );
|
||||
//minmax
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
mMinLineEdit->setText( QString::number( ce->minimumValue() ) );
|
||||
mMaxLineEdit->setText( QString::number( ce->maximumValue() ) );
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
//contrast enhancement algorithm
|
||||
mContrastEnhancementComboBox->setCurrentIndex(
|
||||
mContrastEnhancementComboBox->findData(( int )( ce->contrastEnhancementAlgorithm() ) ) );
|
||||
|
||||
mMinMaxWidget->setFromMinMaxOrigin( gr->minMaxOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::setMin( const QString& value, int )
|
||||
{
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
mMinLineEdit->setText( value );
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::setMax( const QString& value, int )
|
||||
{
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
mMaxLineEdit->setText( value );
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
@ -42,18 +42,26 @@ class GUI_EXPORT QgsSingleBandGrayRendererWidget: public QgsRasterRendererWidget
|
||||
|
||||
QString min( int index = 0 ) override { Q_UNUSED( index ); return mMinLineEdit->text(); }
|
||||
QString max( int index = 0 ) override { Q_UNUSED( index ); return mMaxLineEdit->text(); }
|
||||
void setMin( const QString& value, int index = 0 ) override { Q_UNUSED( index ); mMinLineEdit->setText( value ); }
|
||||
void setMax( const QString& value, int index = 0 ) override { Q_UNUSED( index ); mMaxLineEdit->setText( value ); }
|
||||
void setMin( const QString& value, int index = 0 ) override;
|
||||
void setMax( const QString& value, int index = 0 ) override;
|
||||
int selectedBand( int index = 0 ) override { Q_UNUSED( index ); return mGrayBandComboBox->currentIndex() + 1; }
|
||||
void doComputations() override;
|
||||
QgsRasterMinMaxWidget* minMaxWidget() override { return mMinMaxWidget; }
|
||||
|
||||
public slots:
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
|
||||
//! called when new min/max values are loaded
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax );
|
||||
|
||||
private slots:
|
||||
void on_mGrayBandComboBox_currentIndexChanged( int index );
|
||||
void on_mMinLineEdit_textChanged( const QString & );
|
||||
void on_mMaxLineEdit_textChanged( const QString & );
|
||||
|
||||
private:
|
||||
QgsRasterMinMaxWidget * mMinMaxWidget;
|
||||
bool mDisableMinMaxWidgetRefresh;
|
||||
|
||||
void minMaxModified();
|
||||
};
|
||||
|
||||
#endif // QGSSINGLEBANDGRAYRENDERERWIDGET_H
|
||||
|
@ -42,6 +42,7 @@
|
||||
QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget( QgsRasterLayer* layer, const QgsRectangle &extent )
|
||||
: QgsRasterRendererWidget( layer, extent )
|
||||
, mMinMaxWidget( nullptr )
|
||||
, mDisableMinMaxWidgetRefresh( false )
|
||||
, mMinMaxOrigin( 0 )
|
||||
{
|
||||
QSettings settings;
|
||||
@ -84,9 +85,12 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
|
||||
layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
mMinMaxContainerWidget->setLayout( layout );
|
||||
layout->addWidget( mMinMaxWidget );
|
||||
connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
|
||||
this, SLOT( loadMinMax( int, double, double, int ) ) );
|
||||
|
||||
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged,
|
||||
this, &QgsSingleBandPseudoColorRendererWidget::widgetChanged );
|
||||
|
||||
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::load,
|
||||
this, &QgsSingleBandPseudoColorRendererWidget::loadMinMax );
|
||||
|
||||
//fill available bands into combo box
|
||||
int nBands = provider->bandCount();
|
||||
@ -111,7 +115,13 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
|
||||
// If there is currently no min/max, load default with user current default options
|
||||
if ( mMinLineEdit->text().isEmpty() || mMaxLineEdit->text().isEmpty() )
|
||||
{
|
||||
mMinMaxWidget->load();
|
||||
QgsRasterMinMaxOrigin minMaxOrigin = mMinMaxWidget->minMaxOrigin();
|
||||
if ( minMaxOrigin.limits() == QgsRasterMinMaxOrigin::None )
|
||||
{
|
||||
minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::MinMax );
|
||||
mMinMaxWidget->setFromMinMaxOrigin( minMaxOrigin );
|
||||
}
|
||||
mMinMaxWidget->doComputations();
|
||||
}
|
||||
|
||||
on_mClassificationModeComboBox_currentIndexChanged( 0 );
|
||||
@ -119,8 +129,6 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
|
||||
resetClassifyButton();
|
||||
|
||||
connect( mClassificationModeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( classify() ) );
|
||||
connect( mMinLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( classify() ) );
|
||||
connect( mMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( classify() ) );
|
||||
connect( mClassifyButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::applyColorRamp );
|
||||
connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsSingleBandPseudoColorRendererWidget::applyColorRamp );
|
||||
connect( mNumberOfEntriesSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( classify() ) );
|
||||
@ -175,10 +183,17 @@ QgsRasterRenderer* QgsSingleBandPseudoColorRendererWidget::renderer()
|
||||
|
||||
renderer->setClassificationMin( lineEditValue( mMinLineEdit ) );
|
||||
renderer->setClassificationMax( lineEditValue( mMaxLineEdit ) );
|
||||
renderer->setClassificationMinMaxOrigin( mMinMaxOrigin );
|
||||
renderer->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::doComputations()
|
||||
{
|
||||
mMinMaxWidget->doComputations();
|
||||
if ( mColormapTreeWidget->topLevelItemCount() == 0 )
|
||||
applyColorRamp();
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::setMapCanvas( QgsMapCanvas* canvas )
|
||||
{
|
||||
QgsRasterRendererWidget::setMapCanvas( canvas );
|
||||
@ -841,8 +856,8 @@ void QgsSingleBandPseudoColorRendererWidget::setFromRenderer( const QgsRasterRen
|
||||
}
|
||||
setLineEditValue( mMinLineEdit, pr->classificationMin() );
|
||||
setLineEditValue( mMaxLineEdit, pr->classificationMax() );
|
||||
mMinMaxOrigin = pr->classificationMinMaxOrigin();
|
||||
showMinMaxOrigin();
|
||||
|
||||
mMinMaxWidget->setFromMinMaxOrigin( pr->minMaxOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -885,11 +900,12 @@ void QgsSingleBandPseudoColorRendererWidget::on_mColorInterpolationComboBox_curr
|
||||
emit widgetChanged();
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
|
||||
void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax )
|
||||
{
|
||||
Q_UNUSED( theBandNo );
|
||||
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
|
||||
|
||||
mDisableMinMaxWidgetRefresh = true;
|
||||
if ( qIsNaN( theMin ) )
|
||||
{
|
||||
mMinLineEdit->clear();
|
||||
@ -907,14 +923,7 @@ void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int theBandNo, double t
|
||||
{
|
||||
mMaxLineEdit->setText( QString::number( theMax ) );
|
||||
}
|
||||
|
||||
mMinMaxOrigin = theOrigin;
|
||||
showMinMaxOrigin();
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::showMinMaxOrigin()
|
||||
{
|
||||
mMinMaxOriginLabel->setText( QgsRasterRenderer::minMaxOriginLabel( mMinMaxOrigin ) );
|
||||
mDisableMinMaxWidgetRefresh = false;
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( QLineEdit * theLineEdit, double theValue )
|
||||
@ -995,3 +1004,23 @@ void QgsSingleBandPseudoColorRendererWidget::changeTransparency()
|
||||
emit widgetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::on_mMinLineEdit_textEdited( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
classify();
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::on_mMaxLineEdit_textEdited( const QString & )
|
||||
{
|
||||
minMaxModified();
|
||||
classify();
|
||||
}
|
||||
|
||||
void QgsSingleBandPseudoColorRendererWidget::minMaxModified()
|
||||
{
|
||||
if ( !mDisableMinMaxWidgetRefresh )
|
||||
{
|
||||
mMinMaxWidget->userHasSetManualMinMaxValues();
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere
|
||||
static QgsRasterRendererWidget* create( QgsRasterLayer* layer, const QgsRectangle &theExtent ) { return new QgsSingleBandPseudoColorRendererWidget( layer, theExtent ); }
|
||||
QgsRasterRenderer* renderer() override;
|
||||
void setMapCanvas( QgsMapCanvas* canvas ) override;
|
||||
void doComputations() override;
|
||||
QgsRasterMinMaxWidget* minMaxWidget() override { return mMinMaxWidget; }
|
||||
|
||||
void setFromRenderer( const QgsRasterRenderer* r );
|
||||
|
||||
@ -57,7 +59,8 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere
|
||||
/** Executes the single band pseudo raster classficiation
|
||||
*/
|
||||
void classify();
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
|
||||
//! called when new min/max values are loaded
|
||||
void loadMinMax( int theBandNo, double theMin, double theMax );
|
||||
|
||||
private:
|
||||
|
||||
@ -87,10 +90,10 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere
|
||||
void mColormapTreeWidget_itemEdited( QTreeWidgetItem* item, int column );
|
||||
void on_mBandComboBox_currentIndexChanged( int index );
|
||||
void on_mColorInterpolationComboBox_currentIndexChanged( int index );
|
||||
void on_mMinLineEdit_textChanged( const QString & text ) { Q_UNUSED( text ); resetClassifyButton(); }
|
||||
void on_mMaxLineEdit_textChanged( const QString & text ) { Q_UNUSED( text ); resetClassifyButton(); }
|
||||
void on_mMinLineEdit_textEdited( const QString & text ) { Q_UNUSED( text ); mMinMaxOrigin = QgsRasterRenderer::MinMaxUser; showMinMaxOrigin(); }
|
||||
void on_mMaxLineEdit_textEdited( const QString & text ) { Q_UNUSED( text ); mMinMaxOrigin = QgsRasterRenderer::MinMaxUser; showMinMaxOrigin(); }
|
||||
void on_mMinLineEdit_textChanged( const QString & ) { resetClassifyButton(); }
|
||||
void on_mMaxLineEdit_textChanged( const QString & ) { resetClassifyButton(); }
|
||||
void on_mMinLineEdit_textEdited( const QString & text ) ;
|
||||
void on_mMaxLineEdit_textEdited( const QString & text ) ;
|
||||
void on_mClassificationModeComboBox_currentIndexChanged( int index );
|
||||
void changeColor();
|
||||
void changeTransparency();
|
||||
@ -100,10 +103,11 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere
|
||||
void setLineEditValue( QLineEdit *theLineEdit, double theValue );
|
||||
double lineEditValue( const QLineEdit *theLineEdit ) const;
|
||||
void resetClassifyButton();
|
||||
void showMinMaxOrigin();
|
||||
QgsRasterMinMaxWidget * mMinMaxWidget;
|
||||
bool mDisableMinMaxWidgetRefresh;
|
||||
int mMinMaxOrigin;
|
||||
|
||||
void minMaxModified();
|
||||
};
|
||||
|
||||
|
||||
|
@ -686,7 +686,7 @@ void QgsGeorefPluginGui::localHistogramStretch()
|
||||
{
|
||||
QgsRectangle rectangle = mIface->mapCanvas()->mapSettings().outputExtentToLayerExtent( mLayer, mIface->mapCanvas()->extent() );
|
||||
|
||||
mLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRaster::ContrastEnhancementMinMax, rectangle );
|
||||
mLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax, rectangle );
|
||||
mCanvas->refresh();
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>857</width>
|
||||
<height>658</height>
|
||||
<width>1029</width>
|
||||
<height>726</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
@ -308,7 +308,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="mOptionsStackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>8</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="mOptionsPageGeneral">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
@ -337,8 +337,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>712</width>
|
||||
<height>693</height>
|
||||
<width>723</width>
|
||||
<height>640</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_28">
|
||||
@ -1023,8 +1023,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>601</width>
|
||||
<height>877</height>
|
||||
<width>607</width>
|
||||
<height>850</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_22">
|
||||
@ -1456,8 +1456,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>741</height>
|
||||
<width>545</width>
|
||||
<height>694</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_27">
|
||||
@ -1813,9 +1813,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>735</width>
|
||||
<height>1038</height>
|
||||
<y>-299</y>
|
||||
<width>839</width>
|
||||
<height>982</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_22">
|
||||
@ -2233,45 +2233,67 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_3" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_22">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_37">
|
||||
<property name="text">
|
||||
<string>Single band gray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementAlgorithmSingleBand"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_23">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>208</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout_33">
|
||||
<item row="4" column="2">
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementLimitsMultiBandSingleByte"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_50">
|
||||
<property name="text">
|
||||
<string>Algorithm</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementAlgorithmSingleBand"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_37">
|
||||
<property name="text">
|
||||
<string>Single band gray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_51">
|
||||
<property name="text">
|
||||
<string>Limits (minimum/maximum)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementLimitsSingleBand"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementAlgorithmMultiBandSingleByte"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_38">
|
||||
<property name="text">
|
||||
<string>Multi band color (byte / band) </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_39">
|
||||
<property name="text">
|
||||
<string>Multi band color (> byte / band) </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementAlgorithmMultiBandMultiByte"/>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementLimitsMultiBandMultiByte"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_4" native="true">
|
||||
@ -2288,29 +2310,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_38">
|
||||
<property name="text">
|
||||
<string>Multi band color (byte / band) </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementAlgorithmMultiBandSingleByte"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_24">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>208</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -2329,29 +2328,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_39">
|
||||
<property name="text">
|
||||
<string>Multi band color (> byte / band) </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementAlgorithmMultiBandMultiByte"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_25">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>208</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -2377,29 +2353,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_40">
|
||||
<property name="text">
|
||||
<string>Limits (minimum/maximum)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboxContrastEnhancementLimits"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_26">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>208</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -2612,8 +2565,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>148</width>
|
||||
<height>276</height>
|
||||
<width>147</width>
|
||||
<height>240</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_46">
|
||||
@ -2759,8 +2712,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>526</width>
|
||||
<height>354</height>
|
||||
<width>528</width>
|
||||
<height>327</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_25">
|
||||
@ -3102,8 +3055,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>639</width>
|
||||
<height>668</height>
|
||||
<width>650</width>
|
||||
<height>612</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_30">
|
||||
@ -3533,8 +3486,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>522</width>
|
||||
<height>591</height>
|
||||
<width>514</width>
|
||||
<height>571</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_39">
|
||||
@ -3802,8 +3755,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>670</width>
|
||||
<height>718</height>
|
||||
<width>586</width>
|
||||
<height>701</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_31">
|
||||
@ -4357,8 +4310,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>457</width>
|
||||
<height>382</height>
|
||||
<width>474</width>
|
||||
<height>372</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
@ -4496,8 +4449,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>557</width>
|
||||
<height>677</height>
|
||||
<width>574</width>
|
||||
<height>644</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_15">
|
||||
@ -4579,7 +4532,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="radOtfNone">
|
||||
<property name="text">
|
||||
<string>Don't enable 'on the fly' reprojection</string>
|
||||
<string>Don't enable 'on the fl&y' reprojection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -4609,7 +4562,7 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="radOtfTransform">
|
||||
<property name="text">
|
||||
<string>Enable 'on the &fly' reprojection by default</string>
|
||||
<string>Enable 'on t&he fly' reprojection by default</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -4743,7 +4696,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>302</width>
|
||||
<height>238</height>
|
||||
<height>226</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_32">
|
||||
@ -4851,8 +4804,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>670</width>
|
||||
<height>793</height>
|
||||
<width>542</width>
|
||||
<height>737</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
||||
@ -5489,9 +5442,6 @@
|
||||
<tabstop>spnGreen</tabstop>
|
||||
<tabstop>spnBlue</tabstop>
|
||||
<tabstop>cboxContrastEnhancementAlgorithmSingleBand</tabstop>
|
||||
<tabstop>cboxContrastEnhancementAlgorithmMultiBandSingleByte</tabstop>
|
||||
<tabstop>cboxContrastEnhancementAlgorithmMultiBandMultiByte</tabstop>
|
||||
<tabstop>cboxContrastEnhancementLimits</tabstop>
|
||||
<tabstop>mRasterCumulativeCutLowerDoubleSpinBox</tabstop>
|
||||
<tabstop>mRasterCumulativeCutUpperDoubleSpinBox</tabstop>
|
||||
<tabstop>spnThreeBandStdDev</tabstop>
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>316</width>
|
||||
<height>300</height>
|
||||
<width>324</width>
|
||||
<height>250</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -45,202 +45,211 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mCumulativeCutRadioButton">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="mUserDefinedRadioButton">
|
||||
<property name="text">
|
||||
<string>Cumulative
|
||||
count cut</string>
|
||||
<string>Use&r defined</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">buttonGroup</string>
|
||||
<string notr="true">mMinMaxMethodRadioButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mCumulativeCutLowerDoubleSpinBox">
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mCumulativeCutRadioButton">
|
||||
<property name="text">
|
||||
<string>Cumula&tive
|
||||
count cut</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">mMinMaxMethodRadioButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mCumulativeCutLowerDoubleSpinBox">
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mCumulativeCutUpperDoubleSpinBox">
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>123</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mStdDevRadioButton">
|
||||
<property name="text">
|
||||
<string>Mean +/-
|
||||
standard de&viation ×</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">mMinMaxMethodRadioButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mStdDevSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>123</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mCumulativeCutUpperDoubleSpinBox">
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>123</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="mMinMaxRadioButton">
|
||||
<property name="text">
|
||||
<string>Min / max</string>
|
||||
<string>&Min / max</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">buttonGroup</string>
|
||||
<string notr="true">mMinMaxMethodRadioButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
<item row="6" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="mStatisticsExtentCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Whole raster</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Current canvas</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Updated canvas</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mStatisticsExtentLabel">
|
||||
<property name="text">
|
||||
<string>Statistics extent</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="mAccuracyLabel">
|
||||
<property name="text">
|
||||
<string>Accuracy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cboAccuracy">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Estimate (faster)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Actual (slower)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mStdDevRadioButton">
|
||||
<property name="text">
|
||||
<string>Mean +/-
|
||||
standard deviation ×</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">buttonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mStdDevSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
<item>
|
||||
<widget class="QPushButton" name="mLoadPushButton">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mColorInterpolationLabel_2">
|
||||
<property name="text">
|
||||
<string>Accuracy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboAccuracy">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Estimate (faster)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Actual (slower)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxClipExtent">
|
||||
<property name="text">
|
||||
<string>Clip extent to canvas</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
||||
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBox</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mUserDefinedRadioButton</tabstop>
|
||||
<tabstop>mCumulativeCutRadioButton</tabstop>
|
||||
<tabstop>mCumulativeCutLowerDoubleSpinBox</tabstop>
|
||||
<tabstop>mCumulativeCutUpperDoubleSpinBox</tabstop>
|
||||
<tabstop>mMinMaxRadioButton</tabstop>
|
||||
<tabstop>mStdDevRadioButton</tabstop>
|
||||
<tabstop>mStdDevSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="buttonGroup"/>
|
||||
<buttongroup name="mMinMaxMethodRadioButtonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
@ -26,6 +26,46 @@
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="6" column="0" colspan="5">
|
||||
<widget class="QTreeWidget" name="mColormapTreeWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>70</number>
|
||||
</attribute>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>10</number>
|
||||
</attribute>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Label</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="4">
|
||||
<widget class="QgsColorRampButton" name="btnColorRamp">
|
||||
<property name="sizePolicy">
|
||||
@ -60,12 +100,12 @@
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="mMinLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min</string>
|
||||
</property>
|
||||
@ -74,6 +114,9 @@
|
||||
<item row="3" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="mColorInterpolationComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="mBandComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mBandLabel">
|
||||
<property name="text">
|
||||
@ -81,17 +124,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="mBandComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="mMaxLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
@ -104,7 +144,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="5">
|
||||
<item row="8" column="0" colspan="5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="mClassifyButton">
|
||||
@ -183,28 +223,10 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Min / max
|
||||
origin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="mMinLineEdit"/>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="4">
|
||||
<widget class="QLabel" name="mMinMaxOriginLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min / Max origin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="5">
|
||||
<item row="9" column="0" colspan="5">
|
||||
<widget class="QCheckBox" name="mClipCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>If checked, any pixels with a value out of range will not be rendered</string>
|
||||
@ -214,10 +236,7 @@ origin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="mMinLineEdit"/>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="5">
|
||||
<item row="7" column="0" colspan="5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="mClassificationModeLabel">
|
||||
@ -257,12 +276,12 @@ origin:</string>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
@ -270,49 +289,6 @@ origin:</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="5">
|
||||
<widget class="QWidget" name="mMinMaxContainerWidget" native="true"/>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="5">
|
||||
<widget class="QTreeWidget" name="mColormapTreeWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>70</number>
|
||||
</attribute>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>10</number>
|
||||
</attribute>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Label</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="mUnitLineEdit">
|
||||
<property name="toolTip">
|
||||
@ -320,6 +296,9 @@ origin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="5">
|
||||
<widget class="QWidget" name="mMinMaxContainerWidget" native="true"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="mUnitLabel">
|
||||
<property name="text">
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
//qgis unit test includes
|
||||
#include <qgsrenderchecker.h>
|
||||
#include "qgstestutils.h"
|
||||
|
||||
/** \ingroup UnitTests
|
||||
* This is a unit test for the QgsRasterLayer class.
|
||||
@ -90,6 +91,7 @@ class TestQgsRasterLayer : public QObject
|
||||
void multiBandColorRenderer();
|
||||
void setRenderer();
|
||||
void regression992(); //test for issue #992 - GeoJP2 images improperly displayed as all black
|
||||
void testRefreshRendererIfNeeded();
|
||||
|
||||
|
||||
private:
|
||||
@ -206,7 +208,7 @@ void TestQgsRasterLayer::cleanupTestCase()
|
||||
void TestQgsRasterLayer::isValid()
|
||||
{
|
||||
QVERIFY( mpRasterLayer->isValid() );
|
||||
mpRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRaster::ContrastEnhancementMinMax );
|
||||
mpRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax );
|
||||
mMapSettings->setExtent( mpRasterLayer->extent() );
|
||||
QVERIFY( render( "raster" ) );
|
||||
}
|
||||
@ -355,7 +357,7 @@ void TestQgsRasterLayer::colorRamp4()
|
||||
void TestQgsRasterLayer::landsatBasic()
|
||||
{
|
||||
QVERIFY2( mpLandsatRasterLayer->isValid(), "landsat.tif layer is not valid!" );
|
||||
mpLandsatRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRaster::ContrastEnhancementMinMax );
|
||||
mpLandsatRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax );
|
||||
mMapSettings->setLayers( QList<QgsMapLayer*>() << mpLandsatRasterLayer );
|
||||
mMapSettings->setExtent( mpLandsatRasterLayer->extent() );
|
||||
QVERIFY( render( "landsat_basic" ) );
|
||||
@ -632,7 +634,7 @@ void TestQgsRasterLayer::transparency()
|
||||
QVERIFY( mpFloat32RasterLayer->isValid() );
|
||||
QgsSingleBandGrayRenderer* renderer = new QgsSingleBandGrayRenderer( mpRasterLayer->dataProvider(), 1 );
|
||||
mpFloat32RasterLayer->setRenderer( renderer );
|
||||
mpFloat32RasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRaster::ContrastEnhancementMinMax );
|
||||
mpFloat32RasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax );
|
||||
|
||||
qDebug( "contrastEnhancement.minimumValue = %.17g", renderer->contrastEnhancement()->minimumValue() );
|
||||
qDebug( "contrastEnhancement.maximumValue = %.17g", renderer->contrastEnhancement()->maximumValue() );
|
||||
@ -695,5 +697,31 @@ void TestQgsRasterLayer::regression992()
|
||||
QVERIFY( render( "raster_geojp2", 400 ) );
|
||||
}
|
||||
|
||||
void TestQgsRasterLayer::testRefreshRendererIfNeeded()
|
||||
{
|
||||
QVERIFY2( mpLandsatRasterLayer->isValid(), "landsat.tif layer is not valid!" );
|
||||
mpLandsatRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax );
|
||||
mMapSettings->setLayers( QList<QgsMapLayer*>() << mpLandsatRasterLayer );
|
||||
mMapSettings->setExtent( mpLandsatRasterLayer->extent() );
|
||||
double initMinVal = dynamic_cast<QgsMultiBandColorRenderer*>( mpLandsatRasterLayer->renderer() )->redContrastEnhancement()->minimumValue();
|
||||
|
||||
// Should do nothing
|
||||
QgsRectangle newExtent = QgsRectangle( 785000, 3340000, 785100, 3340100 );
|
||||
mpLandsatRasterLayer->refreshRendererIfNeeded( mpLandsatRasterLayer->renderer(), newExtent );
|
||||
QCOMPARE( mpLandsatRasterLayer->renderer()->minMaxOrigin().limits(), QgsRasterMinMaxOrigin::MinMax );
|
||||
double minVal = dynamic_cast<QgsMultiBandColorRenderer*>( mpLandsatRasterLayer->renderer() )->redContrastEnhancement()->minimumValue();
|
||||
QGSCOMPARENEAR( initMinVal, minVal, 1e-5 );
|
||||
|
||||
// Change to UpdatedCanvas
|
||||
QgsRasterMinMaxOrigin mmo = mpLandsatRasterLayer->renderer()->minMaxOrigin();
|
||||
mmo.setExtent( QgsRasterMinMaxOrigin::UpdatedCanvas );
|
||||
mmo.setStatAccuracy( QgsRasterMinMaxOrigin::Exact );
|
||||
mpLandsatRasterLayer->renderer()->setMinMaxOrigin( mmo );
|
||||
QCOMPARE( mpLandsatRasterLayer->renderer()->minMaxOrigin().extent(), QgsRasterMinMaxOrigin::UpdatedCanvas );
|
||||
mpLandsatRasterLayer->refreshRendererIfNeeded( mpLandsatRasterLayer->renderer(), newExtent );
|
||||
double newMinVal = dynamic_cast<QgsMultiBandColorRenderer*>( mpLandsatRasterLayer->renderer() )->redContrastEnhancement()->minimumValue();
|
||||
QGSCOMPARENOTNEAR( initMinVal, newMinVal, 1e-5 );
|
||||
}
|
||||
|
||||
QTEST_MAIN( TestQgsRasterLayer )
|
||||
#include "testqgsrasterlayer.moc"
|
||||
|
@ -19,6 +19,7 @@ import os
|
||||
|
||||
from qgis.PyQt.QtCore import QFileInfo
|
||||
from qgis.PyQt.QtGui import QColor
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
|
||||
from qgis.core import (QgsRaster,
|
||||
QgsRasterLayer,
|
||||
@ -27,6 +28,7 @@ from qgis.core import (QgsRaster,
|
||||
QgsProject,
|
||||
QgsMapSettings,
|
||||
QgsPoint,
|
||||
QgsRasterMinMaxOrigin,
|
||||
QgsRasterShader,
|
||||
QgsRasterTransparency,
|
||||
QgsRenderChecker,
|
||||
@ -89,7 +91,7 @@ class TestQgsRasterLayer(unittest.TestCase):
|
||||
myRasterLayer.setRenderer(renderer)
|
||||
myRasterLayer.setContrastEnhancement(
|
||||
QgsContrastEnhancement.StretchToMinimumMaximum,
|
||||
QgsRaster.ContrastEnhancementMinMax)
|
||||
QgsRasterMinMaxOrigin.MinMax)
|
||||
|
||||
myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement()
|
||||
# print ("myContrastEnhancement.minimumValue = %.17g" %
|
||||
@ -229,5 +231,62 @@ class TestQgsRasterLayer(unittest.TestCase):
|
||||
assert self.rendererChanged
|
||||
assert layer.renderer() == r
|
||||
|
||||
def testQgsRasterMinMaxOrigin(self):
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
mmo_default = QgsRasterMinMaxOrigin()
|
||||
self.assertEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
self.assertEqual(mmo.limits(), QgsRasterMinMaxOrigin.None_)
|
||||
mmo.setLimits(QgsRasterMinMaxOrigin.CumulativeCut)
|
||||
self.assertEqual(mmo.limits(), QgsRasterMinMaxOrigin.CumulativeCut)
|
||||
self.assertNotEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
self.assertEqual(mmo.extent(), QgsRasterMinMaxOrigin.WholeRaster)
|
||||
mmo.setExtent(QgsRasterMinMaxOrigin.UpdatedCanvas)
|
||||
self.assertEqual(mmo.extent(), QgsRasterMinMaxOrigin.UpdatedCanvas)
|
||||
self.assertNotEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
self.assertEqual(mmo.statAccuracy(), QgsRasterMinMaxOrigin.Estimated)
|
||||
mmo.setStatAccuracy(QgsRasterMinMaxOrigin.Exact)
|
||||
self.assertEqual(mmo.statAccuracy(), QgsRasterMinMaxOrigin.Exact)
|
||||
self.assertNotEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
self.assertAlmostEqual(mmo.cumulativeCutLower(), 0.02)
|
||||
mmo.setCumulativeCutLower(0.1)
|
||||
self.assertAlmostEqual(mmo.cumulativeCutLower(), 0.1)
|
||||
self.assertNotEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
self.assertAlmostEqual(mmo.cumulativeCutUpper(), 0.98)
|
||||
mmo.setCumulativeCutUpper(0.9)
|
||||
self.assertAlmostEqual(mmo.cumulativeCutUpper(), 0.9)
|
||||
self.assertNotEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
self.assertAlmostEqual(mmo.stdDevFactor(), 2.0)
|
||||
mmo.setStdDevFactor(2.5)
|
||||
self.assertAlmostEqual(mmo.stdDevFactor(), 2.5)
|
||||
self.assertNotEqual(mmo, mmo_default)
|
||||
|
||||
mmo = QgsRasterMinMaxOrigin()
|
||||
mmo.setLimits(QgsRasterMinMaxOrigin.CumulativeCut)
|
||||
mmo.setExtent(QgsRasterMinMaxOrigin.UpdatedCanvas)
|
||||
mmo.setStatAccuracy(QgsRasterMinMaxOrigin.Exact)
|
||||
mmo.setCumulativeCutLower(0.1)
|
||||
mmo.setCumulativeCutUpper(0.9)
|
||||
mmo.setStdDevFactor(2.5)
|
||||
doc = QDomDocument()
|
||||
parentElem = doc.createElement("test")
|
||||
mmo.writeXml(doc, parentElem)
|
||||
mmoUnserialized = QgsRasterMinMaxOrigin()
|
||||
mmoUnserialized.readXml(parentElem)
|
||||
self.assertEqual(mmo, mmoUnserialized)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user