33 #include <qwt_global.h>    34 #include <qwt_plot_canvas.h>    35 #include <qwt_legend.h>    37 #include <qwt_plot_curve.h>    38 #include <qwt_plot_grid.h>    39 #include <qwt_plot_marker.h>    40 #include <qwt_plot_picker.h>    41 #include <qwt_picker_machine.h>    42 #include <qwt_plot_zoomer.h>    43 #include <qwt_plot_layout.h>    44 #include <qwt_plot_renderer.h>    45 #include <qwt_plot_histogram.h>    61   connect( mSaveAsImageButton, &QToolButton::clicked, 
this, &QgsRasterHistogramWidget::mSaveAsImageButton_clicked );
    62   connect( cboHistoBand, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsRasterHistogramWidget::cboHistoBand_currentIndexChanged );
    63   connect( btnHistoMin, &QToolButton::toggled, 
this, &QgsRasterHistogramWidget::btnHistoMin_toggled );
    64   connect( btnHistoMax, &QToolButton::toggled, 
this, &QgsRasterHistogramWidget::btnHistoMax_toggled );
    65   connect( btnHistoCompute, &QPushButton::clicked, 
this, &QgsRasterHistogramWidget::btnHistoCompute_clicked );
    69   mRendererWidget = 
nullptr;
    70   mRendererName = QStringLiteral( 
"singlebandgray" );
    75   mHistoPicker = 
nullptr;
    76   mHistoZoomer = 
nullptr;
    77   mHistoMarkerMin = 
nullptr;
    78   mHistoMarkerMax = 
nullptr;
    81   mHistoShowMarkers = settings.
value( QStringLiteral( 
"Raster/histogram/showMarkers" ), 
false ).toBool();
    83   mHistoZoomToMinMax = settings.
value( QStringLiteral( 
"Raster/histogram/zoomToMinMax" ), 
false ).toBool();
    84   mHistoUpdateStyleToMinMax = settings.
value( QStringLiteral( 
"Raster/histogram/updateStyleToMinMax" ), 
true ).toBool();
    85   mHistoDrawLines = settings.
value( QStringLiteral( 
"Raster/histogram/drawLines" ), 
true ).toBool();
    87   mHistoShowBands = ShowAll;
    93     int myBandCountInt = mRasterLayer->
bandCount();
    94     for ( 
int myIteratorInt = 1;
    95           myIteratorInt <= myBandCountInt;
    98       cboHistoBand->addItem( mRasterLayer->
bandName( myIteratorInt ) );
   107     leHistoMin->setValidator( 
new QDoubleValidator( 
this ) );
   108     leHistoMax->setValidator( 
new QDoubleValidator( 
this ) );
   114     connect( leHistoMin, &QLineEdit::editingFinished, 
this, &QgsRasterHistogramWidget::applyHistoMin );
   115     connect( leHistoMax, &QLineEdit::editingFinished, 
this, &QgsRasterHistogramWidget::applyHistoMax );
   119     QMenu *menu = 
new QMenu( 
this );
   120     menu->setSeparatorsCollapsible( 
false );
   121     btnHistoActions->setMenu( menu );
   122     QActionGroup *group = 
nullptr;
   123     QAction *action = 
nullptr;
   126     group = 
new QActionGroup( 
this );
   127     group->setExclusive( 
false );
   128     connect( group, &QActionGroup::triggered, 
this, &QgsRasterHistogramWidget::histoActionTriggered );
   129     action = 
new QAction( tr( 
"Min/Max options" ), group );
   130     action->setSeparator( 
true );
   131     menu->addAction( action );
   132     action = 
new QAction( tr( 
"Always show min/max markers" ), group );
   133     action->setData( QVariant( 
"Show markers" ) );
   134     action->setCheckable( 
true );
   135     action->setChecked( mHistoShowMarkers );
   136     menu->addAction( action );
   137     action = 
new QAction( tr( 
"Zoom to min/max" ), group );
   138     action->setData( QVariant( 
"Zoom min_max" ) );
   139     action->setCheckable( 
true );
   140     action->setChecked( mHistoZoomToMinMax );
   141     menu->addAction( action );
   142     action = 
new QAction( tr( 
"Update style to min/max" ), group );
   143     action->setData( QVariant( 
"Update min_max" ) );
   144     action->setCheckable( 
true );
   145     action->setChecked( mHistoUpdateStyleToMinMax );
   146     menu->addAction( action );
   149     group = 
new QActionGroup( 
this );
   150     group->setExclusive( 
false );
   151     connect( group, &QActionGroup::triggered, 
this, &QgsRasterHistogramWidget::histoActionTriggered );
   152     action = 
new QAction( tr( 
"Visibility" ), group );
   153     action->setSeparator( 
true );
   154     menu->addAction( action );
   155     group = 
new QActionGroup( 
this );
   156     group->setExclusive( 
true ); 
   157     connect( group, &QActionGroup::triggered, 
this, &QgsRasterHistogramWidget::histoActionTriggered );
   158     action = 
new QAction( tr( 
"Show all bands" ), group );
   159     action->setData( QVariant( 
"Show all" ) );
   160     action->setCheckable( 
true );
   161     action->setChecked( mHistoShowBands == ShowAll );
   162     menu->addAction( action );
   163     action = 
new QAction( tr( 
"Show RGB/Gray band(s)" ), group );
   164     action->setData( QVariant( 
"Show RGB" ) );
   165     action->setCheckable( 
true );
   166     action->setChecked( mHistoShowBands == ShowRGB );
   167     menu->addAction( action );
   168     action = 
new QAction( tr( 
"Show selected band" ), group );
   169     action->setData( QVariant( 
"Show selected" ) );
   170     action->setCheckable( 
true );
   171     action->setChecked( mHistoShowBands == ShowSelected );
   172     menu->addAction( action );
   175     group = 
new QActionGroup( 
this );
   176     group->setExclusive( 
false );
   177     connect( group, &QActionGroup::triggered, 
this, &QgsRasterHistogramWidget::histoActionTriggered );
   178     action = 
new QAction( tr( 
"Display" ), group );
   179     action->setSeparator( 
true );
   180     menu->addAction( action );
   182     action = 
new QAction( QString(), group );
   183     action->setData( QVariant( 
"Draw lines" ) );
   186       action->setText( tr( 
"Draw as lines" ) );
   187       action->setCheckable( 
true );
   188       action->setChecked( mHistoDrawLines );
   192       action->setText( tr( 
"Draw as lines (only int layers)" ) );
   193       action->setEnabled( 
false );
   195     menu->addAction( action );
   198     action = 
new QAction( tr( 
"Actions" ), group );
   199     action->setSeparator( 
true );
   200     menu->addAction( action );
   203     group = 
new QActionGroup( 
this );
   204     group->setExclusive( 
false );
   205     connect( group, &QActionGroup::triggered, 
this, &QgsRasterHistogramWidget::histoActionTriggered );
   206     action = 
new QAction( tr( 
"Reset" ), group );
   207     action->setData( QVariant( 
"Load reset" ) );
   208     menu->addAction( action );
   214     action = 
new QAction( tr( 
"Load min/max" ), group );
   215     action->setSeparator( 
true );
   216     menu->addAction( action );
   217     action = 
new QAction( tr( 
"Estimate (faster)" ), group );
   218     action->setData( QVariant( 
"Load estimate" ) );
   219     menu->addAction( action );
   220     action = 
new QAction( tr( 
"Actual (slower)" ), group );
   221     action->setData( QVariant( 
"Load actual" ) );
   222     menu->addAction( action );
   223     action = 
new QAction( tr( 
"Current extent" ), group );
   224     action->setData( QVariant( 
"Load extent" ) );
   225     menu->addAction( action );
   226     action = 
new QAction( tr( 
"Use stddev (1.0)" ), group );
   227     action->setData( QVariant( 
"Load 1 stddev" ) );
   228     menu->addAction( action );
   229     action = 
new QAction( tr( 
"Use stddev (custom)" ), group );
   230     action->setData( QVariant( 
"Load stddev" ) );
   231     menu->addAction( action );
   232     action = 
new QAction( tr( 
"Load for each band" ), group );
   233     action->setData( QVariant( 
"Load apply all" ) );
   234     action->setCheckable( 
true );
   235     action->setChecked( mHistoLoadApplyAll );
   236     menu->addAction( action );
   240     action = 
new QAction( tr( 
"Recompute Histogram" ), group );
   241     action->setData( QVariant( 
"Compute histogram" ) );
   242     menu->addAction( action );
   250   mRendererName = name;
   251   mRendererWidget = rendererWidget;
   253   cboHistoBand_currentIndexChanged( -1 );
   261     cboHistoBand_currentIndexChanged( -1 );
   265     if ( QApplication::overrideCursor() )
   266       QApplication::restoreOverrideCursor();
   267     btnHistoMin->setChecked( 
false );
   268     btnHistoMax->setChecked( 
false );
   272 void QgsRasterHistogramWidget::btnHistoCompute_clicked()
   287   int myBandCountInt = mRasterLayer->
bandCount();
   290   if ( ! forceComputeFlag )
   292     for ( 
int myIteratorInt = 1;
   293           myIteratorInt <= myBandCountInt;
   296       int sampleSize = 250000; 
   297       if ( !mRasterLayer->
dataProvider()->
hasHistogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), 
QgsRectangle(), sampleSize ) )
   299         QgsDebugMsg( QStringLiteral( 
"band %1 does not have cached histo" ).arg( myIteratorInt ) );
   306   stackedWidget2->setCurrentIndex( 1 );
   310   QApplication::setOverrideCursor( Qt::WaitCursor );
   312   for ( 
int myIteratorInt = 1;
   313         myIteratorInt <= myBandCountInt;
   316     int sampleSize = 250000; 
   317     mRasterLayer->
dataProvider()->
histogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), 
QgsRectangle(), sampleSize, 
false, feedback.get() );
   321   stackedWidget2->setCurrentIndex( 0 );
   322   QApplication::restoreOverrideCursor();
   339   int myBandCountInt = mRasterLayer->
bandCount();
   344     QgsDebugMsg( QStringLiteral( 
"raster does not have cached histogram" ) );
   345     stackedWidget2->setCurrentIndex( 2 );
   350   mpPlot->detachItems();
   353   mpPlot->setAutoDelete( 
true );
   354   mpPlot->setTitle( QObject::tr( 
"Raster Histogram" ) );
   355   mpPlot->insertLegend( 
new QwtLegend(), QwtPlot::BottomLegend );
   357   mpPlot->setAxisTitle( QwtPlot::xBottom, QObject::tr( 
"Pixel Value" ) );
   358   mpPlot->setAxisTitle( QwtPlot::yLeft, QObject::tr( 
"Frequency" ) );
   359   mpPlot->setAxisAutoScale( QwtPlot::yLeft );
   363   QwtPlotGrid *myGrid = 
new QwtPlotGrid();
   364   myGrid->attach( mpPlot );
   367   mHistoColors.clear();
   368   mHistoColors << Qt::black; 
   369   QVector<QColor> myColors;
   370   myColors << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::darkYellow << Qt::cyan;
   371   qsrand( myBandCountInt * 100 ); 
   372   while ( myColors.size() <= myBandCountInt )
   375              QColor( 1 + ( 
int )( 255.0 * qrand() / ( RAND_MAX + 1.0 ) ),
   376                      1 + ( 
int )( 255.0 * qrand() / ( RAND_MAX + 1.0 ) ),
   377                      1 + ( 
int )( 255.0 * qrand() / ( RAND_MAX + 1.0 ) ) );
   380   qsrand( time( 
nullptr ) );
   384   QList< int > mySelectedBands = rendererSelectedBands();
   385   if ( mRendererName == QLatin1String( 
"singlebandgray" ) )
   387     int myGrayBand = mySelectedBands[0];
   388     for ( 
int i = 1; i <= myBandCountInt; i++ )
   390       if ( i == myGrayBand )
   392         mHistoColors << Qt::darkGray;
   393         cboHistoBand->setItemData( i - 1, QColor( Qt::darkGray ), Qt::ForegroundRole );
   397         if ( ! myColors.isEmpty() )
   399           mHistoColors << myColors.first();
   400           myColors.pop_front();
   404           mHistoColors << Qt::black;
   406         cboHistoBand->setItemData( i - 1, QColor( Qt::black ), Qt::ForegroundRole );
   411   else if ( mRendererName == QLatin1String( 
"multibandcolor" ) )
   413     int myRedBand = mySelectedBands[0];
   414     int myGreenBand = mySelectedBands[1];
   415     int myBlueBand = mySelectedBands[2];
   418     myColors.remove( 0, 3 );
   419     for ( 
int i = 1; i <= myBandCountInt; i++ )
   422       if ( i == myRedBand )
   424       else if ( i == myGreenBand )
   426       else if ( i == myBlueBand )
   430         if ( ! myColors.isEmpty() )
   432           myColor = myColors.first();
   433           myColors.pop_front();
   439         cboHistoBand->setItemData( i - 1, QColor( Qt::black ), Qt::ForegroundRole );
   441       if ( i == myRedBand ||  i == myGreenBand || i == myBlueBand )
   443         cboHistoBand->setItemData( i - 1, myColor, Qt::ForegroundRole );
   445       mHistoColors << myColor;
   450     mHistoColors << myColors;
   465   bool myFirstIteration = 
true;
   467   mySelectedBands = histoSelectedBands();
   468   double myBinXStep = 1;
   471   for ( 
int myIteratorInt = 1;
   472         myIteratorInt <= myBandCountInt;
   476     if ( mHistoShowBands != ShowAll )
   478       if ( ! mySelectedBands.contains( myIteratorInt ) )
   482     int sampleSize = 250000; 
   489     QgsDebugMsg( QStringLiteral( 
"got raster histo for band %1 : min=%2 max=%3 count=%4" ).arg( myIteratorInt ).arg( myHistogram.minimum ).arg( myHistogram.maximum ).arg( myHistogram.binCount ) );
   492     bool myDrawLines = 
true;
   493     if ( ! mHistoDrawLines &&
   501     QwtPlotCurve *mypCurve = 
nullptr;
   504       mypCurve = 
new QwtPlotCurve( tr( 
"Band %1" ).arg( myIteratorInt ) );
   506       mypCurve->setRenderHint( QwtPlotItem::RenderAntialiased );
   507       mypCurve->setPen( QPen( mHistoColors.at( myIteratorInt ) ) );
   510     QwtPlotHistogram *mypHisto = 
nullptr;
   513       mypHisto = 
new QwtPlotHistogram( tr( 
"Band %1" ).arg( myIteratorInt ) );
   514       mypHisto->setRenderHint( QwtPlotItem::RenderAntialiased );
   516       mypHisto->setPen( QPen( Qt::lightGray ) );
   518       mypHisto->setBrush( QBrush( mHistoColors.at( myIteratorInt ) ) );
   521     QVector<QPointF> data;
   522     QVector<QwtIntervalSample> dataHisto;
   527       myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
   528       myBinX = myHistogram.minimum + myBinXStep / 2.0;
   536     for ( 
int myBin = 0; myBin < myHistogram.binCount; myBin++ )
   538       int myBinValue = myHistogram.histogramVector.at( myBin );
   541         data << QPointF( myBinX, myBinValue );
   545         dataHisto << QwtIntervalSample( myBinValue, myBinX - myBinXStep / 2.0, myBinX + myBinXStep / 2.0 );
   547       myBinX += myBinXStep;
   552       mypCurve->setSamples( data );
   553       mypCurve->attach( mpPlot );
   557       mypHisto->setSamples( dataHisto );
   558       mypHisto->attach( mpPlot );
   561     if ( myFirstIteration || mHistoMin > myHistogram.minimum )
   563       mHistoMin = myHistogram.minimum;
   565     if ( myFirstIteration || mHistoMax < myHistogram.maximum )
   567       mHistoMax = myHistogram.maximum;
   569     QgsDebugMsg( QStringLiteral( 
"computed histo min = %1 max = %2" ).arg( mHistoMin ).arg( mHistoMax ) );
   570     myFirstIteration = 
false;
   573   if ( mHistoMin < mHistoMax )
   579     mpPlot->setAxisScale( QwtPlot::xBottom,
   580                           mHistoMin - myBinXStep / 2,
   581                           mHistoMax + myBinXStep / 2 );
   582     mpPlot->setEnabled( 
true );
   587     mHistoMarkerMin = 
new QwtPlotMarker();
   588     mHistoMarkerMin->attach( mpPlot );
   589     mHistoMarkerMax = 
new QwtPlotMarker();
   590     mHistoMarkerMax->attach( mpPlot );
   591     updateHistoMarkers();
   596       mHistoPicker = 
new QwtPlotPicker( mpPlot->canvas() );
   598       mHistoPicker->setTrackerMode( QwtPicker::AlwaysOff );
   599       mHistoPicker->setRubberBand( QwtPicker::VLineRubberBand );
   600       mHistoPicker->setStateMachine( 
new QwtPickerDragPointMachine );
   601       connect( mHistoPicker, static_cast < 
void ( QwtPlotPicker::* )( 
const QPointF & ) > ( &QwtPlotPicker::selected ), 
this, &QgsRasterHistogramWidget::histoPickerSelected );
   603     mHistoPicker->setEnabled( 
false );
   608       mHistoZoomer = 
new QwtPlotZoomer( mpPlot->canvas() );
   609       mHistoZoomer->setStateMachine( 
new QwtPickerDragRectMachine );
   610       mHistoZoomer->setTrackerMode( QwtPicker::AlwaysOff );
   612     mHistoZoomer->setEnabled( 
true );
   616     mpPlot->setDisabled( 
true );
   618       mHistoPicker->setEnabled( 
false );
   620       mHistoZoomer->setEnabled( 
false );
   623   stackedWidget2->setCurrentIndex( 0 );
   627   QApplication::restoreOverrideCursor();
   630 void QgsRasterHistogramWidget::mSaveAsImageButton_clicked()
   636   QFileInfo myInfo( myFileNameAndFilter.first );
   637   if ( !myInfo.baseName().isEmpty() )
   644     int width, 
int height, 
int quality )
   647   QFileInfo myInfo( filename );
   648   QDir myDir( myInfo.dir() );
   649   if ( ! myDir.exists() )
   651     QgsDebugMsg( QStringLiteral( 
"Error, directory %1 non-existent (theFilename = %2)" ).arg( myDir.absolutePath(), filename ) );
   656   QPixmap myPixmap( width, height );
   657   QRect myQRect( 5, 5, width - 10, height - 10 ); 
   658   myPixmap.fill( Qt::white ); 
   660   QwtPlotRenderer myRenderer;
   661   myRenderer.setDiscardFlags( QwtPlotRenderer::DiscardBackground |
   662                               QwtPlotRenderer::DiscardCanvasBackground );
   663   myRenderer.setLayoutFlags( QwtPlotRenderer::FrameWithScales );
   666   myPainter.begin( &myPixmap );
   667   myRenderer.render( mpPlot, &myPainter, myQRect );
   671   myPixmap.save( filename, 
nullptr, quality );
   679   cboHistoBand->setCurrentIndex( bandNo - 1 );
   682 void QgsRasterHistogramWidget::cboHistoBand_currentIndexChanged( 
int index )
   684   if ( mHistoShowBands == ShowSelected )
   688   index = cboHistoBand->currentIndex();
   691     mHistoPicker->setEnabled( 
false );
   692     mHistoPicker->setRubberBandPen( QPen( mHistoColors.at( index + 1 ) ) );
   695     mHistoZoomer->setEnabled( 
true );
   696   btnHistoMin->setEnabled( 
true );
   697   btnHistoMax->setEnabled( 
true );
   699   QPair< QString, QString > myMinMax = rendererMinMax( index + 1 );
   700   leHistoMin->setText( myMinMax.first );
   701   leHistoMax->setText( myMinMax.second );
   707 void QgsRasterHistogramWidget::histoActionTriggered( QAction *action )
   711   histoAction( action->data().toString(), action->isChecked() );
   716   if ( actionName.isEmpty() )
   720   QgsDebugMsg( QStringLiteral( 
"band = %1 action = %2" ).arg( cboHistoBand->currentIndex() + 1 ).arg( actionName ) );
   723   if ( actionName == QLatin1String( 
"Show markers" ) )
   725     mHistoShowMarkers = actionFlag;
   727     settings.
setValue( QStringLiteral( 
"Raster/histogram/showMarkers" ), mHistoShowMarkers );
   728     updateHistoMarkers();
   731   else if ( actionName == QLatin1String( 
"Zoom min_max" ) )
   733     mHistoZoomToMinMax = actionFlag;
   735     settings.
setValue( QStringLiteral( 
"Raster/histogram/zoomToMinMax" ), mHistoZoomToMinMax );
   738   else if ( actionName == QLatin1String( 
"Update min_max" ) )
   740     mHistoUpdateStyleToMinMax = actionFlag;
   742     settings.
setValue( QStringLiteral( 
"Raster/histogram/updateStyleToMinMax" ), mHistoUpdateStyleToMinMax );
   745   else if ( actionName == QLatin1String( 
"Show all" ) )
   747     mHistoShowBands = ShowAll;
   752   else if ( actionName == QLatin1String( 
"Show selected" ) )
   754     mHistoShowBands = ShowSelected;
   759   else if ( actionName == QLatin1String( 
"Show RGB" ) )
   761     mHistoShowBands = ShowRGB;
   766   else if ( actionName == QLatin1String( 
"Draw lines" ) )
   768     mHistoDrawLines = actionFlag;
   770     settings.
setValue( QStringLiteral( 
"Raster/histogram/drawLines" ), mHistoDrawLines );
   771     btnHistoCompute_clicked(); 
   775   else if ( actionName == 
"Load apply all" )
   777     mHistoLoadApplyAll = actionFlag;
   778     settings.setValue( 
"/Raster/histogram/loadApplyAll", mHistoLoadApplyAll );
   784   else if ( actionName.left( 5 ) == QLatin1String( 
"Load " ) && mRendererWidget )
   786     QVector<int> myBands;
   790     double minMaxValues[2];
   793     if ( mHistoLoadApplyAll )
   795       int myBandCountInt = mRasterLayer->
bandCount();
   796       for ( 
int i = 1; i <= myBandCountInt; i++ )
   798         if ( i != cboHistoBand->currentIndex() + 1 )
   805     myBands << cboHistoBand->currentIndex() + 1;
   809     double myStdDev = 1.0;
   810     if ( actionName == 
"Load stddev" )
   812       myStdDev = mRendererWidget->
stdDev().toDouble();
   817     leHistoMin->blockSignals( 
true );
   818     leHistoMax->blockSignals( 
true );
   821     const auto constMyBands = myBands;
   822     for ( 
int bandNo : constMyBands )
   826       if ( actionName == 
"Load actual" )
   828         ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::Actual,
   829                                           bandNo, minMaxValues );
   831       else if ( actionName == 
"Load estimate" )
   833         ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::Estimate,
   834                                           bandNo, minMaxValues );
   836       else if ( actionName == 
"Load extent" )
   838         ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::CurrentExtent,
   839                                           bandNo, minMaxValues );
   841       else if ( actionName == 
"Load 1 stddev" ||
   842                 actionName == 
"Load stddev" )
   844         ok = mRendererWidget->bandMinMaxFromStdDev( myStdDev, bandNo, minMaxValues );
   849       cboHistoBand->setCurrentIndex( bandNo - 1 );
   850       if ( !ok || actionName == QLatin1String( 
"Load reset" ) )
   864         leHistoMin->setText( QString::number( minMaxValues[0] ) );
   865         leHistoMax->setText( QString::number( minMaxValues[1] ) );
   872     leHistoMin->blockSignals( 
false );
   873     leHistoMax->blockSignals( 
false );
   874     updateHistoMarkers();
   876   else if ( actionName == QLatin1String( 
"Compute histogram" ) )
   878     btnHistoCompute_clicked();
   887 void QgsRasterHistogramWidget::applyHistoMin()
   889   if ( ! mRendererWidget )
   892   int bandNo = cboHistoBand->currentIndex() + 1;
   893   QList< int > mySelectedBands = rendererSelectedBands();
   895   for ( 
int i = 0; i <= mySelectedBands.size(); i++ )
   899       min = leHistoMin->text();
   900       if ( mHistoUpdateStyleToMinMax && mRendererWidget->
min( i ) != min )
   902         mRendererWidget->
setMin( min, i );
   911   updateHistoMarkers();
   913   if ( ! min.isEmpty() && mHistoZoomToMinMax && mHistoZoomer )
   915     QRectF rect = mHistoZoomer->zoomRect();
   916     rect.setLeft( min.toDouble() );
   917     mHistoZoomer->zoom( rect );
   922 void QgsRasterHistogramWidget::applyHistoMax()
   924   if ( ! mRendererWidget )
   927   int bandNo = cboHistoBand->currentIndex() + 1;
   928   QList< int > mySelectedBands = rendererSelectedBands();
   930   for ( 
int i = 0; i <= mySelectedBands.size(); i++ )
   934       max = leHistoMax->text();
   935       if ( mHistoUpdateStyleToMinMax && mRendererWidget->
max( i ) != max )
   937         mRendererWidget->
setMax( max, i );
   946   updateHistoMarkers();
   948   if ( ! max.isEmpty() && mHistoZoomToMinMax && mHistoZoomer )
   950     QRectF rect = mHistoZoomer->zoomRect();
   951     rect.setRight( max.toDouble() );
   952     mHistoZoomer->zoom( rect );
   957 void QgsRasterHistogramWidget::btnHistoMin_toggled()
   959   if ( mpPlot && mHistoPicker )
   961     if ( QApplication::overrideCursor() )
   962       QApplication::restoreOverrideCursor();
   963     if ( btnHistoMin->isChecked() )
   965       btnHistoMax->setChecked( 
false );
   966       QApplication::setOverrideCursor( Qt::PointingHandCursor );
   969       mHistoZoomer->setEnabled( ! btnHistoMin->isChecked() );
   970     mHistoPicker->setEnabled( btnHistoMin->isChecked() );
   972   updateHistoMarkers();
   975 void QgsRasterHistogramWidget::btnHistoMax_toggled()
   977   if ( mpPlot && mHistoPicker )
   979     if ( QApplication::overrideCursor() )
   980       QApplication::restoreOverrideCursor();
   981     if ( btnHistoMax->isChecked() )
   983       btnHistoMin->setChecked( 
false );
   984       QApplication::setOverrideCursor( Qt::PointingHandCursor );
   987       mHistoZoomer->setEnabled( ! btnHistoMax->isChecked() );
   988     mHistoPicker->setEnabled( btnHistoMax->isChecked() );
   990   updateHistoMarkers();
   997   if ( !scale ) 
return QString();
   999   QList< double > minorTicks = scale->ticks( QwtScaleDiv::MinorTick );
  1000   QList< double > majorTicks = scale->ticks( QwtScaleDiv::MajorTick );
  1001   double diff = ( minorTicks[1] - minorTicks[0] ) / div;
  1002   double min = majorTicks[0] - diff;
  1004     min -= ( majorTicks[1] - majorTicks[0] );
  1005   double max = scale->upperBound();
  1006   double closest = target;
  1007   double current = min;
  1009   while ( current < max )
  1012     if ( current > target )
  1014       closest = ( std::fabs( target - current + diff ) < std::fabs( target - current ) ) ? current - diff : current;
  1020   return QString::number( closest );
  1023 void QgsRasterHistogramWidget::histoPickerSelected( QPointF pos )
  1025   if ( btnHistoMin->isChecked() || btnHistoMax->isChecked() )
  1027     const QwtScaleDiv *scale = &mpPlot->axisScaleDiv( QwtPlot::xBottom );
  1029     if ( btnHistoMin->isChecked() )
  1033       btnHistoMin->setChecked( 
false );
  1039       btnHistoMax->setChecked( 
false );
  1042   if ( QApplication::overrideCursor() )
  1043     QApplication::restoreOverrideCursor();
  1046 void QgsRasterHistogramWidget::histoPickerSelectedQwt5( 
QwtDoublePoint pos )
  1048   histoPickerSelected( QPointF( pos.x(), pos.y() ) );
  1051 void QgsRasterHistogramWidget::updateHistoMarkers()
  1054   if ( leHistoMin->signalsBlocked() )
  1057   if ( !mpPlot || !mHistoMarkerMin || !mHistoMarkerMax )
  1060   int bandNo = cboHistoBand->currentIndex() + 1;
  1061   QList< int > mySelectedBands = histoSelectedBands();
  1063   if ( ( ! mHistoShowMarkers && ! btnHistoMin->isChecked() && ! btnHistoMax->isChecked() ) ||
  1064        ( ! mySelectedBands.isEmpty() && ! mySelectedBands.contains( bandNo ) ) )
  1066     mHistoMarkerMin->hide();
  1067     mHistoMarkerMax->hide();
  1072   double minVal = mHistoMin;
  1073   double maxVal = mHistoMax;
  1074   QString minStr = leHistoMin->text();
  1075   QString maxStr = leHistoMax->text();
  1076   if ( !minStr.isEmpty() )
  1077     minVal = minStr.toDouble();
  1078   if ( !maxStr.isEmpty() )
  1079     maxVal = maxStr.toDouble();
  1081   QPen linePen = QPen( mHistoColors.at( bandNo ) );
  1082   linePen.setStyle( Qt::DashLine );
  1083   mHistoMarkerMin->setLineStyle( QwtPlotMarker::VLine );
  1084   mHistoMarkerMin->setLinePen( linePen );
  1085   mHistoMarkerMin->setXValue( minVal );
  1086   mHistoMarkerMin->show();
  1087   mHistoMarkerMax->setLineStyle( QwtPlotMarker::VLine );
  1088   mHistoMarkerMax->setLinePen( linePen );
  1089   mHistoMarkerMax->setXValue( maxVal );
  1090   mHistoMarkerMax->show();
  1096 QList< int > QgsRasterHistogramWidget::histoSelectedBands()
  1098   QList< int > mySelectedBands;
  1100   if ( mHistoShowBands != ShowAll )
  1102     if ( mHistoShowBands == ShowSelected )
  1104       mySelectedBands << cboHistoBand->currentIndex() + 1;
  1106     else if ( mHistoShowBands == ShowRGB )
  1108       mySelectedBands = rendererSelectedBands();
  1112   return mySelectedBands;
  1115 QList< int > QgsRasterHistogramWidget::rendererSelectedBands()
  1117   QList< int > mySelectedBands;
  1119   if ( ! mRendererWidget )
  1121     mySelectedBands << -1 << -1 << -1; 
  1122     return mySelectedBands;
  1125   if ( mRendererName == QLatin1String( 
"singlebandgray" ) )
  1129   else if ( mRendererName == QLatin1String( 
"multibandcolor" ) )
  1131     for ( 
int i = 0; i <= 2; i++ )
  1137   return mySelectedBands;
  1140 QPair< QString, QString > QgsRasterHistogramWidget::rendererMinMax( 
int bandNo )
  1142   QPair< QString, QString > myMinMax;
  1144   if ( ! mRendererWidget )
  1147   if ( mRendererName == QLatin1String( 
"singlebandgray" ) )
  1151       myMinMax.first = mRendererWidget->
min();
  1152       myMinMax.second = mRendererWidget->
max();
  1155   else if ( mRendererName == QLatin1String( 
"multibandcolor" ) )
  1157     for ( 
int i = 0; i <= 2; i++ )
  1161         myMinMax.first = mRendererWidget->
min( i );
  1162         myMinMax.second = mRendererWidget->
max( i );
  1178   if ( myMinMax.first.isEmpty() )
  1179     myMinMax.first = QString::number( mHistoMin );
  1180   if ( myMinMax.second.isEmpty() )
  1181     myMinMax.second = QString::number( mHistoMax );
  1183   QgsDebugMsg( QStringLiteral( 
"bandNo %1 got min/max [%2] [%3]" ).arg( bandNo ).arg( myMinMax.first, myMinMax.second ) );
 
A rectangle specified with double values. 
 
Thirty two bit signed integer (qint32) 
 
virtual bool hasHistogram(int bandNo, int binCount, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false)
Returns true if histogram is available (cached, already calculated) 
 
int bandCount() const
Returns the number of bands in this layer. 
 
static double minimumValuePossible(Qgis::DataType dataType)
Helper function that returns the minimum possible value for a GDAL data type. 
 
This class is a composition of two QSettings instances: 
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key. 
 
Represents a raster layer. 
 
static double maximumValuePossible(Qgis::DataType dataType)
Helper function that returns the maximum possible value for a GDAL data type. 
 
Thirty two bit unsigned integer (quint32) 
 
DataType
Raster data types. 
 
Qgis::DataType sourceDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
 
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon. 
 
virtual QgsRasterHistogram histogram(int bandNo, int binCount=0, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false, QgsRasterBlockFeedback *feedback=nullptr)
Returns a band histogram. 
 
Sixteen bit signed integer (qint16) 
 
static QPixmap getThemePixmap(const QString &name)
Helper to get a theme icon as a pixmap. 
 
QPair< QString, QString > GUI_EXPORT getSaveAsImageName(QWidget *parent, const QString &message, const QString &defaultFilename)
A helper function to get an image name from the user. 
 
QgsRasterDataProvider * dataProvider() override
Returns the source data provider. 
 
void progressChanged(double progress)
Emitted when the feedback object reports a progress change. 
 
QString bandName(int bandNoInt) const
Returns the name of a band given its number. 
 
Sixteen bit unsigned integer (quint16) 
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value. 
 
The QgsRasterHistogram is a container for histogram of a single raster band. 
 
Feedback object tailored for raster block reading. 
 
Eight bit unsigned integer (quint8) 
 
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.