diff --git a/images/images.qrc b/images/images.qrc
index 040731dccaa..42c46d02989 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -79,6 +79,7 @@
themes/default/mActionFormAnnotation.png
themes/default/mActionFreezeLabels.png
themes/default/mActionFromSelectedFeature.png
+ themes/default/mActionFullCumulativeCutStretch.png
themes/default/mActionFullHistogramStretch.png
themes/default/mActionGroupItems.png
themes/default/mActionHelpAbout.png
@@ -91,6 +92,7 @@
themes/default/mActionInvertSelection.png
themes/default/mActionLabeling.png
themes/default/mActionLabel.png
+ themes/default/mActionLocalCumulativeCutStretch.png
themes/default/mActionLocalHistogramStretch.png
themes/default/mActionLowerItems.png
themes/default/mActionMapTips.png
diff --git a/images/themes/default/mActionFullCumulativeCutStretch.png b/images/themes/default/mActionFullCumulativeCutStretch.png
new file mode 100644
index 00000000000..7f98110f5b1
Binary files /dev/null and b/images/themes/default/mActionFullCumulativeCutStretch.png differ
diff --git a/images/themes/default/mActionLocalCumulativeCutStretch.png b/images/themes/default/mActionLocalCumulativeCutStretch.png
new file mode 100644
index 00000000000..c7f2e61d15b
Binary files /dev/null and b/images/themes/default/mActionLocalCumulativeCutStretch.png differ
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index 0521ac99e10..8aac076b405 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -963,6 +963,8 @@ void QgisApp::createActions()
// Raster toolbar items
connect( mActionLocalHistogramStretch, SIGNAL( triggered() ), this, SLOT( localHistogramStretch() ) );
connect( mActionFullHistogramStretch, SIGNAL( triggered() ), this, SLOT( fullHistogramStretch() ) );
+ connect( mActionLocalCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( localCumulativeCutStretch() ) );
+ connect( mActionFullCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( fullCumulativeCutStretch() ) );
// Help Menu Items
@@ -5461,14 +5463,29 @@ void QgisApp::options()
void QgisApp::fullHistogramStretch()
{
- histogramStretch( false );
+ histogramStretch( false, QgsRasterLayer::ContrastEnhancementMinMax );
}
-void QgisApp::histogramStretch( bool visibleAreaOnly )
+void QgisApp::localHistogramStretch()
{
- QgsMapLayer * layer = mMapLegend->currentLayer();
+ histogramStretch( true, QgsRasterLayer::ContrastEnhancementMinMax );
+}
- if ( !layer )
+void QgisApp::fullCumulativeCutStretch()
+{
+ histogramStretch( false, QgsRasterLayer::ContrastEnhancementCumulativeCut );
+}
+
+void QgisApp::localCumulativeCutStretch()
+{
+ histogramStretch( true, QgsRasterLayer::ContrastEnhancementCumulativeCut );
+}
+
+void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRasterLayer::ContrastEnhancementLimits theLimits )
+{
+ QgsMapLayer * myLayer = mMapLegend->currentLayer();
+
+ if ( !myLayer )
{
QMessageBox::information( this,
tr( "No Layer Selected" ),
@@ -5476,8 +5493,8 @@ void QgisApp::histogramStretch( bool visibleAreaOnly )
return;
}
- QgsRasterLayer* rlayer = qobject_cast( layer );
- if ( !rlayer )
+ QgsRasterLayer* myRasterLayer = qobject_cast( myLayer );
+ if ( !myRasterLayer )
{
QMessageBox::information( this,
tr( "No Raster Layer Selected" ),
@@ -5485,118 +5502,14 @@ void QgisApp::histogramStretch( bool visibleAreaOnly )
return;
}
- QgsRasterDataProvider* provider = rlayer->dataProvider();
- if ( !provider )
- {
- return;
- }
+ QgsRectangle myRectangle;
+ if ( visibleAreaOnly ) myRectangle = mMapCanvas->mapRenderer()->outputExtentToLayerExtent( myRasterLayer, mMapCanvas->extent() );
- //get renderer
- QgsRasterRenderer* renderer = rlayer->renderer();
- if ( !renderer )
- {
- return;
- }
-
- //singleband gray <-> multiband color
- if ( renderer->type() == "singlebandgray" )
- {
- QgsSingleBandGrayRenderer* grayRenderer = static_cast( renderer );
- if ( !grayRenderer )
- {
- return;
- }
-
- //create new contrast enhancements
- int grayBand = grayRenderer->grayBand();
- if ( grayBand == -1 )
- {
- return;
- }
-
- QgsContrastEnhancement* e = rasterContrastEnhancement( rlayer, grayBand, visibleAreaOnly );
- if ( !e )
- {
- return;
- }
- grayRenderer->setContrastEnhancement( e );
- }
- else if ( renderer->type() == "multibandcolor" )
- {
- QgsMultiBandColorRenderer* colorRenderer = static_cast( renderer );
- if ( !colorRenderer )
- {
- return;
- }
-
- QgsContrastEnhancement* redEnhancement = rasterContrastEnhancement( rlayer, colorRenderer->redBand(), visibleAreaOnly );
- if ( redEnhancement )
- {
- colorRenderer->setRedContrastEnhancement( redEnhancement );
- }
- QgsContrastEnhancement* greenEnhancement = rasterContrastEnhancement( rlayer, colorRenderer->greenBand(), visibleAreaOnly );
- if ( greenEnhancement )
- {
- colorRenderer->setGreenContrastEnhancement( greenEnhancement );
- }
- QgsContrastEnhancement* blueEnhancement = rasterContrastEnhancement( rlayer, colorRenderer->blueBand(), visibleAreaOnly );
- if ( blueEnhancement )
- {
- colorRenderer->setBlueContrastEnhancement( blueEnhancement );
- }
- }
- else
- {
- return;
- }
+ myRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, theLimits, myRectangle );
mMapCanvas->refresh();
}
-QgsContrastEnhancement* QgisApp::rasterContrastEnhancement( QgsRasterLayer* rlayer, int band,
- bool visibleAreaOnly ) const
-{
- if ( !rlayer || band == -1 )
- {
- return 0;
- }
-
- QgsRasterDataProvider* provider = rlayer->dataProvider();
- if ( !provider )
- {
- return 0;
- }
-
- QgsContrastEnhancement* e = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )(
- provider->dataType( band ) ) );
- double minValue = 0;
- double maxValue = 0;
-
- if ( visibleAreaOnly )
- {
- double minMax[2];
- rlayer->computeMinimumMaximumFromLastExtent( band, minMax );
- minValue = minMax[0];
- maxValue = minMax[1];
- }
- else
- {
- QgsRasterBandStats rasterBandStats = rlayer->dataProvider()->bandStatistics( band );
- minValue = rasterBandStats.minimumValue;
- maxValue = rasterBandStats.maximumValue;
- }
-
- e->setMinimumValue( minValue );
- e->setMaximumValue( maxValue );
- e->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum );
- return e;
-}
-
-void QgisApp::localHistogramStretch()
-{
- histogramStretch( true );
-}
-
void QgisApp::helpContents()
{
openURL( "index.html" );
diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h
index 06f4c032d01..42480ee9d61 100644
--- a/src/app/qgisapp.h
+++ b/src/app/qgisapp.h
@@ -55,7 +55,6 @@ class QgsPalLabeling;
class QgsPoint;
class QgsProviderRegistry;
class QgsPythonUtils;
-class QgsRasterLayer;
class QgsRectangle;
class QgsUndoWidget;
class QgsVectorLayer;
@@ -87,6 +86,7 @@ class QgsTileScaleWidget;
#include "qgsconfig.h"
#include "qgsfeature.h"
#include "qgspoint.h"
+#include "qgsrasterlayer.h"
#include "qgssnappingdialog.h"
#include "ui_qgisapp.h"
@@ -548,6 +548,10 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
* Valid for non wms raster layers only.
* @note Added in QGIS 1.7 */
void fullHistogramStretch();
+ /** Perform a local cumulative cut stretch */
+ void localCumulativeCutStretch();
+ /** Perform a full extent cumulative cut stretch */
+ void fullCumulativeCutStretch();
//! plugin manager
void showPluginManager();
//! load python support if possible
@@ -992,10 +996,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void createDecorations();
/**Do histogram stretch for singleband gray / multiband color rasters*/
- void histogramStretch( bool visibleAreaOnly = false );
- /**Create raster enhancement object for a raster band*/
- QgsContrastEnhancement* rasterContrastEnhancement( QgsRasterLayer* rlayer, int band,
- bool visibleAreaOnly = false ) const;
+ void histogramStretch( bool visibleAreaOnly = false, QgsRasterLayer::ContrastEnhancementLimits theLimits = QgsRasterLayer::ContrastEnhancementMinMax );
// actions for menus and toolbars -----------------
diff --git a/src/core/qgsrasterdataprovider.cpp b/src/core/qgsrasterdataprovider.cpp
index a4b60554c0b..9efeac2c088 100644
--- a/src/core/qgsrasterdataprovider.cpp
+++ b/src/core/qgsrasterdataprovider.cpp
@@ -435,7 +435,15 @@ void QgsRasterDataProvider::initStatistics( QgsRasterBandStats &theStatistics,
theStatistics.bandNumber = theBandNo;
theStatistics.statsGathered = theStats;
- QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
+ QgsRectangle myExtent;
+ if ( theExtent.isEmpty() )
+ {
+ myExtent = extent();
+ }
+ else
+ {
+ myExtent = extent().intersect( &theExtent );
+ }
theStatistics.extent = myExtent;
if ( theSampleSize > 0 )
@@ -674,7 +682,15 @@ void QgsRasterDataProvider::initHistogram( QgsRasterHistogram &theHistogram,
}
}
- QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
+ QgsRectangle myExtent;
+ if ( theExtent.isEmpty() )
+ {
+ myExtent = extent();
+ }
+ else
+ {
+ myExtent = extent().intersect( &theExtent );
+ }
theHistogram.extent = myExtent;
if ( theSampleSize > 0 )
diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp
index a503c560f9b..75d3af40ce5 100644
--- a/src/core/raster/qgsrasterlayer.cpp
+++ b/src/core/raster/qgsrasterlayer.cpp
@@ -96,6 +96,10 @@ typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QStrin
// doubles can take for the current system. (Yes, 20 was arbitrary.)
#define TINY_VALUE std::numeric_limits::epsilon() * 20
+const double QgsRasterLayer::CUMULATIVE_CUT_LOWER = 0.02;
+const double QgsRasterLayer::CUMULATIVE_CUT_UPPER = 0.98;
+const double QgsRasterLayer::SAMPLE_SIZE = 250000;
+
QgsRasterLayer::QgsRasterLayer()
: QgsMapLayer( RasterLayer )
, QSTRING_NOT_SET( "Not Set" )
@@ -1845,71 +1849,91 @@ void QgsRasterLayer::setColorShadingAlgorithm( QString )
void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, bool theGenerateLookupTableFlag )
{
+ setContrastEnhancementAlgorithm( theAlgorithm, ContrastEnhancementMinMax, QgsRectangle(), SAMPLE_SIZE, theGenerateLookupTableFlag );
+}
+
+void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, ContrastEnhancementLimits theLimits, QgsRectangle theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
+{
+ QgsDebugMsg( QString( "theAlgorithm = %1 theLimits = %2 theExtent.isEmpty() = %3" ).arg( theAlgorithm ).arg( theLimits ).arg( theExtent.isEmpty() ) );
if ( !mPipe.renderer() || !mDataProvider )
{
return;
}
+ QList myBands;
+ QList myEnhancements;
+ QgsSingleBandGrayRenderer* myGrayRenderer = 0;
+ QgsMultiBandColorRenderer* myMultiBandRenderer = 0;
QString rendererType = mPipe.renderer()->type();
if ( rendererType == "singlebandgray" )
{
- QgsSingleBandGrayRenderer* gr = dynamic_cast( mPipe.renderer() );
- if ( gr )
- {
- int grayBand = gr->grayBand();
- if ( grayBand == -1 )
- {
- return;
- }
- QgsRasterDataProvider::DataType dataType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( grayBand );
- QgsContrastEnhancement* ce = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )dataType );
- ce->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
- ce->setMinimumValue( mDataProvider->minimumValue( grayBand ) );
- ce->setMaximumValue( mDataProvider->maximumValue( grayBand ) );
- gr->setContrastEnhancement( ce );
- }
+ myGrayRenderer = dynamic_cast( mPipe.renderer() );
+ if ( !myGrayRenderer ) return;
+ myBands << myGrayRenderer->grayBand();
}
else if ( rendererType == "multibandcolor" )
{
- QgsMultiBandColorRenderer* cr = dynamic_cast( mPipe.renderer() );
- if ( cr )
+ myMultiBandRenderer = dynamic_cast( mPipe.renderer() );
+ if ( !myMultiBandRenderer ) return;
+ myBands << myMultiBandRenderer->redBand() << myMultiBandRenderer->greenBand() << myMultiBandRenderer->blueBand();
+ }
+
+ foreach( int myBand, myBands )
+ {
+ if ( myBand != -1 )
{
- //red enhancement
- int redBand = cr->redBand();
- if ( redBand != -1 )
+ QgsRasterDataProvider::DataType myType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( myBand );
+ QgsContrastEnhancement* myEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )myType );
+ myEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
+
+ double myMin = std::numeric_limits::quiet_NaN();
+ double myMax = std::numeric_limits::quiet_NaN();
+
+ if ( theLimits == ContrastEnhancementMinMax )
{
- QgsRasterDataProvider::DataType redType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( redBand );
- QgsContrastEnhancement* redEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )redType );
- redEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
- redEnhancement->setMinimumValue( mDataProvider->minimumValue( redBand ) );
- redEnhancement->setMaximumValue( mDataProvider->maximumValue( redBand ) );
- cr->setRedContrastEnhancement( redEnhancement );
+ // minimumValue/maximumValue are not well defined (estimation) and will be removed
+ //myMin = mDataProvider->minimumValue( myBand );
+ //myMax = mDataProvider->maximumValue( myBand );
+ QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, theExtent, theSampleSize );
+ myMin = myRasterBandStats.minimumValue;
+ myMax = myRasterBandStats.maximumValue;
+ }
+ else if ( theLimits == 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 == ContrastEnhancementCumulativeCut )
+ {
+ QSettings mySettings;
+ double myLower = mySettings.value( "/Raster/cumulativeCutLower", QString::number( CUMULATIVE_CUT_LOWER ) ).toDouble();
+ double myUpper = mySettings.value( "/Raster/cumulativeCutUpper", QString::number( CUMULATIVE_CUT_UPPER ) ).toDouble();
+ QgsDebugMsg( QString( "myLower = %1 myUpper = %2" ).arg( myLower ).arg( myUpper ) );
+ mDataProvider->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, theExtent, theSampleSize );
}
- //green enhancement
- int greenBand = cr->greenBand();
- if ( greenBand != -1 )
- {
- QgsRasterDataProvider::DataType greenType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( cr->greenBand() );
- QgsContrastEnhancement* greenEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )greenType );
- greenEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
- greenEnhancement->setMinimumValue( mDataProvider->minimumValue( greenBand ) );
- greenEnhancement->setMaximumValue( mDataProvider->maximumValue( greenBand ) );
- cr->setGreenContrastEnhancement( greenEnhancement );
- }
-
- //blue enhancement
- int blueBand = cr->blueBand();
- if ( blueBand != -1 )
- {
- QgsRasterDataProvider::DataType blueType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( cr->blueBand() );
- QgsContrastEnhancement* blueEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )blueType );
- blueEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
- blueEnhancement->setMinimumValue( mDataProvider->minimumValue( blueBand ) );
- blueEnhancement->setMaximumValue( mDataProvider->maximumValue( blueBand ) );
- cr->setBlueContrastEnhancement( blueEnhancement );
- }
+ QgsDebugMsg( QString( "myBand = %1 myMin = %2 myMax = %3" ).arg( myBand ).arg( myMin ).arg( myMax ) );
+ myEnhancement->setMinimumValue( myMin );
+ myEnhancement->setMaximumValue( myMax );
+ myEnhancements.append( myEnhancement );
}
+ else
+ {
+ myEnhancements.append( 0 );
+ }
+ }
+
+ if ( rendererType == "singlebandgray" )
+ {
+ if ( myEnhancements.value( 0 ) ) myGrayRenderer->setContrastEnhancement( myEnhancements.value( 0 ) );
+ }
+ else if ( rendererType == "multibandcolor" )
+ {
+ if ( myEnhancements.value( 0 ) ) myMultiBandRenderer->setRedContrastEnhancement( myEnhancements.value( 0 ) );
+ if ( myEnhancements.value( 1 ) ) myMultiBandRenderer->setGreenContrastEnhancement( myEnhancements.value( 1 ) );
+ if ( myEnhancements.value( 2 ) ) myMultiBandRenderer->setBlueContrastEnhancement( myEnhancements.value( 2 ) );
}
}
diff --git a/src/core/raster/qgsrasterlayer.h b/src/core/raster/qgsrasterlayer.h
index 8ef777a5c18..d28361809c8 100644
--- a/src/core/raster/qgsrasterlayer.h
+++ b/src/core/raster/qgsrasterlayer.h
@@ -174,6 +174,15 @@ 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 Constructor. Provider is not set. */
QgsRasterLayer();
@@ -243,7 +252,15 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
Palette,
Multiband,
ColorLayer
- } ;
+ };
+
+ /** \brief Contrast enhancement limits */
+ enum ContrastEnhancementLimits
+ {
+ ContrastEnhancementMinMax,
+ ContrastEnhancementStdDev,
+ ContrastEnhancementCumulativeCut
+ };
/** \brief A list containing on ContrastEnhancement object per raster band in this raster layer */
typedef QList ContrastEnhancementList;
@@ -548,10 +565,25 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
/** \brief Mutator for color shader algorithm */
Q_DECL_DEPRECATED void setColorShadingAlgorithm( QString theShaderAlgorithm );
- /** \brief Mutator for contrast enhancement algorithm */
+ /** \brief Mutator for contrast enhancement algorithm using min/max */
+ // TODO: remove in 2.0, replaced by following
void setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
bool theGenerateLookupTableFlag = true );
+ /** \brief Mutator for contrast enhancement algorithm
+ * @param theAlgorithm Contrast enhancement algorithm
+ * @param theLimits Limits
+ * @param theExtent Extent used to calculate limits, if empty, use full layer extent
+ * @param theSampleSize Size of data sample to calculate limits, if 0, use full resolution
+ * @param theGenerateLookupTableFlag Generate llokup table. */
+
+
+ void setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
+ ContrastEnhancementLimits theLimits = ContrastEnhancementMinMax,
+ QgsRectangle theExtent = QgsRectangle(),
+ int theSampleSize = SAMPLE_SIZE,
+ bool theGenerateLookupTableFlag = true );
+
/** \brief Mutator for contrast enhancement algorithm */
void setContrastEnhancementAlgorithm( QString theAlgorithm, bool theGenerateLookupTableFlag = true );
diff --git a/src/core/raster/qgsrasterrenderer.h b/src/core/raster/qgsrasterrenderer.h
index 2a7911c70c4..cdfa306b58d 100644
--- a/src/core/raster/qgsrasterrenderer.h
+++ b/src/core/raster/qgsrasterrenderer.h
@@ -22,6 +22,8 @@
#include "qgsrasterdataprovider.h"
#include
+#include "cpl_conv.h"
+
class QPainter;
class QgsMapToPixel;
class QgsRasterResampler;
diff --git a/src/gui/raster/qgsrasterminmaxwidget.cpp b/src/gui/raster/qgsrasterminmaxwidget.cpp
index da7eff2e3f4..dca7fb3e8fc 100644
--- a/src/gui/raster/qgsrasterminmaxwidget.cpp
+++ b/src/gui/raster/qgsrasterminmaxwidget.cpp
@@ -70,7 +70,7 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
}
else if ( mStdDevRadioButton->isChecked() )
{
- QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean, myExtent, mySampleSize );
+ 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 );
diff --git a/src/plugins/sqlanywhere/sasourceselect.cpp b/src/plugins/sqlanywhere/sasourceselect.cpp
index 68260b37105..ec677b78c77 100644
--- a/src/plugins/sqlanywhere/sasourceselect.cpp
+++ b/src/plugins/sqlanywhere/sasourceselect.cpp
@@ -28,7 +28,6 @@
#include "sanewconnection.h"
#include "qgsquerybuilder.h"
-#include "qgisapp.h"
#include "qgslogger.h"
#include "qgsapplication.h"
#include "qgscontexthelp.h"
diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui
index e79176259c2..438e9480c4a 100644
--- a/src/ui/qgisapp.ui
+++ b/src/ui/qgisapp.ui
@@ -17,7 +17,7 @@
0
0
1052
- 26
+ 21
-
+
@@ -385,8 +385,10 @@
false
-
+
+
+
@@ -1748,6 +1750,30 @@ Shift thaws, Alt toggles, Ctl (Cmd) hides
New Blank Project
+
+
+
+ :/images/themes/default/mActionLocalCumulativeCutStretch.png:/images/themes/default/mActionLocalCumulativeCutStretch.png
+
+
+ Local Cumulative Cut Stretch
+
+
+ Local cumulative cut stretch using current extent, default limits and estimated values.
+
+
+
+
+
+ :/images/themes/default/mActionFullCumulativeCutStretch.png:/images/themes/default/mActionFullCumulativeCutStretch.png
+
+
+ Full Dataset Cumulative Cut Stretch
+
+
+ Cumulative cut stretch using full dataset extent, default limits and estimated values.
+
+
diff --git a/tests/testdata/control_images/expected_landsat_basic/expected_landsat_basic.png b/tests/testdata/control_images/expected_landsat_basic/expected_landsat_basic.png
index 455f791ab93..00abbd07d7e 100644
Binary files a/tests/testdata/control_images/expected_landsat_basic/expected_landsat_basic.png and b/tests/testdata/control_images/expected_landsat_basic/expected_landsat_basic.png differ