Skip to content

Commit 2a2f4ce

Browse files
committed
let the raster provider/interface calculate histogram bin count, and make sure there are no more bins than actual range (max-min) for Int16/32 bands
1 parent 884283a commit 2a2f4ce

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

src/core/raster/qgsrasterinterface.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,16 @@ void QgsRasterInterface::initHistogram( QgsRasterHistogram &theHistogram,
349349
// There is no best default value, to display something reasonable in histogram chart, binCount should be small, OTOH, to get precise data for cumulative cut, the number should be big. Because it is easier to define fixed lower value for the chart, we calc optimum binCount for higher resolution (to avoid calculating that where histogram() is used. In any any case, it does not make sense to use more than width*height;
350350
myBinCount = theHistogram.width * theHistogram.height;
351351
if ( myBinCount > 1000 ) myBinCount = 1000;
352+
353+
// for Int16/Int32 make sure bin count <= actual range, because there is no sense in having
354+
// bins at fractional values
355+
if ( !mInput && (
356+
mySrcDataType == QGis::Int16 || mySrcDataType == QGis::Int32 ||
357+
mySrcDataType == QGis::UInt16 || mySrcDataType == QGis::UInt32 ) )
358+
{
359+
if ( myBinCount > theHistogram.maximum - theHistogram.minimum + 1 )
360+
myBinCount = int( ceil( theHistogram.maximum - theHistogram.minimum + 1 ) );
361+
}
352362
}
353363
}
354364
theHistogram.binCount = myBinCount;

src/gui/raster/qgsrasterhistogramwidget.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
#include <qwt_plot_histogram.h>
4545
#endif
4646

47-
#define RASTER_HISTOGRAM_BINS 256
47+
// this has been removed, now we let the provider/raster interface decide
48+
// how many bins are suitable depending on data type and range
49+
//#define RASTER_HISTOGRAM_BINS 256
4850

4951
QgsRasterHistogramWidget::QgsRasterHistogramWidget( QgsRasterLayer* lyr, QWidget *parent )
5052
: QWidget( parent ),
@@ -263,7 +265,8 @@ void QgsRasterHistogramWidget::on_btnHistoCompute_clicked()
263265

264266
bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
265267
{
266-
const int BINCOUNT = RASTER_HISTOGRAM_BINS;
268+
QgsDebugMsg( "entered." );
269+
267270
//bool myIgnoreOutOfRangeFlag = true;
268271
//bool myThoroughBandScanFlag = false;
269272
int myBandCountInt = mRasterLayer->bandCount();
@@ -275,9 +278,8 @@ bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
275278
myIteratorInt <= myBandCountInt;
276279
++myIteratorInt )
277280
{
278-
//if ( ! mRasterLayer->hasCachedHistogram( myIteratorInt, BINCOUNT ) )
279281
int sampleSize = 250000; // number of sample cells
280-
if ( !mRasterLayer->dataProvider()->hasHistogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize ) )
282+
if ( !mRasterLayer->dataProvider()->hasHistogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize ) )
281283
{
282284
QgsDebugMsg( QString( "band %1 does not have cached histo" ).arg( myIteratorInt ) );
283285
return false;
@@ -294,9 +296,8 @@ bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
294296
myIteratorInt <= myBandCountInt;
295297
++myIteratorInt )
296298
{
297-
//mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
298299
int sampleSize = 250000; // number of sample cells
299-
mRasterLayer->dataProvider()->histogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
300+
mRasterLayer->dataProvider()->histogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
300301
}
301302

302303
disconnect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mHistogramProgress, SLOT( setValue( int ) ) );
@@ -319,7 +320,6 @@ void QgsRasterHistogramWidget::refreshHistogram()
319320
// bin in all selected layers, and the min. It then draws a scaled line between min
320321
// and max - scaled to image height. 1 line drawn per selected band
321322
//
322-
const int BINCOUNT = RASTER_HISTOGRAM_BINS;
323323
int myBandCountInt = mRasterLayer->bandCount();
324324

325325
QgsDebugMsg( "entered." );
@@ -465,9 +465,9 @@ void QgsRasterHistogramWidget::refreshHistogram()
465465
}
466466

467467
int sampleSize = 250000; // number of sample cells
468-
//QgsRasterBandStats myRasterBandStats = mRasterLayer->dataProvider()->bandStatistics( myIteratorInt );
469-
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
470-
QgsRasterHistogram myHistogram = mRasterLayer->dataProvider()->histogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
468+
QgsRasterHistogram myHistogram = mRasterLayer->dataProvider()->histogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
469+
470+
QgsDebugMsg( QString( "got raster histo for band %1 : min=%2 max=%3 count=%4" ).arg( myIteratorInt ).arg( myHistogram.minimum ).arg( myHistogram.maximum ).arg( myHistogram.binCount ) );
471471

472472
bool myDrawLines = true;
473473

@@ -495,9 +495,7 @@ void QgsRasterHistogramWidget::refreshHistogram()
495495
// calculate first bin x value and bin step size if not Byte data
496496
if ( mRasterLayer->dataProvider()->srcDataType( myIteratorInt ) != QGis::Byte )
497497
{
498-
//myBinXStep = myRasterBandStats.range / BINCOUNT;
499-
//myBinX = myRasterBandStats.minimumValue + myBinXStep / 2.0;
500-
myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / BINCOUNT;
498+
myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
501499
myBinX = myHistogram.minimum + myBinXStep / 2.0;
502500
}
503501
else
@@ -511,11 +509,9 @@ void QgsRasterHistogramWidget::refreshHistogram()
511509
#endif
512510
}
513511

514-
for ( int myBin = 0; myBin < BINCOUNT; myBin++ )
512+
for ( int myBin = 0; myBin < myHistogram.binCount; myBin++ )
515513
{
516-
// TODO - why is histogram in int and not double?
517514
int myBinValue = myHistogram.histogramVector.at( myBin );
518-
//printf("%d/%d %d\n",myBin,BINCOUNT,myBinValue);
519515
#if defined(QWT_VERSION) && QWT_VERSION>=0x060000
520516
if ( myDrawLines )
521517
{

0 commit comments

Comments
 (0)