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)
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:
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
Thirty two bit unsigned integer (quint32)
DataType
Raster data types.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
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.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
int bandCount() const
Returns the number of bands in this layer.
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.
QString bandName(int bandNoInt) const
Returns the name of a band given its number.
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.