Skip to content

Commit

Permalink
let the raster provider/interface calculate histogram bin count, and …
Browse files Browse the repository at this point in the history
…make sure there are no more bins than actual range (max-min) for Int16/32 bands
  • Loading branch information
etiennesky committed Feb 22, 2014
1 parent 884283a commit 2a2f4ce
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
10 changes: 10 additions & 0 deletions src/core/raster/qgsrasterinterface.cpp
Expand Up @@ -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;
Expand Down
28 changes: 12 additions & 16 deletions src/gui/raster/qgsrasterhistogramwidget.cpp
Expand Up @@ -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 ),
Expand Down Expand Up @@ -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();
Expand All @@ -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;
Expand All @@ -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 ) ) );
Expand All @@ -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." );
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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 )
{
Expand Down

0 comments on commit 2a2f4ce

Please sign in to comment.