Skip to content
Permalink
Browse files

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
  • Loading branch information
etiennesky committed Feb 3, 2014
1 parent 884283a commit 2a2f4ceedf208ef6e6ef170531a2bdb3cc2915c6
Showing with 22 additions and 16 deletions.
  1. +10 −0 src/core/raster/qgsrasterinterface.cpp
  2. +12 −16 src/gui/raster/qgsrasterhistogramwidget.cpp
@@ -349,6 +349,16 @@ void QgsRasterInterface::initHistogram( QgsRasterHistogram &theHistogram,
// 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;
myBinCount = theHistogram.width * theHistogram.height;
if ( myBinCount > 1000 ) myBinCount = 1000;

// for Int16/Int32 make sure bin count <= actual range, because there is no sense in having
// bins at fractional values
if ( !mInput && (
mySrcDataType == QGis::Int16 || mySrcDataType == QGis::Int32 ||
mySrcDataType == QGis::UInt16 || mySrcDataType == QGis::UInt32 ) )
{
if ( myBinCount > theHistogram.maximum - theHistogram.minimum + 1 )
myBinCount = int( ceil( theHistogram.maximum - theHistogram.minimum + 1 ) );
}
}
}
theHistogram.binCount = myBinCount;
@@ -44,7 +44,9 @@
#include <qwt_plot_histogram.h>
#endif

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

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

bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
{
const int BINCOUNT = RASTER_HISTOGRAM_BINS;
QgsDebugMsg( "entered." );

//bool myIgnoreOutOfRangeFlag = true;
//bool myThoroughBandScanFlag = false;
int myBandCountInt = mRasterLayer->bandCount();
@@ -275,9 +278,8 @@ bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
myIteratorInt <= myBandCountInt;
++myIteratorInt )
{
//if ( ! mRasterLayer->hasCachedHistogram( myIteratorInt, BINCOUNT ) )
int sampleSize = 250000; // number of sample cells
if ( !mRasterLayer->dataProvider()->hasHistogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize ) )
if ( !mRasterLayer->dataProvider()->hasHistogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize ) )
{
QgsDebugMsg( QString( "band %1 does not have cached histo" ).arg( myIteratorInt ) );
return false;
@@ -294,9 +296,8 @@ bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
myIteratorInt <= myBandCountInt;
++myIteratorInt )
{
//mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
int sampleSize = 250000; // number of sample cells
mRasterLayer->dataProvider()->histogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
mRasterLayer->dataProvider()->histogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
}

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

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

int sampleSize = 250000; // number of sample cells
//QgsRasterBandStats myRasterBandStats = mRasterLayer->dataProvider()->bandStatistics( myIteratorInt );
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
QgsRasterHistogram myHistogram = mRasterLayer->dataProvider()->histogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
QgsRasterHistogram myHistogram = mRasterLayer->dataProvider()->histogram( myIteratorInt, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );

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 ) );

bool myDrawLines = true;

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

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

0 comments on commit 2a2f4ce

Please sign in to comment.
You can’t perform that action at this time.