mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
add UI to pick min/max band values in histogram
This commit is contained in:
parent
b70a0c6991
commit
4a53350d7c
@ -389,6 +389,7 @@
|
||||
<file>themes/gis/mActionTouch.png</file>
|
||||
<file>themes/default/mActionAddMssqlLayer.png</file>
|
||||
<file>themes/default/mActionTouch.png</file>
|
||||
<file>themes/default/mActionTouch2.png</file>
|
||||
<file>themes/classic/mActionTouch.png</file>
|
||||
<file>flags/af.png</file>
|
||||
<file>flags/ar.png</file>
|
||||
|
BIN
images/themes/default/mActionTouch2.png
Normal file
BIN
images/themes/default/mActionTouch2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -68,6 +68,9 @@
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_plot_curve.h>
|
||||
#include <qwt_plot_grid.h>
|
||||
#include <qwt_plot_marker.h>
|
||||
#include <qwt_plot_picker.h>
|
||||
#include <qwt_picker_machine.h>
|
||||
|
||||
QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanvas* theCanvas, QWidget *parent, Qt::WFlags fl )
|
||||
: QDialog( parent, fl ),
|
||||
@ -180,14 +183,9 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
|
||||
|
||||
QSettings settings;
|
||||
restoreGeometry( settings.value( "/Windows/RasterLayerProperties/geometry" ).toByteArray() );
|
||||
tabBar->setCurrentIndex( settings.value( "/Windows/RasterLayerProperties/row" ).toInt() );
|
||||
|
||||
setWindowTitle( tr( "Layer Properties - %1" ).arg( lyr->name() ) );
|
||||
int myHistogramTab = 5;
|
||||
if ( tabBar->currentIndex() == myHistogramTab )
|
||||
{
|
||||
refreshHistogram();
|
||||
}
|
||||
|
||||
tableTransparency->horizontalHeader()->setResizeMode( 0, QHeaderView::Stretch );
|
||||
tableTransparency->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
|
||||
|
||||
@ -299,8 +297,87 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
|
||||
}
|
||||
on_mRenderTypeComboBox_currentIndexChanged( mRenderTypeComboBox->currentIndex() );
|
||||
|
||||
// histogram
|
||||
mHistoPicker = NULL;
|
||||
mHistoMarkerMin = NULL;
|
||||
mHistoMarkerMax = NULL;
|
||||
if ( tabPageHistogram->isEnabled() )
|
||||
{
|
||||
//band selector
|
||||
int myBandCountInt = mRasterLayer->bandCount();
|
||||
for ( int myIteratorInt = 1;
|
||||
myIteratorInt <= myBandCountInt;
|
||||
++myIteratorInt )
|
||||
{
|
||||
cboHistoBand->addItem( mRasterLayer->bandName( myIteratorInt ) );
|
||||
}
|
||||
|
||||
// histo min/max selectors
|
||||
leHistoMin->setValidator( new QDoubleValidator( this ) );
|
||||
leHistoMax->setValidator( new QDoubleValidator( this ) );
|
||||
// this might generate many refresh events! test..
|
||||
// connect( leHistoMin, SIGNAL( textChanged( const QString & ) ), this, SLOT( updateHistoMarkers() ) );
|
||||
// connect( leHistoMax, SIGNAL( textChanged( const QString & ) ), this, SLOT( updateHistoMarkers() ) );
|
||||
// connect( leHistoMin, SIGNAL( textChanged( const QString & ) ), this, SLOT( applyHistoMin() ) );
|
||||
// connect( leHistoMax, SIGNAL( textChanged( const QString & ) ), this, SLOT( applyHistoMax() ) );
|
||||
connect( leHistoMin, SIGNAL( editingFinished() ), this, SLOT( applyHistoMin() ) );
|
||||
connect( leHistoMax, SIGNAL( editingFinished() ), this, SLOT( applyHistoMax() ) );
|
||||
connect( cbxHistoShow, SIGNAL( toggled( bool ) ), this, SLOT( updateHistoMarkers() ) );
|
||||
|
||||
// histo actions
|
||||
QMenu* menu = new QMenu( this );
|
||||
menu->setSeparatorsCollapsible( false );
|
||||
btnHistoActions->setMenu( menu );
|
||||
|
||||
QActionGroup* group = new QActionGroup( this );
|
||||
group->setExclusive( false );
|
||||
connect( group, SIGNAL( triggered( QAction* ) ), this, SLOT( histoActionTriggered( QAction* ) ) );
|
||||
QAction* action;
|
||||
// action = new QAction( tr( "Load min/max from band" ), group );
|
||||
action = new QAction( tr( "Load min/max" ), group );
|
||||
action->setSeparator( true );
|
||||
menu->addAction( action );
|
||||
action = new QAction( tr( "Estimate (faster)" ), group );
|
||||
action->setData( QVariant( "Load estimate" ) );
|
||||
menu->addAction( action );
|
||||
action = new QAction( tr( "Actual (slower)" ), group );
|
||||
action->setData( QVariant( "Load actual" ) );
|
||||
menu->addAction( action );
|
||||
action = new QAction( tr( "Current extent" ), group );
|
||||
action->setData( QVariant( "Load extent" ) );
|
||||
menu->addAction( action );
|
||||
// stddev was removed...
|
||||
action = new QAction( tr( "Use 1 stddev" ), group );
|
||||
action->setData( QVariant( "Load 1 stddev" ) );
|
||||
menu->addAction( action );
|
||||
/*
|
||||
action = new QAction( tr( "Use custom stddev" ), group );
|
||||
action->setData( QVariant( "Load stddev" ) );
|
||||
menu->addAction( action );
|
||||
*/
|
||||
action = new QAction( tr( "Reset" ), group );
|
||||
action->setData( QVariant( "Load reset" ) );
|
||||
menu->addAction( action );
|
||||
action = new QAction( tr( "Load for all bands" ), group );
|
||||
action->setData( QVariant( "Load apply all" ) );
|
||||
action->setCheckable( true );
|
||||
action->setChecked( true );
|
||||
menu->addAction( action );
|
||||
}
|
||||
|
||||
// update based on lyr's current state
|
||||
sync();
|
||||
|
||||
// set current tab after everything has been initialized
|
||||
tabBar->setCurrentIndex( settings.value( "/Windows/RasterLayerProperties/row" ).toInt() );
|
||||
|
||||
// show histogram tab
|
||||
int myHistogramTab = 5;
|
||||
if ( tabBar->currentIndex() == myHistogramTab )
|
||||
{
|
||||
refreshHistogram();
|
||||
}
|
||||
|
||||
} // QgsRasterLayerProperties ctor
|
||||
|
||||
|
||||
@ -1106,6 +1183,13 @@ void QgsRasterLayerProperties::on_tabBar_currentChanged( int theTab )
|
||||
{
|
||||
refreshHistogram();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( QApplication::overrideCursor() )
|
||||
QApplication::restoreOverrideCursor();
|
||||
btnHistoMin->setChecked( false );
|
||||
btnHistoMax->setChecked( false );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::refreshHistogram()
|
||||
@ -1113,7 +1197,8 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
#if !defined(QWT_VERSION) || QWT_VERSION<0x060000
|
||||
mpPlot->clear();
|
||||
#endif
|
||||
mHistogramProgress->show();
|
||||
// mHistogramProgress->show();
|
||||
stackedWidget2->setCurrentIndex( 1 );
|
||||
connect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mHistogramProgress, SLOT( setValue( int ) ) );
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
QgsDebugMsg( "entered." );
|
||||
@ -1135,7 +1220,7 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
// to create 256 bins. Each bin stores the total number of cells that
|
||||
// fit into the range defined by that bin.
|
||||
//
|
||||
// The graph routine below determines the greatest number of pixesl in any given
|
||||
// The graph routine below determines the greatest number of pixels in any given
|
||||
// bin in all selected layers, and the min. It then draws a scaled line between min
|
||||
// and max - scaled to image height. 1 line drawn per selected band
|
||||
//
|
||||
@ -1143,9 +1228,13 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
bool myIgnoreOutOfRangeFlag = true;
|
||||
bool myThoroughBandScanFlag = false;
|
||||
int myBandCountInt = mRasterLayer->bandCount();
|
||||
QList<QColor> myColors;
|
||||
myColors << Qt::black << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::darkRed << Qt::darkGreen << Qt::darkBlue;
|
||||
|
||||
// make colors list
|
||||
mHistoColors.clear();
|
||||
mHistoColors << Qt::black; // first element, not used
|
||||
// get a list fo colors
|
||||
QVector<QColor> myColors;
|
||||
myColors << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::darkYellow << Qt::cyan;
|
||||
while ( myColors.size() <= myBandCountInt )
|
||||
{
|
||||
myColors <<
|
||||
@ -1154,6 +1243,70 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) ) );
|
||||
}
|
||||
|
||||
// assign colors to each band, depending on the current RGB/gray band selection
|
||||
// TODO paletted + pseudo ?
|
||||
QString rendererName = mRenderTypeComboBox->itemData( mRenderTypeComboBox->currentIndex() ).toString();
|
||||
// greyscale
|
||||
if ( rendererName == "singlebandgray" )
|
||||
{
|
||||
int myGrayBand = mRendererWidget->selectedBand();
|
||||
for ( int i = 1; i <= myBandCountInt; i++ )
|
||||
{
|
||||
if ( i == myGrayBand )
|
||||
mHistoColors << Qt::black;
|
||||
else
|
||||
{
|
||||
if ( ! myColors.isEmpty() )
|
||||
{
|
||||
mHistoColors << myColors.first();
|
||||
myColors.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
mHistoColors << Qt::black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// RGB
|
||||
else if ( rendererName == "multibandcolor" )
|
||||
{
|
||||
int myRedBand = mRendererWidget->selectedBand( 0 );
|
||||
int myGreenBand = mRendererWidget->selectedBand( 1 );
|
||||
int myBlueBand = mRendererWidget->selectedBand( 2 );
|
||||
// remove RGB, which are reserved for the actual RGB bands
|
||||
// show name of RGB bands in appropriate color in bold
|
||||
myColors.remove( 0, 3 );
|
||||
for ( int i = 1; i <= myBandCountInt; i++ )
|
||||
{
|
||||
QColor myColor;
|
||||
if ( i == myRedBand )
|
||||
myColor = Qt::red;
|
||||
else if ( i == myGreenBand )
|
||||
myColor = Qt::green;
|
||||
else if ( i == myBlueBand )
|
||||
myColor = Qt::blue;
|
||||
else
|
||||
{
|
||||
if ( ! myColors.isEmpty() )
|
||||
{
|
||||
myColor = myColors.first();
|
||||
myColors.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
myColor = Qt::black;
|
||||
}
|
||||
cboHistoBand->setItemData( i - 1, Qt::black, Qt::ForegroundRole );
|
||||
}
|
||||
if ( i == myRedBand || i == myGreenBand || i == myBlueBand )
|
||||
{
|
||||
cboHistoBand->setItemData( i - 1, myColor, Qt::ForegroundRole );
|
||||
}
|
||||
mHistoColors << myColor;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//now draw actual graphs
|
||||
//
|
||||
@ -1164,8 +1317,8 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
//
|
||||
// scan through to get counts from layers' histograms
|
||||
//
|
||||
float myGlobalMin = 0;
|
||||
float myGlobalMax = 0;
|
||||
mHistoMin = 0;
|
||||
mHistoMax = 0;
|
||||
bool myFirstIteration = true;
|
||||
for ( int myIteratorInt = 1;
|
||||
myIteratorInt <= myBandCountInt;
|
||||
@ -1176,7 +1329,7 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
QwtPlotCurve * mypCurve = new QwtPlotCurve( tr( "Band %1" ).arg( myIteratorInt ) );
|
||||
mypCurve->setCurveAttribute( QwtPlotCurve::Fitted );
|
||||
mypCurve->setRenderHint( QwtPlotItem::RenderAntialiased );
|
||||
mypCurve->setPen( QPen( myColors.at( myIteratorInt ) ) );
|
||||
mypCurve->setPen( QPen( mHistoColors.at( myIteratorInt ) ) );
|
||||
#if defined(QWT_VERSION) && QWT_VERSION>=0x060000
|
||||
QVector<QPointF> data;
|
||||
#else
|
||||
@ -1199,26 +1352,51 @@ void QgsRasterLayerProperties::refreshHistogram()
|
||||
mypCurve->setData( myX2Data, myY2Data );
|
||||
#endif
|
||||
mypCurve->attach( mpPlot );
|
||||
if ( myFirstIteration || myGlobalMin < myRasterBandStats.minimumValue )
|
||||
if ( myFirstIteration || mHistoMin > myRasterBandStats.minimumValue )
|
||||
{
|
||||
myGlobalMin = myRasterBandStats.minimumValue;
|
||||
mHistoMin = myRasterBandStats.minimumValue;
|
||||
}
|
||||
if ( myFirstIteration || myGlobalMax < myRasterBandStats.maximumValue )
|
||||
if ( myFirstIteration || mHistoMax < myRasterBandStats.maximumValue )
|
||||
{
|
||||
myGlobalMax = myRasterBandStats.maximumValue;
|
||||
mHistoMax = myRasterBandStats.maximumValue;
|
||||
}
|
||||
QgsDebugMsg( QString( "computed histo min = %1 max = %2" ).arg( mHistoMin ).arg( mHistoMax ) );
|
||||
myFirstIteration = false;
|
||||
}
|
||||
// for x axis use band pixel values rather than gdal hist. bin values
|
||||
// subtract -0.5 to prevent rounding errors
|
||||
// see http://www.gdal.org/classGDALRasterBand.html#3f8889607d3b2294f7e0f11181c201c8
|
||||
mpPlot->setAxisScale( QwtPlot::xBottom,
|
||||
myGlobalMin - 0.5,
|
||||
myGlobalMax + 0.5 );
|
||||
mHistoMin - 0.5,
|
||||
mHistoMax + 0.5 );
|
||||
|
||||
mpPlot->replot();
|
||||
|
||||
// histo plot markers
|
||||
// memory leak?
|
||||
mHistoMarkerMin = new QwtPlotMarker();
|
||||
mHistoMarkerMin->attach( mpPlot );
|
||||
mHistoMarkerMax = new QwtPlotMarker();
|
||||
mHistoMarkerMax->attach( mpPlot );
|
||||
updateHistoMarkers();
|
||||
|
||||
// histo picker
|
||||
if ( ! mHistoPicker )
|
||||
{
|
||||
mHistoPicker = new QwtPlotPicker( mpPlot->canvas() );
|
||||
mHistoPicker->setSelectionFlags( QwtPicker::PointSelection | QwtPicker::DragSelection );
|
||||
// mHistoPicker->setTrackerMode( QwtPicker::ActiveOnly );
|
||||
mHistoPicker->setTrackerMode( QwtPicker::AlwaysOff );
|
||||
mHistoPicker->setRubberBand( QwtPicker::VLineRubberBand );
|
||||
mHistoPicker->setEnabled( false );
|
||||
connect( mHistoPicker, SIGNAL( selected( const QwtDoublePoint & ) ), this, SLOT( histoPickerSelected( const QwtDoublePoint & ) ) );
|
||||
}
|
||||
|
||||
disconnect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mHistogramProgress, SLOT( setValue( int ) ) );
|
||||
mHistogramProgress->hide();
|
||||
// mHistogramProgress->hide();
|
||||
stackedWidget2->setCurrentIndex( 0 );
|
||||
mpPlot->canvas()->setCursor( Qt::ArrowCursor );
|
||||
on_cboHistoBand_currentIndexChanged( -1 );
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
@ -1590,3 +1768,334 @@ void QgsRasterLayerProperties::toggleBuildPyramidsButton()
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::on_cboHistoBand_currentIndexChanged( int index )
|
||||
{
|
||||
// get the current index value, index can be -1
|
||||
index = cboHistoBand->currentIndex();
|
||||
if ( mHistoPicker != NULL )
|
||||
{
|
||||
mHistoPicker->setEnabled( false );
|
||||
mHistoPicker->setRubberBandPen( QPen( mHistoColors.at( index + 1 ) ) );
|
||||
}
|
||||
btnHistoMin->setEnabled( true );
|
||||
btnHistoMax->setEnabled( true );
|
||||
|
||||
int theBandNo = index + 1;
|
||||
QString minStr, maxStr;
|
||||
// TODO - there are 2 definitions of raster data type that should be unified
|
||||
// QgsRasterDataProvider::DataType and QgsContrastEnhancement::QgsRasterDataType
|
||||
// TODO - fix gdal provider: changes data type when nodata value is not found
|
||||
// this prevents us from getting proper min and max values here
|
||||
// minStr = QString::number( QgsContrastEnhancement::minimumValuePossible( ( QgsContrastEnhancement::QgsRasterDataType )
|
||||
// mRasterLayer->dataProvider()->dataType( theBandNo ) ) );
|
||||
// maxStr = QString::number( QgsContrastEnhancement::maximumValuePossible( ( QgsContrastEnhancement::QgsRasterDataType )
|
||||
// mRasterLayer->dataProvider()->dataType( theBandNo ) ) );
|
||||
QString rendererName = mRenderTypeComboBox->itemData( mRenderTypeComboBox->currentIndex() ).toString();
|
||||
|
||||
// TODO paletted + pseudo ?
|
||||
if ( rendererName == "singlebandgray" )
|
||||
{
|
||||
if ( theBandNo == mRendererWidget->selectedBand() )
|
||||
{
|
||||
minStr = mRendererWidget->min();
|
||||
maxStr = mRendererWidget->max();
|
||||
}
|
||||
}
|
||||
else if ( rendererName == "multibandcolor" )
|
||||
{
|
||||
for ( int i = 0; i <= 2; i++ )
|
||||
{
|
||||
if ( theBandNo == mRendererWidget->selectedBand( i ) )
|
||||
{
|
||||
minStr = mRendererWidget->min( i );
|
||||
maxStr = mRendererWidget->max( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leHistoMin->setText( minStr );
|
||||
leHistoMax->setText( maxStr );
|
||||
applyHistoMin();
|
||||
applyHistoMax();
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::histoActionTriggered( QAction* action )
|
||||
{
|
||||
if ( ! action )
|
||||
return;
|
||||
|
||||
// this approach is a bit of a hack, but we don't have to define slots for each action
|
||||
QString actionName = action->data().toString();
|
||||
|
||||
QgsDebugMsg( QString( "band = %1 action = %2" ).arg( cboHistoBand->currentIndex() + 1 ).arg( actionName ) );
|
||||
|
||||
if ( actionName.left( 5 ) == "Load " )
|
||||
{
|
||||
if ( actionName == "Load apply all" )
|
||||
return;
|
||||
|
||||
QgsRasterBandStats myRasterBandStats;
|
||||
QVector<int> myBands;
|
||||
double minMaxValues[2];
|
||||
bool ok = false;
|
||||
|
||||
// get "Load apply all" value to find which band(s) need updating
|
||||
QList< QAction* > actions;
|
||||
if ( action->actionGroup() )
|
||||
actions = action->actionGroup()->actions();
|
||||
foreach( QAction* tmpAction, actions )
|
||||
{
|
||||
if ( tmpAction && ( tmpAction->data().toString() == "Load apply all" ) )
|
||||
{
|
||||
// add all bands
|
||||
if ( tmpAction->isChecked() )
|
||||
{
|
||||
int myBandCountInt = mRasterLayer->bandCount();
|
||||
for ( int myIteratorInt = 1;
|
||||
myIteratorInt <= myBandCountInt;
|
||||
++myIteratorInt )
|
||||
{
|
||||
if ( myIteratorInt != cboHistoBand->currentIndex() + 1 )
|
||||
myBands << myIteratorInt;
|
||||
}
|
||||
}
|
||||
// add current band to the end
|
||||
myBands << cboHistoBand->currentIndex() + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// don't update markers every time
|
||||
if ( myBands.size() > 1 )
|
||||
{
|
||||
leHistoMin->blockSignals( true );
|
||||
leHistoMax->blockSignals( true );
|
||||
}
|
||||
foreach( int theBandNo, myBands )
|
||||
{
|
||||
ok = false;
|
||||
if ( actionName == "Load actual" )
|
||||
{
|
||||
ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::Actual,
|
||||
theBandNo, minMaxValues );
|
||||
}
|
||||
else if ( actionName == "Load estimate" )
|
||||
{
|
||||
ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::Estimate,
|
||||
theBandNo, minMaxValues );
|
||||
}
|
||||
else if ( actionName == "Load extent" )
|
||||
{
|
||||
ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::CurrentExtent,
|
||||
theBandNo, minMaxValues );
|
||||
}
|
||||
else if ( actionName == "Load 1 stddev" )
|
||||
{
|
||||
double myStdDev = 1.0;
|
||||
ok = mRendererWidget->bandMinMaxFromStdDev( myStdDev, theBandNo, minMaxValues );
|
||||
}
|
||||
|
||||
// apply current item
|
||||
cboHistoBand->setCurrentIndex( theBandNo - 1 );
|
||||
if ( !ok || actionName == "Load reset" )
|
||||
{
|
||||
leHistoMin->clear();
|
||||
leHistoMax->clear();
|
||||
// TODO - fix gdal provider: changes data type when nodata value is not found
|
||||
// this prevents us from getting proper min and max values here
|
||||
// minMaxValues[0] = QgsContrastEnhancement::minimumValuePossible( ( QgsContrastEnhancement::QgsRasterDataType )
|
||||
// mRasterLayer->dataProvider()->dataType( theBandNo ) );
|
||||
// minMaxValues[1] = QgsContrastEnhancement::maximumValuePossible( ( QgsContrastEnhancement::QgsRasterDataType )
|
||||
// mRasterLayer->dataProvider()->dataType( theBandNo ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
leHistoMin->setText( QString::number( minMaxValues[0] ) );
|
||||
leHistoMax->setText( QString::number( minMaxValues[1] ) );
|
||||
}
|
||||
applyHistoMin( );
|
||||
applyHistoMax( );
|
||||
}
|
||||
// update markers
|
||||
if ( myBands.size() > 1 )
|
||||
{
|
||||
leHistoMin->blockSignals( false );
|
||||
leHistoMax->blockSignals( false );
|
||||
updateHistoMarkers();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::applyHistoMin( )
|
||||
{
|
||||
int theBandNo = cboHistoBand->currentIndex() + 1;
|
||||
QString rendererName = mRenderTypeComboBox->itemData( mRenderTypeComboBox->currentIndex() ).toString();
|
||||
|
||||
// TMP ET TODO - paletted + pseudo
|
||||
if ( rendererName.startsWith( "singlebandgray" ) )
|
||||
{
|
||||
if ( theBandNo == mRendererWidget->selectedBand( ) )
|
||||
{
|
||||
mRendererWidget->setMin( leHistoMin->text() );
|
||||
}
|
||||
}
|
||||
else if ( rendererName == "multibandcolor" )
|
||||
{
|
||||
for ( int i = 0; i <= 2; i++ )
|
||||
{
|
||||
if ( theBandNo == mRendererWidget->selectedBand( i ) )
|
||||
mRendererWidget->setMin( leHistoMin->text(), i );
|
||||
}
|
||||
}
|
||||
|
||||
updateHistoMarkers();
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::applyHistoMax( )
|
||||
{
|
||||
int theBandNo = cboHistoBand->currentIndex() + 1;
|
||||
QString rendererName = mRenderTypeComboBox->itemData( mRenderTypeComboBox->currentIndex() ).toString();
|
||||
|
||||
if ( rendererName.startsWith( "singleband" ) )
|
||||
{
|
||||
if ( theBandNo == mRendererWidget->selectedBand( ) )
|
||||
{
|
||||
mRendererWidget->setMax( leHistoMax->text() );
|
||||
}
|
||||
}
|
||||
else if ( rendererName == "multibandcolor" )
|
||||
{
|
||||
for ( int i = 0; i <= 2; i++ )
|
||||
{
|
||||
if ( theBandNo == mRendererWidget->selectedBand( i ) )
|
||||
mRendererWidget->setMax( leHistoMax->text(), i );
|
||||
}
|
||||
}
|
||||
|
||||
updateHistoMarkers();
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::on_btnHistoMin_toggled()
|
||||
{
|
||||
if ( mpPlot != NULL && mHistoPicker != NULL )
|
||||
{
|
||||
if ( QApplication::overrideCursor() )
|
||||
QApplication::restoreOverrideCursor();
|
||||
if ( btnHistoMin->isChecked() )
|
||||
{
|
||||
btnHistoMax->setChecked( false );
|
||||
QApplication::setOverrideCursor( Qt::PointingHandCursor );
|
||||
}
|
||||
mHistoPicker->setEnabled( btnHistoMin->isChecked() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::on_btnHistoMax_toggled()
|
||||
{
|
||||
if ( mpPlot != NULL && mHistoPicker != NULL )
|
||||
{
|
||||
if ( QApplication::overrideCursor() )
|
||||
QApplication::restoreOverrideCursor();
|
||||
if ( btnHistoMax->isChecked() )
|
||||
{
|
||||
btnHistoMin->setChecked( false );
|
||||
QApplication::setOverrideCursor( Qt::PointingHandCursor );
|
||||
}
|
||||
mHistoPicker->setEnabled( btnHistoMax->isChecked() );
|
||||
}
|
||||
}
|
||||
|
||||
// local function used by histoPickerSelected(), to get a rounded picked value
|
||||
// this is sensitive and may not always be correct, needs more testing
|
||||
QString findClosestTickVal( double target, QwtScaleDiv * scale, int div = 100 )
|
||||
{
|
||||
if ( scale == NULL ) return "";
|
||||
|
||||
QList< double > minorTicks = scale->ticks( QwtScaleDiv::MinorTick );
|
||||
QList< double > majorTicks = scale->ticks( QwtScaleDiv::MajorTick );
|
||||
double diff = ( minorTicks[1] - minorTicks[0] ) / div;
|
||||
double min = majorTicks[0] - diff;
|
||||
if ( min > target )
|
||||
min -= ( majorTicks[1] - majorTicks[0] );
|
||||
double max = scale->upperBound();
|
||||
double closest = target;
|
||||
double current = min;
|
||||
|
||||
while ( current < max )
|
||||
{
|
||||
current += diff;
|
||||
if ( current > target )
|
||||
{
|
||||
closest = ( abs( target - current + diff ) < abs( target - current ) ) ? current - diff : current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QgsDebugMsg( QString( "target=%1 div=%2 closest=%3" ).arg( target ).arg( div ).arg( closest ) );
|
||||
return QString::number( closest );
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::histoPickerSelected( const QwtDoublePoint & pos )
|
||||
{
|
||||
if ( btnHistoMin->isChecked() )
|
||||
{
|
||||
leHistoMin->setText( findClosestTickVal( pos.x(), mpPlot->axisScaleDiv( QwtPlot::xBottom ) ) );
|
||||
applyHistoMin();
|
||||
btnHistoMin->setChecked( false );
|
||||
}
|
||||
else if ( btnHistoMax->isChecked() )
|
||||
{
|
||||
leHistoMax->setText( findClosestTickVal( pos.x(), mpPlot->axisScaleDiv( QwtPlot::xBottom ) ) );
|
||||
applyHistoMax();
|
||||
btnHistoMax->setChecked( false );
|
||||
}
|
||||
if ( QApplication::overrideCursor() )
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::updateHistoMarkers( )
|
||||
{
|
||||
// hack to not update markers
|
||||
if ( leHistoMin->signalsBlocked() )
|
||||
return;
|
||||
// todo error checking
|
||||
if ( mpPlot == NULL || mHistoMarkerMin == NULL || mHistoMarkerMax == NULL )
|
||||
return;
|
||||
|
||||
if ( ! cbxHistoShow->isChecked() )
|
||||
{
|
||||
mHistoMarkerMin->hide();
|
||||
mHistoMarkerMax->hide();
|
||||
mpPlot->replot();
|
||||
return;
|
||||
}
|
||||
|
||||
int theBandNo = cboHistoBand->currentIndex() + 1;
|
||||
double minVal = mHistoMin;
|
||||
double maxVal = mHistoMax;
|
||||
QString minStr = leHistoMin->text();
|
||||
QString maxStr = leHistoMax->text();
|
||||
if ( minStr != "" )
|
||||
minVal = minStr.toDouble();
|
||||
if ( maxStr != "" )
|
||||
maxVal = maxStr.toDouble();
|
||||
|
||||
QPen linePen = QPen( mHistoColors.at( theBandNo ) );
|
||||
linePen.setStyle( Qt::DashLine );
|
||||
mHistoMarkerMin->setLineStyle( QwtPlotMarker::VLine );
|
||||
mHistoMarkerMin->setLinePen( linePen );
|
||||
mHistoMarkerMin->setXValue( minVal );
|
||||
mHistoMarkerMin->show();
|
||||
mHistoMarkerMax->setLineStyle( QwtPlotMarker::VLine );
|
||||
mHistoMarkerMax->setLinePen( linePen );
|
||||
mHistoMarkerMax->setXValue( maxVal );
|
||||
mHistoMarkerMax->show();
|
||||
|
||||
mpPlot->replot();
|
||||
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ class QgsRasterLayer;
|
||||
class QgsMapToolEmitPoint;
|
||||
class QgsRasterRenderer;
|
||||
class QgsRasterRendererWidget;
|
||||
class QwtPlotPicker;
|
||||
class QwtPlotMarker;
|
||||
|
||||
/**Property sheet for a raster map layer
|
||||
*@author Tim Sutton
|
||||
@ -100,6 +102,23 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
|
||||
/**Enable or disable Build pyramids button depending on selection in pyramids list*/
|
||||
void toggleBuildPyramidsButton();
|
||||
|
||||
// histogram
|
||||
|
||||
/** Used when the histogram band selector changes, or when tab is loaded. */
|
||||
void on_cboHistoBand_currentIndexChanged( int );
|
||||
/** Applies the selected min/max values to the renderer widget. */
|
||||
void applyHistoMin( );
|
||||
void applyHistoMax( );
|
||||
/** Button to activate picking of the min/max value on the graph. */
|
||||
void on_btnHistoMin_toggled();
|
||||
void on_btnHistoMax_toggled();
|
||||
/** Called when a selection has been made using the plot picker. */
|
||||
void histoPickerSelected( const QwtDoublePoint & );
|
||||
/** Various actions that are stored in btnHistoActions. */
|
||||
void histoActionTriggered( QAction* );
|
||||
/** Draw the min/max markers on the histogram plot. */
|
||||
void updateHistoMarkers();
|
||||
|
||||
signals:
|
||||
/** emitted when changes to layer were saved to update legend */
|
||||
void refreshLegend( QString layerID, bool expandItem );
|
||||
@ -154,5 +173,13 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
|
||||
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
QgsMapToolEmitPoint* mPixelSelectorTool;
|
||||
|
||||
// histogram
|
||||
QwtPlotPicker* mHistoPicker;
|
||||
QwtPlotMarker* mHistoMarkerMin;
|
||||
QwtPlotMarker* mHistoMarkerMax;
|
||||
double mHistoMin;
|
||||
double mHistoMax;
|
||||
QVector<QColor> mHistoColors;
|
||||
};
|
||||
#endif
|
||||
|
@ -204,38 +204,20 @@ void QgsMultiBandColorRendererWidget::loadMinMaxValueForBand( int band, QLineEdi
|
||||
return;
|
||||
}
|
||||
|
||||
QgsRasterDataProvider* provider = mRasterLayer->dataProvider();
|
||||
if ( !provider )
|
||||
{
|
||||
return;
|
||||
}
|
||||
double minMaxValues[2];
|
||||
bool ok = false;
|
||||
|
||||
if ( band < 0 )
|
||||
{
|
||||
minEdit->clear();
|
||||
maxEdit->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
double minVal = 0;
|
||||
double maxVal = 0;
|
||||
if ( mEstimateRadioButton->isChecked() )
|
||||
{
|
||||
minVal = provider->minimumValue( band );
|
||||
maxVal = provider->maximumValue( band );
|
||||
ok = bandMinMax( Estimate, band, minMaxValues );
|
||||
}
|
||||
else if ( mActualRadioButton->isChecked() )
|
||||
{
|
||||
QgsRasterBandStats rasterBandStats = mRasterLayer->bandStatistics( band );
|
||||
minVal = rasterBandStats.minimumValue;
|
||||
maxVal = rasterBandStats.maximumValue;
|
||||
ok = bandMinMax( Actual, band, minMaxValues );
|
||||
}
|
||||
else if ( mCurrentExtentRadioButton->isChecked() )
|
||||
{
|
||||
double minMax[2];
|
||||
mRasterLayer->computeMinimumMaximumFromLastExtent( band, minMax );
|
||||
minVal = minMax[0];
|
||||
maxVal = minMax[1];
|
||||
ok = bandMinMax( CurrentExtent, band, minMaxValues );
|
||||
}
|
||||
else if ( mUseStdDevRadioButton->isChecked() )
|
||||
{
|
||||
@ -245,8 +227,16 @@ void QgsMultiBandColorRendererWidget::loadMinMaxValueForBand( int band, QLineEdi
|
||||
maxVal = rasterBandStats.mean + diff;
|
||||
}
|
||||
|
||||
minEdit->setText( QString::number( minVal ) );
|
||||
maxEdit->setText( QString::number( maxVal ) );
|
||||
if ( ok )
|
||||
{
|
||||
minEdit->setText( QString::number( minMaxValues[0] ) );
|
||||
maxEdit->setText( QString::number( minMaxValues[1] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
minEdit->clear();
|
||||
maxEdit->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setFromRenderer( const QgsRasterRenderer* r )
|
||||
@ -269,3 +259,96 @@ void QgsMultiBandColorRendererWidget::setFromRenderer( const QgsRasterRenderer*
|
||||
mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findText( tr( "Blue" ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsMultiBandColorRendererWidget::min( int index )
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
return mRedMinLineEdit->text();
|
||||
break;
|
||||
case 1:
|
||||
return mGreenMinLineEdit->text();
|
||||
break;
|
||||
case 2:
|
||||
return mBlueMinLineEdit->text();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QString( );
|
||||
}
|
||||
|
||||
QString QgsMultiBandColorRendererWidget::max( int index )
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
return mRedMaxLineEdit->text();
|
||||
break;
|
||||
case 1:
|
||||
return mGreenMaxLineEdit->text();
|
||||
break;
|
||||
case 2:
|
||||
return mBlueMaxLineEdit->text();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QString( );
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setMin( QString value, int index )
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
mRedMinLineEdit->setText( value );
|
||||
break;
|
||||
case 1:
|
||||
mGreenMinLineEdit->setText( value );
|
||||
break;
|
||||
case 2:
|
||||
mBlueMinLineEdit->setText( value );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsMultiBandColorRendererWidget::setMax( QString value, int index )
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
mRedMaxLineEdit->setText( value );
|
||||
break;
|
||||
case 1:
|
||||
mGreenMaxLineEdit->setText( value );
|
||||
break;
|
||||
case 2:
|
||||
mBlueMaxLineEdit->setText( value );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int QgsMultiBandColorRendererWidget::selectedBand( int index )
|
||||
{
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
return mRedBandComboBox->currentIndex();
|
||||
break;
|
||||
case 1:
|
||||
return mGreenBandComboBox->currentIndex();
|
||||
break;
|
||||
case 2:
|
||||
return mBlueBandComboBox->currentIndex();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -40,6 +40,12 @@ class GUI_EXPORT QgsMultiBandColorRendererWidget: public QgsRasterRendererWidget
|
||||
|
||||
void setFromRenderer( const QgsRasterRenderer* r );
|
||||
|
||||
QString min( int index = 0 );
|
||||
QString max( int index = 0 );
|
||||
void setMin( QString value, int index = 0 );
|
||||
void setMax( QString value, int index = 0 );
|
||||
int selectedBand( int index = 0 );
|
||||
|
||||
private slots:
|
||||
void on_mLoadPushButton_clicked();
|
||||
|
||||
|
@ -41,3 +41,64 @@ QString QgsRasterRendererWidget::displayBandName( int band ) const
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
bool QgsRasterRendererWidget::bandMinMax( LoadMinMaxAlgo loadAlgo, int band, double* minMaxValues )
|
||||
{
|
||||
if ( !mRasterLayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QgsRasterDataProvider* provider = mRasterLayer->dataProvider();
|
||||
if ( !provider )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( band < 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( loadAlgo == Estimate )
|
||||
{
|
||||
minMaxValues[0] = provider->minimumValue( band );
|
||||
minMaxValues[1] = provider->maximumValue( band );
|
||||
}
|
||||
else if ( loadAlgo == Actual )
|
||||
{
|
||||
QgsRasterBandStats rasterBandStats = mRasterLayer->bandStatistics( band );
|
||||
minMaxValues[0] = rasterBandStats.minimumValue;
|
||||
minMaxValues[1] = rasterBandStats.maximumValue;
|
||||
}
|
||||
else if ( loadAlgo == CurrentExtent )
|
||||
{
|
||||
mRasterLayer->computeMinimumMaximumFromLastExtent( band, minMaxValues );
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsRasterRendererWidget::bandMinMaxFromStdDev( double stdDev, int band, double* minMaxValues )
|
||||
{
|
||||
if ( !mRasterLayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QgsRasterDataProvider* provider = mRasterLayer->dataProvider();
|
||||
if ( !provider )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( band < 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsRasterBandStats myRasterBandStats = mRasterLayer->bandStatistics( band );
|
||||
minMaxValues[0] = myRasterBandStats.mean - ( stdDev * myRasterBandStats.stdDev );
|
||||
minMaxValues[1] = myRasterBandStats.mean + ( stdDev * myRasterBandStats.stdDev );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -29,11 +29,27 @@ class GUI_EXPORT QgsRasterRendererWidget: public QWidget
|
||||
QgsRasterRendererWidget( QgsRasterLayer* layer ) { mRasterLayer = layer; }
|
||||
virtual ~QgsRasterRendererWidget() {}
|
||||
|
||||
enum LoadMinMaxAlgo
|
||||
{
|
||||
Estimate,
|
||||
Actual,
|
||||
CurrentExtent
|
||||
};
|
||||
|
||||
virtual QgsRasterRenderer* renderer() = 0;
|
||||
|
||||
void setRasterLayer( QgsRasterLayer* layer ) { mRasterLayer = layer; }
|
||||
const QgsRasterLayer* rasterLayer() const { return mRasterLayer; }
|
||||
|
||||
virtual QString min( int index = 0 ) { Q_UNUSED( index ); return QString( ); }
|
||||
virtual QString max( int index = 0 ) { Q_UNUSED( index ); return QString( ); }
|
||||
virtual void setMin( QString value, int index = 0 ) { Q_UNUSED( index ); Q_UNUSED( value ); }
|
||||
virtual void setMax( QString value, int index = 0 ) { Q_UNUSED( index ); Q_UNUSED( value ); }
|
||||
virtual int selectedBand( int index = 0 ) { Q_UNUSED( index ); return -1; }
|
||||
|
||||
bool bandMinMax( LoadMinMaxAlgo loadAlgo, int band, double *values );
|
||||
bool bandMinMaxFromStdDev( double stdDev, int band, double *values );
|
||||
|
||||
protected:
|
||||
QgsRasterLayer* mRasterLayer;
|
||||
/**Returns a band name for display. First choice is color name, otherwise band number*/
|
||||
|
@ -82,36 +82,27 @@ QgsRasterRenderer* QgsSingleBandGrayRendererWidget::renderer()
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::on_mLoadPushButton_clicked()
|
||||
{
|
||||
if ( !mRasterLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
QgsRasterDataProvider* provider = mRasterLayer->dataProvider();
|
||||
if ( !provider )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int band = mGrayBandComboBox->itemData( mGrayBandComboBox->currentIndex() ).toInt();
|
||||
double minVal = 0;
|
||||
double maxVal = 0;
|
||||
double minMaxValues[2];
|
||||
bool ok = false;
|
||||
|
||||
if ( mEstimateRadioButton->isChecked() )
|
||||
{
|
||||
minVal = provider->minimumValue( band );
|
||||
maxVal = provider->maximumValue( band );
|
||||
ok = bandMinMax( Estimate, band, minMaxValues );
|
||||
}
|
||||
else if ( mActualRadioButton->isChecked() )
|
||||
{
|
||||
QgsRasterBandStats rasterBandStats = mRasterLayer->bandStatistics( band );
|
||||
minVal = rasterBandStats.minimumValue;
|
||||
maxVal = rasterBandStats.maximumValue;
|
||||
ok = bandMinMax( Actual, band, minMaxValues );
|
||||
}
|
||||
else if ( mCurrentExtentRadioButton->isChecked() )
|
||||
{
|
||||
double minMax[2];
|
||||
mRasterLayer->computeMinimumMaximumFromLastExtent( band, minMax );
|
||||
minVal = minMax[0];
|
||||
maxVal = minMax[1];
|
||||
ok = bandMinMax( CurrentExtent, band, minMaxValues );
|
||||
}
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
mMinLineEdit->setText( QString::number( minMaxValues[0] ) );
|
||||
mMaxLineEdit->setText( QString::number( minMaxValues[1] ) );
|
||||
}
|
||||
else if ( mUseStdDevRadioButton->isChecked() )
|
||||
{
|
||||
@ -122,11 +113,9 @@ void QgsSingleBandGrayRendererWidget::on_mLoadPushButton_clicked()
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
mMinLineEdit->clear();
|
||||
mMaxLineEdit->clear();
|
||||
}
|
||||
|
||||
mMinLineEdit->setText( QString::number( minVal ) );
|
||||
mMaxLineEdit->setText( QString::number( maxVal ) );
|
||||
}
|
||||
|
||||
void QgsSingleBandGrayRendererWidget::setFromRenderer( const QgsRasterRenderer* r )
|
||||
|
@ -34,6 +34,12 @@ class GUI_EXPORT QgsSingleBandGrayRendererWidget: public QgsRasterRendererWidget
|
||||
|
||||
void setFromRenderer( const QgsRasterRenderer* r );
|
||||
|
||||
QString min( int index = 0 ) { Q_UNUSED( index ); return mMinLineEdit->text(); }
|
||||
QString max( int index = 0 ) { Q_UNUSED( index ); return mMaxLineEdit->text(); }
|
||||
void setMin( QString value, int index = 0 ) { Q_UNUSED( index ); mMinLineEdit->setText( value ); }
|
||||
void setMax( QString value, int index = 0 ) { Q_UNUSED( index ); mMaxLineEdit->setText( value ); }
|
||||
int selectedBand( int index = 0 ) { Q_UNUSED( index ); return mGrayBandComboBox->currentIndex() + 1; }
|
||||
|
||||
private slots:
|
||||
void on_mLoadPushButton_clicked();
|
||||
};
|
||||
|
@ -1467,12 +1467,12 @@ void QgsGdalProvider::populateHistogram( int theBandNo, QgsRasterBandStats & t
|
||||
if ( myHistogramArray[myBin] < 0 ) //can't have less than 0 pixels of any value
|
||||
{
|
||||
theBandStats.histogramVector->push_back( 0 );
|
||||
QgsDebugMsg( "Added 0 to histogram vector as freq was negative!" );
|
||||
// QgsDebugMsg( "Added 0 to histogram vector as freq was negative!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
theBandStats.histogramVector->push_back( myHistogramArray[myBin] );
|
||||
QgsDebugMsg( "Added " + QString::number( myHistogramArray[myBin] ) + " to histogram vector" );
|
||||
// QgsDebugMsg( "Added " + QString::number( myHistogramArray[myBin] ) + " to histogram vector" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>706</width>
|
||||
<width>722</width>
|
||||
<height>663</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -825,7 +825,7 @@
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;">
|
||||
<tr>
|
||||
<td style="border: none;">
|
||||
@ -933,21 +933,361 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QwtPlot" name="mpPlot"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QProgressBar" name="mHistogramProgress">
|
||||
<property name="value">
|
||||
<widget class="QStackedWidget" name="stackedWidget2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="mSaveAsImageButton">
|
||||
<property name="text">
|
||||
<string>Save as image...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>../../images/themes/default/mActionFileSave.png</normaloff>../../images/themes/default/mActionFileSave.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="page1_2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnHistoActions">
|
||||
<property name="toolTip">
|
||||
<string>Load min/max values from Bands</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mAction.png</normaloff>:/images/themes/default/mAction.png</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxHistoShow">
|
||||
<property name="toolTip">
|
||||
<string>Show Min and Max on plot</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Min/Max</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Band:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboHistoBand">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<property name="spacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnHistoMin">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Pick Min value on graph</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionTouch2.png</normaloff>:/images/themes/default/mActionTouch2.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="leHistoMin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_15">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<property name="spacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnHistoMax">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Pick Max value on graph</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionTouch2.png</normaloff>:/images/themes/default/mActionTouch2.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="leHistoMax">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_16">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_17">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mSaveAsImageButton">
|
||||
<property name="toolTip">
|
||||
<string>Save plot</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save as image...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionFileSave.png</normaloff>:/images/themes/default/mActionFileSave.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page2_2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="mHistogramProgress">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -1000,6 +1340,7 @@ p, li { white-space: pre-wrap; }
|
||||
<class>QwtPlot</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>qwt_plot.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
|
Loading…
x
Reference in New Issue
Block a user