mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
cumulative cut tools, raster stretching moved from qgisapp to raster layer, unfortunately one control image has also be changed because stretching changed from GDALComputeRasterMinMax which gives for tests/testdata/landsat.tif 3. band min/max 57/157 to GDALComputeRasterStatistics which gives 51/172
This commit is contained in:
parent
ad9cb9d194
commit
80c251d2a9
@ -79,6 +79,7 @@
|
|||||||
<file>themes/default/mActionFormAnnotation.png</file>
|
<file>themes/default/mActionFormAnnotation.png</file>
|
||||||
<file>themes/default/mActionFreezeLabels.png</file>
|
<file>themes/default/mActionFreezeLabels.png</file>
|
||||||
<file>themes/default/mActionFromSelectedFeature.png</file>
|
<file>themes/default/mActionFromSelectedFeature.png</file>
|
||||||
|
<file>themes/default/mActionFullCumulativeCutStretch.png</file>
|
||||||
<file>themes/default/mActionFullHistogramStretch.png</file>
|
<file>themes/default/mActionFullHistogramStretch.png</file>
|
||||||
<file>themes/default/mActionGroupItems.png</file>
|
<file>themes/default/mActionGroupItems.png</file>
|
||||||
<file>themes/default/mActionHelpAbout.png</file>
|
<file>themes/default/mActionHelpAbout.png</file>
|
||||||
@ -91,6 +92,7 @@
|
|||||||
<file>themes/default/mActionInvertSelection.png</file>
|
<file>themes/default/mActionInvertSelection.png</file>
|
||||||
<file>themes/default/mActionLabeling.png</file>
|
<file>themes/default/mActionLabeling.png</file>
|
||||||
<file>themes/default/mActionLabel.png</file>
|
<file>themes/default/mActionLabel.png</file>
|
||||||
|
<file>themes/default/mActionLocalCumulativeCutStretch.png</file>
|
||||||
<file>themes/default/mActionLocalHistogramStretch.png</file>
|
<file>themes/default/mActionLocalHistogramStretch.png</file>
|
||||||
<file>themes/default/mActionLowerItems.png</file>
|
<file>themes/default/mActionLowerItems.png</file>
|
||||||
<file>themes/default/mActionMapTips.png</file>
|
<file>themes/default/mActionMapTips.png</file>
|
||||||
|
BIN
images/themes/default/mActionFullCumulativeCutStretch.png
Normal file
BIN
images/themes/default/mActionFullCumulativeCutStretch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
images/themes/default/mActionLocalCumulativeCutStretch.png
Normal file
BIN
images/themes/default/mActionLocalCumulativeCutStretch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -963,6 +963,8 @@ void QgisApp::createActions()
|
|||||||
// Raster toolbar items
|
// Raster toolbar items
|
||||||
connect( mActionLocalHistogramStretch, SIGNAL( triggered() ), this, SLOT( localHistogramStretch() ) );
|
connect( mActionLocalHistogramStretch, SIGNAL( triggered() ), this, SLOT( localHistogramStretch() ) );
|
||||||
connect( mActionFullHistogramStretch, SIGNAL( triggered() ), this, SLOT( fullHistogramStretch() ) );
|
connect( mActionFullHistogramStretch, SIGNAL( triggered() ), this, SLOT( fullHistogramStretch() ) );
|
||||||
|
connect( mActionLocalCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( localCumulativeCutStretch() ) );
|
||||||
|
connect( mActionFullCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( fullCumulativeCutStretch() ) );
|
||||||
|
|
||||||
// Help Menu Items
|
// Help Menu Items
|
||||||
|
|
||||||
@ -5461,14 +5463,29 @@ void QgisApp::options()
|
|||||||
|
|
||||||
void QgisApp::fullHistogramStretch()
|
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,
|
QMessageBox::information( this,
|
||||||
tr( "No Layer Selected" ),
|
tr( "No Layer Selected" ),
|
||||||
@ -5476,8 +5493,8 @@ void QgisApp::histogramStretch( bool visibleAreaOnly )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer *>( layer );
|
QgsRasterLayer* myRasterLayer = qobject_cast<QgsRasterLayer *>( myLayer );
|
||||||
if ( !rlayer )
|
if ( !myRasterLayer )
|
||||||
{
|
{
|
||||||
QMessageBox::information( this,
|
QMessageBox::information( this,
|
||||||
tr( "No Raster Layer Selected" ),
|
tr( "No Raster Layer Selected" ),
|
||||||
@ -5485,118 +5502,14 @@ void QgisApp::histogramStretch( bool visibleAreaOnly )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsRasterDataProvider* provider = rlayer->dataProvider();
|
QgsRectangle myRectangle;
|
||||||
if ( !provider )
|
if ( visibleAreaOnly ) myRectangle = mMapCanvas->mapRenderer()->outputExtentToLayerExtent( myRasterLayer, mMapCanvas->extent() );
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get renderer
|
myRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, theLimits, myRectangle );
|
||||||
QgsRasterRenderer* renderer = rlayer->renderer();
|
|
||||||
if ( !renderer )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//singleband gray <-> multiband color
|
|
||||||
if ( renderer->type() == "singlebandgray" )
|
|
||||||
{
|
|
||||||
QgsSingleBandGrayRenderer* grayRenderer = static_cast<QgsSingleBandGrayRenderer*>( 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<QgsMultiBandColorRenderer*>( 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMapCanvas->refresh();
|
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()
|
void QgisApp::helpContents()
|
||||||
{
|
{
|
||||||
openURL( "index.html" );
|
openURL( "index.html" );
|
||||||
|
@ -55,7 +55,6 @@ class QgsPalLabeling;
|
|||||||
class QgsPoint;
|
class QgsPoint;
|
||||||
class QgsProviderRegistry;
|
class QgsProviderRegistry;
|
||||||
class QgsPythonUtils;
|
class QgsPythonUtils;
|
||||||
class QgsRasterLayer;
|
|
||||||
class QgsRectangle;
|
class QgsRectangle;
|
||||||
class QgsUndoWidget;
|
class QgsUndoWidget;
|
||||||
class QgsVectorLayer;
|
class QgsVectorLayer;
|
||||||
@ -87,6 +86,7 @@ class QgsTileScaleWidget;
|
|||||||
#include "qgsconfig.h"
|
#include "qgsconfig.h"
|
||||||
#include "qgsfeature.h"
|
#include "qgsfeature.h"
|
||||||
#include "qgspoint.h"
|
#include "qgspoint.h"
|
||||||
|
#include "qgsrasterlayer.h"
|
||||||
#include "qgssnappingdialog.h"
|
#include "qgssnappingdialog.h"
|
||||||
|
|
||||||
#include "ui_qgisapp.h"
|
#include "ui_qgisapp.h"
|
||||||
@ -548,6 +548,10 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
|
|||||||
* Valid for non wms raster layers only.
|
* Valid for non wms raster layers only.
|
||||||
* @note Added in QGIS 1.7 */
|
* @note Added in QGIS 1.7 */
|
||||||
void fullHistogramStretch();
|
void fullHistogramStretch();
|
||||||
|
/** Perform a local cumulative cut stretch */
|
||||||
|
void localCumulativeCutStretch();
|
||||||
|
/** Perform a full extent cumulative cut stretch */
|
||||||
|
void fullCumulativeCutStretch();
|
||||||
//! plugin manager
|
//! plugin manager
|
||||||
void showPluginManager();
|
void showPluginManager();
|
||||||
//! load python support if possible
|
//! load python support if possible
|
||||||
@ -992,10 +996,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
|
|||||||
void createDecorations();
|
void createDecorations();
|
||||||
|
|
||||||
/**Do histogram stretch for singleband gray / multiband color rasters*/
|
/**Do histogram stretch for singleband gray / multiband color rasters*/
|
||||||
void histogramStretch( bool visibleAreaOnly = false );
|
void histogramStretch( bool visibleAreaOnly = false, QgsRasterLayer::ContrastEnhancementLimits theLimits = QgsRasterLayer::ContrastEnhancementMinMax );
|
||||||
/**Create raster enhancement object for a raster band*/
|
|
||||||
QgsContrastEnhancement* rasterContrastEnhancement( QgsRasterLayer* rlayer, int band,
|
|
||||||
bool visibleAreaOnly = false ) const;
|
|
||||||
|
|
||||||
// actions for menus and toolbars -----------------
|
// actions for menus and toolbars -----------------
|
||||||
|
|
||||||
|
@ -435,7 +435,15 @@ void QgsRasterDataProvider::initStatistics( QgsRasterBandStats &theStatistics,
|
|||||||
theStatistics.bandNumber = theBandNo;
|
theStatistics.bandNumber = theBandNo;
|
||||||
theStatistics.statsGathered = theStats;
|
theStatistics.statsGathered = theStats;
|
||||||
|
|
||||||
QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
|
QgsRectangle myExtent;
|
||||||
|
if ( theExtent.isEmpty() )
|
||||||
|
{
|
||||||
|
myExtent = extent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myExtent = extent().intersect( &theExtent );
|
||||||
|
}
|
||||||
theStatistics.extent = myExtent;
|
theStatistics.extent = myExtent;
|
||||||
|
|
||||||
if ( theSampleSize > 0 )
|
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;
|
theHistogram.extent = myExtent;
|
||||||
|
|
||||||
if ( theSampleSize > 0 )
|
if ( theSampleSize > 0 )
|
||||||
|
@ -96,6 +96,10 @@ typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QStrin
|
|||||||
// doubles can take for the current system. (Yes, 20 was arbitrary.)
|
// doubles can take for the current system. (Yes, 20 was arbitrary.)
|
||||||
#define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
|
#define TINY_VALUE std::numeric_limits<double>::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()
|
QgsRasterLayer::QgsRasterLayer()
|
||||||
: QgsMapLayer( RasterLayer )
|
: QgsMapLayer( RasterLayer )
|
||||||
, QSTRING_NOT_SET( "Not Set" )
|
, QSTRING_NOT_SET( "Not Set" )
|
||||||
@ -1845,71 +1849,91 @@ void QgsRasterLayer::setColorShadingAlgorithm( QString )
|
|||||||
|
|
||||||
void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, bool theGenerateLookupTableFlag )
|
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 )
|
if ( !mPipe.renderer() || !mDataProvider )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<int> myBands;
|
||||||
|
QList<QgsContrastEnhancement*> myEnhancements;
|
||||||
|
QgsSingleBandGrayRenderer* myGrayRenderer = 0;
|
||||||
|
QgsMultiBandColorRenderer* myMultiBandRenderer = 0;
|
||||||
QString rendererType = mPipe.renderer()->type();
|
QString rendererType = mPipe.renderer()->type();
|
||||||
if ( rendererType == "singlebandgray" )
|
if ( rendererType == "singlebandgray" )
|
||||||
{
|
{
|
||||||
QgsSingleBandGrayRenderer* gr = dynamic_cast<QgsSingleBandGrayRenderer*>( mPipe.renderer() );
|
myGrayRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( mPipe.renderer() );
|
||||||
if ( gr )
|
if ( !myGrayRenderer ) return;
|
||||||
{
|
myBands << myGrayRenderer->grayBand();
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ( rendererType == "multibandcolor" )
|
else if ( rendererType == "multibandcolor" )
|
||||||
{
|
{
|
||||||
QgsMultiBandColorRenderer* cr = dynamic_cast<QgsMultiBandColorRenderer*>( mPipe.renderer() );
|
myMultiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( mPipe.renderer() );
|
||||||
if ( cr )
|
if ( !myMultiBandRenderer ) return;
|
||||||
|
myBands << myMultiBandRenderer->redBand() << myMultiBandRenderer->greenBand() << myMultiBandRenderer->blueBand();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach( int myBand, myBands )
|
||||||
|
{
|
||||||
|
if ( myBand != -1 )
|
||||||
{
|
{
|
||||||
//red enhancement
|
QgsRasterDataProvider::DataType myType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( myBand );
|
||||||
int redBand = cr->redBand();
|
QgsContrastEnhancement* myEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )myType );
|
||||||
if ( redBand != -1 )
|
myEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
|
||||||
|
|
||||||
|
double myMin = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
double myMax = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
|
if ( theLimits == ContrastEnhancementMinMax )
|
||||||
{
|
{
|
||||||
QgsRasterDataProvider::DataType redType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( redBand );
|
// minimumValue/maximumValue are not well defined (estimation) and will be removed
|
||||||
QgsContrastEnhancement* redEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )redType );
|
//myMin = mDataProvider->minimumValue( myBand );
|
||||||
redEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
|
//myMax = mDataProvider->maximumValue( myBand );
|
||||||
redEnhancement->setMinimumValue( mDataProvider->minimumValue( redBand ) );
|
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, theExtent, theSampleSize );
|
||||||
redEnhancement->setMaximumValue( mDataProvider->maximumValue( redBand ) );
|
myMin = myRasterBandStats.minimumValue;
|
||||||
cr->setRedContrastEnhancement( redEnhancement );
|
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
|
QgsDebugMsg( QString( "myBand = %1 myMin = %2 myMax = %3" ).arg( myBand ).arg( myMin ).arg( myMax ) );
|
||||||
int greenBand = cr->greenBand();
|
myEnhancement->setMinimumValue( myMin );
|
||||||
if ( greenBand != -1 )
|
myEnhancement->setMaximumValue( myMax );
|
||||||
{
|
myEnhancements.append( myEnhancement );
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +174,15 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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. */
|
/** \brief Constructor. Provider is not set. */
|
||||||
QgsRasterLayer();
|
QgsRasterLayer();
|
||||||
|
|
||||||
@ -243,7 +252,15 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
|||||||
Palette,
|
Palette,
|
||||||
Multiband,
|
Multiband,
|
||||||
ColorLayer
|
ColorLayer
|
||||||
} ;
|
};
|
||||||
|
|
||||||
|
/** \brief Contrast enhancement limits */
|
||||||
|
enum ContrastEnhancementLimits
|
||||||
|
{
|
||||||
|
ContrastEnhancementMinMax,
|
||||||
|
ContrastEnhancementStdDev,
|
||||||
|
ContrastEnhancementCumulativeCut
|
||||||
|
};
|
||||||
|
|
||||||
/** \brief A list containing on ContrastEnhancement object per raster band in this raster layer */
|
/** \brief A list containing on ContrastEnhancement object per raster band in this raster layer */
|
||||||
typedef QList<QgsContrastEnhancement> ContrastEnhancementList;
|
typedef QList<QgsContrastEnhancement> ContrastEnhancementList;
|
||||||
@ -548,10 +565,25 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
|||||||
/** \brief Mutator for color shader algorithm */
|
/** \brief Mutator for color shader algorithm */
|
||||||
Q_DECL_DEPRECATED void setColorShadingAlgorithm( QString theShaderAlgorithm );
|
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,
|
void setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
|
||||||
bool theGenerateLookupTableFlag = true );
|
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 */
|
/** \brief Mutator for contrast enhancement algorithm */
|
||||||
void setContrastEnhancementAlgorithm( QString theAlgorithm, bool theGenerateLookupTableFlag = true );
|
void setContrastEnhancementAlgorithm( QString theAlgorithm, bool theGenerateLookupTableFlag = true );
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "qgsrasterdataprovider.h"
|
#include "qgsrasterdataprovider.h"
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
|
|
||||||
|
#include "cpl_conv.h"
|
||||||
|
|
||||||
class QPainter;
|
class QPainter;
|
||||||
class QgsMapToPixel;
|
class QgsMapToPixel;
|
||||||
class QgsRasterResampler;
|
class QgsRasterResampler;
|
||||||
|
@ -70,7 +70,7 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
|
|||||||
}
|
}
|
||||||
else if ( mStdDevRadioButton->isChecked() )
|
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();
|
double myStdDev = mStdDevSpinBox->value();
|
||||||
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
|
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
|
||||||
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
|
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "sanewconnection.h"
|
#include "sanewconnection.h"
|
||||||
#include "qgsquerybuilder.h"
|
#include "qgsquerybuilder.h"
|
||||||
|
|
||||||
#include "qgisapp.h"
|
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
#include "qgsapplication.h"
|
#include "qgsapplication.h"
|
||||||
#include "qgscontexthelp.h"
|
#include "qgscontexthelp.h"
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1052</width>
|
<width>1052</width>
|
||||||
<height>26</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="mEditMenu">
|
<widget class="QMenu" name="mEditMenu">
|
||||||
@ -189,12 +189,6 @@
|
|||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="mActionShowPythonDialog"/>
|
<addaction name="mActionShowPythonDialog"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="mRasterMenu">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Raster</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="mActionShowRasterCalculator"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="mHelpMenu">
|
<widget class="QMenu" name="mHelpMenu">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&Help</string>
|
<string>&Help</string>
|
||||||
@ -220,6 +214,12 @@
|
|||||||
<addaction name="mActionOptions"/>
|
<addaction name="mActionOptions"/>
|
||||||
<addaction name="mActionSnappingOptions"/>
|
<addaction name="mActionSnappingOptions"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="mRasterMenu">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Raster</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="mActionShowRasterCalculator"/>
|
||||||
|
</widget>
|
||||||
<addaction name="mFileMenu"/>
|
<addaction name="mFileMenu"/>
|
||||||
<addaction name="mEditMenu"/>
|
<addaction name="mEditMenu"/>
|
||||||
<addaction name="mViewMenu"/>
|
<addaction name="mViewMenu"/>
|
||||||
@ -385,8 +385,10 @@
|
|||||||
<attribute name="toolBarBreak">
|
<attribute name="toolBarBreak">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<addaction name="mActionFullHistogramStretch"/>
|
<addaction name="mActionLocalCumulativeCutStretch"/>
|
||||||
|
<addaction name="mActionFullCumulativeCutStretch"/>
|
||||||
<addaction name="mActionLocalHistogramStretch"/>
|
<addaction name="mActionLocalHistogramStretch"/>
|
||||||
|
<addaction name="mActionFullHistogramStretch"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QToolBar" name="mLabelToolBar">
|
<widget class="QToolBar" name="mLabelToolBar">
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -1748,6 +1750,30 @@ Shift thaws, Alt toggles, Ctl (Cmd) hides</string>
|
|||||||
<string>New Blank Project</string>
|
<string>New Blank Project</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="mActionLocalCumulativeCutStretch">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionLocalCumulativeCutStretch.png</normaloff>:/images/themes/default/mActionLocalCumulativeCutStretch.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Local Cumulative Cut Stretch</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Local cumulative cut stretch using current extent, default limits and estimated values.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="mActionFullCumulativeCutStretch">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionFullCumulativeCutStretch.png</normaloff>:/images/themes/default/mActionFullCumulativeCutStretch.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Full Dataset Cumulative Cut Stretch</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Cumulative cut stretch using full dataset extent, default limits and estimated values.</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../images/images.qrc"/>
|
<include location="../../images/images.qrc"/>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
Loading…
x
Reference in New Issue
Block a user