Skip to content

Commit 3c13f3c

Browse files
committed
histogram: ui tweaks; re-organize actions and add custom stddev action
1 parent f6d1bd1 commit 3c13f3c

File tree

6 files changed

+233
-127
lines changed

6 files changed

+233
-127
lines changed

src/app/qgsrasterlayerproperties.cpp

Lines changed: 156 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
307307
mHistoZoomer = NULL;
308308
mHistoMarkerMin = NULL;
309309
mHistoMarkerMax = NULL;
310+
mHistoShowMarkers = false;
311+
mHistoLoadApplyAll = false;
312+
mHistoShowBands = ShowAll;
310313
if ( tabPageHistogram->isEnabled() )
311314
{
312315
//band selector
@@ -328,18 +331,49 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
328331
// connect( leHistoMax, SIGNAL( textChanged( const QString & ) ), this, SLOT( applyHistoMax() ) );
329332
connect( leHistoMin, SIGNAL( editingFinished() ), this, SLOT( applyHistoMin() ) );
330333
connect( leHistoMax, SIGNAL( editingFinished() ), this, SLOT( applyHistoMax() ) );
331-
connect( cbxHistoShow, SIGNAL( toggled( bool ) ), this, SLOT( updateHistoMarkers() ) );
332334

333335
// histo actions
334336
QMenu* menu = new QMenu( this );
335337
menu->setSeparatorsCollapsible( false );
336338
btnHistoActions->setMenu( menu );
337339
QActionGroup* group;
340+
QAction* action;
338341

342+
// various actions / prefs
343+
group = new QActionGroup( this );
344+
group->setExclusive( false );
345+
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( histoActionTriggered( QAction* ) ) );
346+
action = new QAction( tr( "Visibility" ), group );
347+
action->setSeparator( true );
348+
menu->addAction( action );
349+
action = new QAction( tr( "Show min/max markers" ), group );
350+
action->setData( QVariant( "Show markers" ) );
351+
action->setCheckable( true );
352+
action->setChecked( mHistoShowMarkers );
353+
menu->addAction( action );
354+
group = new QActionGroup( this );
355+
group->setExclusive( true ); // these options are exclusive
356+
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( histoActionTriggered( QAction* ) ) );
357+
action = new QAction( tr( "Show all bands" ), group );
358+
action->setData( QVariant( "Show all" ) );
359+
action->setCheckable( true );
360+
action->setChecked( mHistoShowBands == ShowAll );
361+
menu->addAction( action );
362+
action = new QAction( tr( "Show RGB/Gray band(s)" ), group );
363+
action->setData( QVariant( "Show RGB" ) );
364+
action->setCheckable( true );
365+
action->setChecked( mHistoShowBands == ShowRGB );
366+
menu->addAction( action );
367+
action = new QAction( tr( "Show selected band" ), group );
368+
action->setData( QVariant( "Show selected" ) );
369+
action->setCheckable( true );
370+
action->setChecked( mHistoShowBands == ShowSelected );
371+
menu->addAction( action );
372+
373+
// load actions
339374
group = new QActionGroup( this );
340375
group->setExclusive( false );
341376
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( histoActionTriggered( QAction* ) ) );
342-
QAction* action;
343377
// action = new QAction( tr( "Load min/max from band" ), group );
344378
action = new QAction( tr( "Load min/max" ), group );
345379
action->setSeparator( true );
@@ -353,30 +387,27 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
353387
action = new QAction( tr( "Current extent" ), group );
354388
action->setData( QVariant( "Load extent" ) );
355389
menu->addAction( action );
356-
// stddev was removed...
357-
action = new QAction( tr( "Use 1 stddev" ), group );
390+
action = new QAction( tr( "Use stddev (1.0)" ), group );
358391
action->setData( QVariant( "Load 1 stddev" ) );
359392
menu->addAction( action );
360-
/*
361-
action = new QAction( tr( "Use custom stddev" ), group );
393+
action = new QAction( tr( "Use stddev (custom)" ), group );
362394
action->setData( QVariant( "Load stddev" ) );
363395
menu->addAction( action );
364-
*/
365396
action = new QAction( tr( "Reset" ), group );
366397
action->setData( QVariant( "Load reset" ) );
367398
menu->addAction( action );
368-
action = new QAction( tr( "Load for all bands" ), group );
399+
action = new QAction( tr( "Load for each band" ), group );
369400
action->setData( QVariant( "Load apply all" ) );
370401
action->setCheckable( true );
371-
action->setChecked( true );
402+
action->setChecked( mHistoLoadApplyAll );
372403
menu->addAction( action );
373404

405+
//others
374406
menu->addSeparator( );
375-
group = new QActionGroup( this );
376-
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( histoActionTriggered( QAction* ) ) );
377-
action = new QAction( tr( "Compute Histogram" ), group );
378-
action->setData( QVariant( "Compute Histogram" ) );
407+
action = new QAction( tr( "Recompute Histogram" ), group );
408+
action->setData( QVariant( "Compute histogram" ) );
379409
menu->addAction( action );
410+
380411
}
381412

382413
// update based on lyr's current state
@@ -1205,7 +1236,6 @@ void QgsRasterLayerProperties::on_btnHistoCompute_clicked()
12051236
// which is only visible if there is no cached histogram or by calling the
12061237
// "Compute Histogram" action. Due to limitations in the gdal api, it is not possible
12071238
// to re-calculate the histogramif it has already been calculated
1208-
QgsDebugMsg( "Entered" );
12091239
computeHistogram( true );
12101240
refreshHistogram();
12111241
}
@@ -1270,6 +1300,7 @@ void QgsRasterLayerProperties::refreshHistogram()
12701300

12711301
if ( ! computeHistogram( false ) )
12721302
{
1303+
// TODO - check raster min/max and min/max of default histogram
12731304
QgsDebugMsg( QString( "raster does not have cached histo" ) );
12741305
stackedWidget2->setCurrentIndex( 2 );
12751306
return;
@@ -1315,7 +1346,10 @@ void QgsRasterLayerProperties::refreshHistogram()
13151346
for ( int i = 1; i <= myBandCountInt; i++ )
13161347
{
13171348
if ( i == myGrayBand )
1349+
{
13181350
mHistoColors << Qt::black;
1351+
cboHistoBand->setItemData( i - 1, Qt::darkGray, Qt::ForegroundRole );
1352+
}
13191353
else
13201354
{
13211355
if ( ! myColors.isEmpty() )
@@ -1327,6 +1361,7 @@ void QgsRasterLayerProperties::refreshHistogram()
13271361
{
13281362
mHistoColors << Qt::black;
13291363
}
1364+
cboHistoBand->setItemData( i - 1, Qt::black, Qt::ForegroundRole );
13301365
}
13311366
}
13321367
}
@@ -1382,10 +1417,19 @@ void QgsRasterLayerProperties::refreshHistogram()
13821417
mHistoMin = 0;
13831418
mHistoMax = 0;
13841419
bool myFirstIteration = true;
1420+
/* get selected band list, if mHistoShowBands != ShowAll */
1421+
QList< int > mySelectedBands = histoSelectedBands();
1422+
13851423
for ( int myIteratorInt = 1;
13861424
myIteratorInt <= myBandCountInt;
13871425
++myIteratorInt )
13881426
{
1427+
/* skip this band if mHistoShowBands != ShowAll and this band is not selected */
1428+
if ( mHistoShowBands != ShowAll )
1429+
{
1430+
if ( ! mySelectedBands.contains( myIteratorInt ) )
1431+
continue;
1432+
}
13891433
QgsRasterBandStats myRasterBandStats = mRasterLayer->bandStatistics( myIteratorInt );
13901434
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
13911435
QwtPlotCurve * mypCurve = new QwtPlotCurve( tr( "Band %1" ).arg( myIteratorInt ) );
@@ -1464,12 +1508,10 @@ void QgsRasterLayerProperties::refreshHistogram()
14641508
}
14651509

14661510
disconnect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mHistogramProgress, SLOT( setValue( int ) ) );
1467-
// mHistogramProgress->hide();
14681511
stackedWidget2->setCurrentIndex( 0 );
1469-
// mpPlot->canvas()->setCursor( Qt::ArrowCursor );
14701512
// icon from http://findicons.com/icon/169577/14_zoom?id=171427
14711513
mpPlot->canvas()->setCursor( QCursor( QgisApp::getThemePixmap( "/mIconZoom.png" ) ) );
1472-
on_cboHistoBand_currentIndexChanged( -1 );
1514+
// on_cboHistoBand_currentIndexChanged( -1 );
14731515
QApplication::restoreOverrideCursor();
14741516
}
14751517

@@ -1843,6 +1885,9 @@ void QgsRasterLayerProperties::toggleBuildPyramidsButton()
18431885

18441886
void QgsRasterLayerProperties::on_cboHistoBand_currentIndexChanged( int index )
18451887
{
1888+
if ( mHistoShowBands == ShowSelected )
1889+
refreshHistogram();
1890+
18461891
// get the current index value, index can be -1
18471892
index = cboHistoBand->currentIndex();
18481893
if ( mHistoPicker != NULL )
@@ -1899,52 +1944,74 @@ void QgsRasterLayerProperties::histoActionTriggered( QAction* action )
18991944
if ( ! action )
19001945
return;
19011946

1902-
// this approach is a bit of a hack, but we don't have to define slots for each action
1947+
// this approach is a bit of a hack, but this way we don't have to define slots for each action
19031948
QString actionName = action->data().toString();
19041949

19051950
QgsDebugMsg( QString( "band = %1 action = %2" ).arg( cboHistoBand->currentIndex() + 1 ).arg( actionName ) );
19061951

1907-
if ( actionName.left( 5 ) == "Load " )
1952+
// checkeable actions
1953+
if ( actionName == "Show markers" )
1954+
{
1955+
mHistoShowMarkers = action->isChecked();
1956+
updateHistoMarkers();
1957+
return;
1958+
}
1959+
else if ( actionName == "Show all" )
1960+
{
1961+
mHistoShowBands = ShowAll;
1962+
refreshHistogram();
1963+
return;
1964+
}
1965+
else if ( actionName == "Show selected" )
1966+
{
1967+
mHistoShowBands = ShowSelected;
1968+
refreshHistogram();
1969+
return;
1970+
}
1971+
else if ( actionName == "Show RGB" )
1972+
{
1973+
mHistoShowBands = ShowRGB;
1974+
refreshHistogram();
1975+
return;
1976+
}
1977+
else if ( actionName == "Load apply all" )
1978+
{
1979+
mHistoLoadApplyAll = action->isChecked();
1980+
return;
1981+
}
1982+
// Load actions
1983+
else if ( actionName.left( 5 ) == "Load " )
19081984
{
1909-
if ( actionName == "Load apply all" )
1910-
return;
1911-
19121985
QgsRasterBandStats myRasterBandStats;
19131986
QVector<int> myBands;
19141987
double minMaxValues[2];
19151988
bool ok = false;
19161989

1917-
// get "Load apply all" value to find which band(s) need updating
1918-
QList< QAction* > actions;
1919-
if ( action->actionGroup() )
1920-
actions = action->actionGroup()->actions();
1921-
foreach( QAction* tmpAction, actions )
1990+
// find which band(s) need updating (all or current)
1991+
if ( mHistoLoadApplyAll )
19221992
{
1923-
if ( tmpAction && ( tmpAction->data().toString() == "Load apply all" ) )
1993+
int myBandCountInt = mRasterLayer->bandCount();
1994+
for ( int i = 1; i <= myBandCountInt; i++ )
19241995
{
1925-
// add all bands
1926-
if ( tmpAction->isChecked() )
1927-
{
1928-
int myBandCountInt = mRasterLayer->bandCount();
1929-
for ( int myIteratorInt = 1;
1930-
myIteratorInt <= myBandCountInt;
1931-
++myIteratorInt )
1932-
{
1933-
if ( myIteratorInt != cboHistoBand->currentIndex() + 1 )
1934-
myBands << myIteratorInt;
1935-
}
1936-
}
1937-
// add current band to the end
1938-
myBands << cboHistoBand->currentIndex() + 1;
1939-
break;
1996+
if ( i != cboHistoBand->currentIndex() + 1 )
1997+
myBands << i;
19401998
}
19411999
}
1942-
// don't update markers every time
1943-
if ( myBands.size() > 1 )
2000+
// add current band to the end
2001+
myBands << cboHistoBand->currentIndex() + 1;
2002+
2003+
// get stddev value once if needed
2004+
double myStdDev = 1.0;
2005+
if ( actionName == "Load stddev" )
19442006
{
1945-
leHistoMin->blockSignals( true );
1946-
leHistoMax->blockSignals( true );
2007+
myStdDev = mRendererWidget->stdDev().toDouble();
19472008
}
2009+
2010+
// don't update markers every time
2011+
leHistoMin->blockSignals( true );
2012+
leHistoMax->blockSignals( true );
2013+
2014+
// process each band
19482015
foreach( int theBandNo, myBands )
19492016
{
19502017
ok = false;
@@ -1963,9 +2030,9 @@ void QgsRasterLayerProperties::histoActionTriggered( QAction* action )
19632030
ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::CurrentExtent,
19642031
theBandNo, minMaxValues );
19652032
}
1966-
else if ( actionName == "Load 1 stddev" )
2033+
else if ( actionName == "Load 1 stddev" ||
2034+
actionName == "Load stddev" )
19672035
{
1968-
double myStdDev = 1.0;
19692036
ok = mRendererWidget->bandMinMaxFromStdDev( myStdDev, theBandNo, minMaxValues );
19702037
}
19712038

@@ -1991,19 +2058,17 @@ void QgsRasterLayerProperties::histoActionTriggered( QAction* action )
19912058
applyHistoMax( );
19922059
}
19932060
// update markers
1994-
if ( myBands.size() > 1 )
1995-
{
1996-
leHistoMin->blockSignals( false );
1997-
leHistoMax->blockSignals( false );
1998-
updateHistoMarkers();
1999-
}
2061+
leHistoMin->blockSignals( false );
2062+
leHistoMax->blockSignals( false );
2063+
updateHistoMarkers();
20002064
}
2001-
else if ( actionName == "Compute Histogram" )
2065+
else if ( actionName == "Compute histogram" )
20022066
{
20032067
on_btnHistoCompute_clicked();
20042068
}
20052069
else
20062070
{
2071+
QgsDebugMsg( "Invalid action " + actionName );
20072072
return;
20082073
}
20092074
}
@@ -2149,15 +2214,18 @@ void QgsRasterLayerProperties::updateHistoMarkers( )
21492214
if ( mpPlot == NULL || mHistoMarkerMin == NULL || mHistoMarkerMax == NULL )
21502215
return;
21512216

2152-
if ( ! cbxHistoShow->isChecked() )
2217+
int theBandNo = cboHistoBand->currentIndex() + 1;
2218+
QList< int > mySelectedBands = histoSelectedBands();
2219+
2220+
if ( ! mHistoShowMarkers ||
2221+
( ! mySelectedBands.isEmpty() && ! mySelectedBands.contains( theBandNo ) ) )
21532222
{
21542223
mHistoMarkerMin->hide();
21552224
mHistoMarkerMax->hide();
21562225
mpPlot->replot();
21572226
return;
21582227
}
21592228

2160-
int theBandNo = cboHistoBand->currentIndex() + 1;
21612229
double minVal = mHistoMin;
21622230
double maxVal = mHistoMax;
21632231
QString minStr = leHistoMin->text();
@@ -2182,3 +2250,33 @@ void QgsRasterLayerProperties::updateHistoMarkers( )
21822250

21832251
}
21842252

2253+
2254+
QList< int > QgsRasterLayerProperties::histoSelectedBands()
2255+
{
2256+
QList< int > mySelectedBands;
2257+
QString rendererName = mRenderTypeComboBox->itemData( mRenderTypeComboBox->currentIndex() ).toString();
2258+
2259+
if ( mHistoShowBands != ShowAll )
2260+
{
2261+
if ( mHistoShowBands == ShowSelected )
2262+
{
2263+
mySelectedBands << cboHistoBand->currentIndex() + 1;
2264+
}
2265+
else if ( mHistoShowBands == ShowRGB )
2266+
{
2267+
if ( rendererName.startsWith( "singlebandgray" ) )
2268+
{
2269+
mySelectedBands << mRendererWidget->selectedBand( );
2270+
}
2271+
else if ( rendererName == "multibandcolor" )
2272+
{
2273+
for ( int i = 0; i <= 2; i++ )
2274+
{
2275+
mySelectedBands << mRendererWidget->selectedBand( i );
2276+
}
2277+
}
2278+
}
2279+
}
2280+
2281+
return mySelectedBands;
2282+
}

src/app/qgsrasterlayerproperties.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,20 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
184184
QwtPlotMarker* mHistoMarkerMax;
185185
double mHistoMin;
186186
double mHistoMax;
187-
QVector<QColor> mHistoColors;
187+
QVector<QColor> mHistoColors;
188+
bool mHistoShowMarkers;
189+
bool mHistoLoadApplyAll;
190+
enum HistoShowBands
191+
{
192+
ShowAll = 0,
193+
ShowSelected = 1,
194+
ShowRGB = 2
195+
};
196+
HistoShowBands mHistoShowBands;
188197

189198
/** \brief Compute the histogram on demand. */
190199
bool computeHistogram( bool forceComputeFlag );
200+
/** \brief Returns a list of selected bands - or empty if there is no selection restriction. */
201+
QList< int > histoSelectedBands();
191202
};
192203
#endif

0 commit comments

Comments
 (0)