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)
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.
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
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 layer's data provider, it may be nullptr.
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.
static double maximumValuePossible(Qgis::DataType)
Helper function that returns the maximum possible value for a GDAL data type.
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.