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 Q_FOREACH (
int bandNo, myBands )
825 if ( actionName ==
"Load actual" )
827 ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::Actual,
828 bandNo, minMaxValues );
830 else if ( actionName ==
"Load estimate" )
832 ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::Estimate,
833 bandNo, minMaxValues );
835 else if ( actionName ==
"Load extent" )
837 ok = mRendererWidget->bandMinMax( QgsRasterRendererWidget::CurrentExtent,
838 bandNo, minMaxValues );
840 else if ( actionName ==
"Load 1 stddev" ||
841 actionName ==
"Load stddev" )
843 ok = mRendererWidget->bandMinMaxFromStdDev( myStdDev, bandNo, minMaxValues );
848 cboHistoBand->setCurrentIndex( bandNo - 1 );
849 if ( !ok || actionName == QLatin1String(
"Load reset" ) )
863 leHistoMin->setText( QString::number( minMaxValues[0] ) );
864 leHistoMax->setText( QString::number( minMaxValues[1] ) );
871 leHistoMin->blockSignals(
false );
872 leHistoMax->blockSignals(
false );
873 updateHistoMarkers();
875 else if ( actionName == QLatin1String(
"Compute histogram" ) )
877 btnHistoCompute_clicked();
886 void QgsRasterHistogramWidget::applyHistoMin()
888 if ( ! mRendererWidget )
891 int bandNo = cboHistoBand->currentIndex() + 1;
892 QList< int > mySelectedBands = rendererSelectedBands();
894 for (
int i = 0; i <= mySelectedBands.size(); i++ )
898 min = leHistoMin->text();
899 if ( mHistoUpdateStyleToMinMax && mRendererWidget->
min( i ) != min )
901 mRendererWidget->
setMin( min, i );
910 updateHistoMarkers();
912 if ( ! min.isEmpty() && mHistoZoomToMinMax && mHistoZoomer )
914 QRectF rect = mHistoZoomer->zoomRect();
915 rect.setLeft( min.toDouble() );
916 mHistoZoomer->zoom( rect );
921 void QgsRasterHistogramWidget::applyHistoMax()
923 if ( ! mRendererWidget )
926 int bandNo = cboHistoBand->currentIndex() + 1;
927 QList< int > mySelectedBands = rendererSelectedBands();
929 for (
int i = 0; i <= mySelectedBands.size(); i++ )
933 max = leHistoMax->text();
934 if ( mHistoUpdateStyleToMinMax && mRendererWidget->
max( i ) != max )
936 mRendererWidget->
setMax( max, i );
945 updateHistoMarkers();
947 if ( ! max.isEmpty() && mHistoZoomToMinMax && mHistoZoomer )
949 QRectF rect = mHistoZoomer->zoomRect();
950 rect.setRight( max.toDouble() );
951 mHistoZoomer->zoom( rect );
956 void QgsRasterHistogramWidget::btnHistoMin_toggled()
958 if ( mpPlot && mHistoPicker )
960 if ( QApplication::overrideCursor() )
961 QApplication::restoreOverrideCursor();
962 if ( btnHistoMin->isChecked() )
964 btnHistoMax->setChecked(
false );
965 QApplication::setOverrideCursor( Qt::PointingHandCursor );
968 mHistoZoomer->setEnabled( ! btnHistoMin->isChecked() );
969 mHistoPicker->setEnabled( btnHistoMin->isChecked() );
971 updateHistoMarkers();
974 void QgsRasterHistogramWidget::btnHistoMax_toggled()
976 if ( mpPlot && mHistoPicker )
978 if ( QApplication::overrideCursor() )
979 QApplication::restoreOverrideCursor();
980 if ( btnHistoMax->isChecked() )
982 btnHistoMin->setChecked(
false );
983 QApplication::setOverrideCursor( Qt::PointingHandCursor );
986 mHistoZoomer->setEnabled( ! btnHistoMax->isChecked() );
987 mHistoPicker->setEnabled( btnHistoMax->isChecked() );
989 updateHistoMarkers();
996 if ( !scale )
return QString();
998 QList< double > minorTicks = scale->ticks( QwtScaleDiv::MinorTick );
999 QList< double > majorTicks = scale->ticks( QwtScaleDiv::MajorTick );
1000 double diff = ( minorTicks[1] - minorTicks[0] ) / div;
1001 double min = majorTicks[0] - diff;
1003 min -= ( majorTicks[1] - majorTicks[0] );
1004 double max = scale->upperBound();
1005 double closest = target;
1006 double current = min;
1008 while ( current < max )
1011 if ( current > target )
1013 closest = ( std::fabs( target - current + diff ) < std::fabs( target - current ) ) ? current - diff : current;
1019 return QString::number( closest );
1022 void QgsRasterHistogramWidget::histoPickerSelected( QPointF pos )
1024 if ( btnHistoMin->isChecked() || btnHistoMax->isChecked() )
1026 const QwtScaleDiv *scale = &mpPlot->axisScaleDiv( QwtPlot::xBottom );
1028 if ( btnHistoMin->isChecked() )
1032 btnHistoMin->setChecked(
false );
1038 btnHistoMax->setChecked(
false );
1041 if ( QApplication::overrideCursor() )
1042 QApplication::restoreOverrideCursor();
1045 void QgsRasterHistogramWidget::histoPickerSelectedQwt5(
QwtDoublePoint pos )
1047 histoPickerSelected( QPointF( pos.x(), pos.y() ) );
1050 void QgsRasterHistogramWidget::updateHistoMarkers()
1053 if ( leHistoMin->signalsBlocked() )
1056 if ( !mpPlot || !mHistoMarkerMin || !mHistoMarkerMax )
1059 int bandNo = cboHistoBand->currentIndex() + 1;
1060 QList< int > mySelectedBands = histoSelectedBands();
1062 if ( ( ! mHistoShowMarkers && ! btnHistoMin->isChecked() && ! btnHistoMax->isChecked() ) ||
1063 ( ! mySelectedBands.isEmpty() && ! mySelectedBands.contains( bandNo ) ) )
1065 mHistoMarkerMin->hide();
1066 mHistoMarkerMax->hide();
1071 double minVal = mHistoMin;
1072 double maxVal = mHistoMax;
1073 QString minStr = leHistoMin->text();
1074 QString maxStr = leHistoMax->text();
1075 if ( !minStr.isEmpty() )
1076 minVal = minStr.toDouble();
1077 if ( !maxStr.isEmpty() )
1078 maxVal = maxStr.toDouble();
1080 QPen linePen = QPen( mHistoColors.at( bandNo ) );
1081 linePen.setStyle( Qt::DashLine );
1082 mHistoMarkerMin->setLineStyle( QwtPlotMarker::VLine );
1083 mHistoMarkerMin->setLinePen( linePen );
1084 mHistoMarkerMin->setXValue( minVal );
1085 mHistoMarkerMin->show();
1086 mHistoMarkerMax->setLineStyle( QwtPlotMarker::VLine );
1087 mHistoMarkerMax->setLinePen( linePen );
1088 mHistoMarkerMax->setXValue( maxVal );
1089 mHistoMarkerMax->show();
1095 QList< int > QgsRasterHistogramWidget::histoSelectedBands()
1097 QList< int > mySelectedBands;
1099 if ( mHistoShowBands != ShowAll )
1101 if ( mHistoShowBands == ShowSelected )
1103 mySelectedBands << cboHistoBand->currentIndex() + 1;
1105 else if ( mHistoShowBands == ShowRGB )
1107 mySelectedBands = rendererSelectedBands();
1111 return mySelectedBands;
1114 QList< int > QgsRasterHistogramWidget::rendererSelectedBands()
1116 QList< int > mySelectedBands;
1118 if ( ! mRendererWidget )
1120 mySelectedBands << -1 << -1 << -1;
1121 return mySelectedBands;
1124 if ( mRendererName == QLatin1String(
"singlebandgray" ) )
1128 else if ( mRendererName == QLatin1String(
"multibandcolor" ) )
1130 for (
int i = 0; i <= 2; i++ )
1136 return mySelectedBands;
1139 QPair< QString, QString > QgsRasterHistogramWidget::rendererMinMax(
int bandNo )
1141 QPair< QString, QString > myMinMax;
1143 if ( ! mRendererWidget )
1146 if ( mRendererName == QLatin1String(
"singlebandgray" ) )
1150 myMinMax.first = mRendererWidget->
min();
1151 myMinMax.second = mRendererWidget->
max();
1154 else if ( mRendererName == QLatin1String(
"multibandcolor" ) )
1156 for (
int i = 0; i <= 2; i++ )
1160 myMinMax.first = mRendererWidget->
min( i );
1161 myMinMax.second = mRendererWidget->
max( i );
1177 if ( myMinMax.first.isEmpty() )
1178 myMinMax.first = QString::number( mHistoMin );
1179 if ( myMinMax.second.isEmpty() )
1180 myMinMax.second = QString::number( mHistoMax );
1182 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 null.
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.