Skip to content

Commit 540df9c

Browse files
committedJul 28, 2012
continues removing of stats from raster layer
1 parent 42dc71f commit 540df9c

12 files changed

+211
-132
lines changed
 

‎python/core/qgsrasterbandstats.sip

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ class QgsRasterBandStats
1313
QString bandName;
1414
/** \brief The gdal band number (starts at 1)*/
1515
int bandNumber;
16-
/** \brief A flag to indicate whether this RasterBandStats struct
17-
* is completely populated */
18-
bool statsGathered;
16+
/** \brief Collected statistics */
17+
int statsGathered;
1918
/** \brief The minimum cell value in the raster band. NO_DATA values
2019
* are ignored. This does not use the gdal GetMinimum function. */
2120
double minimumValue;

‎src/core/qgsrasterdataprovider.cpp

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -423,18 +423,20 @@ QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo )
423423
}
424424
#endif
425425

426-
QgsRasterBandStats QgsRasterDataProvider::statisticsDefaults( int theBandNo,
426+
void QgsRasterDataProvider::initStatistics( QgsRasterBandStats &theStatistics,
427+
int theBandNo,
428+
int theStats,
427429
const QgsRectangle & theExtent,
428430
int theSampleSize )
429431
{
430432
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
431433

432-
QgsRasterBandStats myRasterBandStats;
433-
myRasterBandStats.bandName = generateBandName( theBandNo );
434-
myRasterBandStats.bandNumber = theBandNo;
434+
theStatistics.bandName = generateBandName( theBandNo );
435+
theStatistics.bandNumber = theBandNo;
436+
theStatistics.statsGathered = theStats;
435437

436438
QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
437-
myRasterBandStats.extent = myExtent;
439+
theStatistics.extent = myExtent;
438440

439441
if ( theSampleSize > 0 )
440442
{
@@ -452,39 +454,39 @@ QgsRasterBandStats QgsRasterDataProvider::statisticsDefaults( int theBandNo,
452454
}
453455
QgsDebugMsg( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ) );
454456

455-
myRasterBandStats.width = static_cast <int>( myExtent.width() / xRes );
456-
myRasterBandStats.height = static_cast <int>( myExtent.height() / yRes );
457+
theStatistics.width = static_cast <int>( myExtent.width() / xRes );
458+
theStatistics.height = static_cast <int>( myExtent.height() / yRes );
457459
}
458460
else
459461
{
460462
if ( capabilities() & Size )
461463
{
462-
myRasterBandStats.width = xSize();
463-
myRasterBandStats.height = ySize();
464+
theStatistics.width = xSize();
465+
theStatistics.height = ySize();
464466
}
465467
else
466468
{
467-
myRasterBandStats.width = 1000;
468-
myRasterBandStats.height = 1000;
469+
theStatistics.width = 1000;
470+
theStatistics.height = 1000;
469471
}
470472
}
471-
QgsDebugMsg( QString( "myRasterBandStats.width = %1 myRasterBandStats.height = %2" ).arg( myRasterBandStats.width ).arg( myRasterBandStats.height ) );
472-
473-
return myRasterBandStats;
473+
QgsDebugMsg( QString( "theStatistics.width = %1 theStatistics.height = %2" ).arg( theStatistics.width ).arg( theStatistics.height ) );
474474
}
475475

476476
bool QgsRasterDataProvider::hasStatistics( int theBandNo,
477+
int theStats,
477478
const QgsRectangle & theExtent,
478479
int theSampleSize )
479480
{
480-
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
481+
QgsDebugMsg( QString( "theBandNo = %1 theStats = %2 theSampleSize = %3" ).arg( theBandNo ).arg( theStats ).arg( theSampleSize ) );
481482
if ( mStatistics.size() == 0 ) return false;
482483

483-
QgsRasterBandStats myRasterBandStats = statisticsDefaults( theBandNo, theExtent, theSampleSize );
484+
QgsRasterBandStats myRasterBandStats;
485+
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
484486

485487
foreach( QgsRasterBandStats stats, mStatistics )
486488
{
487-
if ( stats == myRasterBandStats )
489+
if ( stats.contains( myRasterBandStats ) )
488490
{
489491
QgsDebugMsg( "Has cached statistics." );
490492
return true;
@@ -495,15 +497,20 @@ bool QgsRasterDataProvider::hasStatistics( int theBandNo,
495497

496498
// Find cached
497499
QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo,
500+
int theStats,
498501
const QgsRectangle & theExtent,
499502
int theSampleSize )
500503
{
501-
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
502-
QgsRasterBandStats myRasterBandStats = statisticsDefaults( theBandNo, theExtent, theSampleSize );
504+
QgsDebugMsg( QString( "theBandNo = %1 theStats = %2 theSampleSize = %3" ).arg( theBandNo ).arg( theStats ).arg( theSampleSize ) );
505+
506+
// TODO: null values set on raster layer!!!
507+
508+
QgsRasterBandStats myRasterBandStats;
509+
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
503510

504511
foreach( QgsRasterBandStats stats, mStatistics )
505512
{
506-
if ( stats == myRasterBandStats )
513+
if ( stats.contains( myRasterBandStats ) )
507514
{
508515
QgsDebugMsg( "Using cached statistics." );
509516
return stats;
@@ -618,57 +625,57 @@ QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo,
618625

619626
CPLFree( myData );
620627

621-
myRasterBandStats.statsGathered = true;
628+
myRasterBandStats.statsGathered = QgsRasterBandStats::All;
622629
mStatistics.append( myRasterBandStats );
623630

624631
return myRasterBandStats;
625632
}
626633

627-
QgsRasterHistogram QgsRasterDataProvider::histogramDefaults( int theBandNo,
634+
void QgsRasterDataProvider::initHistogram( QgsRasterHistogram &theHistogram,
635+
int theBandNo,
628636
int theBinCount,
629637
double theMinimum, double theMaximum,
630638
const QgsRectangle & theExtent,
631639
int theSampleSize,
632640
bool theIncludeOutOfRange )
633641
{
634-
QgsRasterHistogram myHistogram;
635-
myHistogram.bandNumber = theBandNo;
636-
myHistogram.minimum = theMinimum;
637-
myHistogram.maximum = theMaximum;
638-
myHistogram.includeOutOfRange = theIncludeOutOfRange;
642+
theHistogram.bandNumber = theBandNo;
643+
theHistogram.minimum = theMinimum;
644+
theHistogram.maximum = theMaximum;
645+
theHistogram.includeOutOfRange = theIncludeOutOfRange;
639646

640647
int mySrcDataType = srcDataType( theBandNo );
641648

642-
if ( qIsNaN( myHistogram.minimum ) )
649+
if ( qIsNaN( theHistogram.minimum ) )
643650
{
644651
if ( mySrcDataType == QgsRasterDataProvider::Byte )
645652
{
646-
myHistogram.minimum = 0; // see histogram() for shift for rounding
653+
theHistogram.minimum = 0; // see histogram() for shift for rounding
647654
}
648655
else
649656
{
650657
// We need statistcs -> avoid histogramDefaults in hasHistogram if possible
651658
// TODO: use approximated statistics if aproximated histogram is requested
652659
// (theSampleSize > 0)
653-
QgsRasterBandStats stats = bandStatistics( theBandNo, theExtent, theSampleSize );
654-
myHistogram.minimum = stats.minimumValue;
660+
QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
661+
theHistogram.minimum = stats.minimumValue;
655662
}
656663
}
657-
if ( qIsNaN( myHistogram.maximum ) )
664+
if ( qIsNaN( theHistogram.maximum ) )
658665
{
659666
if ( mySrcDataType == QgsRasterDataProvider::Byte )
660667
{
661-
myHistogram.maximum = 255;
668+
theHistogram.maximum = 255;
662669
}
663670
else
664671
{
665-
QgsRasterBandStats stats = bandStatistics( theBandNo, theExtent, theSampleSize );
666-
myHistogram.maximum = stats.maximumValue;
672+
QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Max, theExtent, theSampleSize );
673+
theHistogram.maximum = stats.maximumValue;
667674
}
668675
}
669676

670677
QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
671-
myHistogram.extent = myExtent;
678+
theHistogram.extent = myExtent;
672679

673680
if ( theSampleSize > 0 )
674681
{
@@ -686,23 +693,23 @@ QgsRasterHistogram QgsRasterDataProvider::histogramDefaults( int theBandNo,
686693
}
687694
QgsDebugMsg( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ) );
688695

689-
myHistogram.width = static_cast <int>( myExtent.width() / xRes );
690-
myHistogram.height = static_cast <int>( myExtent.height() / yRes );
696+
theHistogram.width = static_cast <int>( myExtent.width() / xRes );
697+
theHistogram.height = static_cast <int>( myExtent.height() / yRes );
691698
}
692699
else
693700
{
694701
if ( capabilities() & Size )
695702
{
696-
myHistogram.width = xSize();
697-
myHistogram.height = ySize();
703+
theHistogram.width = xSize();
704+
theHistogram.height = ySize();
698705
}
699706
else
700707
{
701-
myHistogram.width = 1000;
702-
myHistogram.height = 1000;
708+
theHistogram.width = 1000;
709+
theHistogram.height = 1000;
703710
}
704711
}
705-
QgsDebugMsg( QString( "myHistogram.width = %1 myHistogram.height = %2" ).arg( myHistogram.width ).arg( myHistogram.height ) );
712+
QgsDebugMsg( QString( "theHistogram.width = %1 theHistogram.height = %2" ).arg( theHistogram.width ).arg( theHistogram.height ) );
706713

707714
int myBinCount = theBinCount;
708715
if ( myBinCount == 0 )
@@ -714,14 +721,12 @@ QgsRasterHistogram QgsRasterDataProvider::histogramDefaults( int theBandNo,
714721
else
715722
{
716723
// 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;
717-
myBinCount = myHistogram.width * myHistogram.height;
724+
myBinCount = theHistogram.width * theHistogram.height;
718725
if ( myBinCount > 1000 ) myBinCount = 1000;
719726
}
720727
}
721-
myHistogram.binCount = myBinCount;
722-
QgsDebugMsg( QString( "myHistogram.binCount = %1" ).arg( myHistogram.binCount ) );
723-
724-
return myHistogram;
728+
theHistogram.binCount = myBinCount;
729+
QgsDebugMsg( QString( "theHistogram.binCount = %1" ).arg( theHistogram.binCount ) );
725730
}
726731

727732
bool QgsRasterDataProvider::hasHistogram( int theBandNo,
@@ -736,7 +741,8 @@ bool QgsRasterDataProvider::hasHistogram( int theBandNo,
736741
// do other checks which dont need statistics before histogramDefaults()
737742
if ( mHistograms.size() == 0 ) return false;
738743

739-
QgsRasterHistogram myHistogram = histogramDefaults( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
744+
QgsRasterHistogram myHistogram;
745+
initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
740746

741747
foreach( QgsRasterHistogram histogram, mHistograms )
742748
{
@@ -758,7 +764,8 @@ QgsRasterHistogram QgsRasterDataProvider::histogram( int theBandNo,
758764
{
759765
QgsDebugMsg( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ) );
760766

761-
QgsRasterHistogram myHistogram = histogramDefaults( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
767+
QgsRasterHistogram myHistogram;
768+
initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
762769

763770
// Find cached
764771
foreach( QgsRasterHistogram histogram, mHistograms )

‎src/core/qgsrasterdataprovider.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -359,16 +359,19 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
359359

360360
/** \brief Get band statistics.
361361
* @param theBandNo The band (number).
362+
* @param theStats Requested statistics
362363
* @param theExtent Extent used to calc histogram, if empty, whole raster extent is used.
363364
* @param theSampleSize Approximate number of cells in sample. If 0, all cells (whole raster will be used). If raster does not have exact size (WCS without exact size for example), provider decides size of sample.
364365
* @return Band statistics.
365366
*/
366367
virtual QgsRasterBandStats bandStatistics( int theBandNo,
368+
int theStats = QgsRasterBandStats::All,
367369
const QgsRectangle & theExtent = QgsRectangle(),
368370
int theSampleSize = 0 );
369371

370372
/** \brief Returns true if histogram is available (cached, already calculated), the parameters are the same as in histogram() */
371373
virtual bool hasStatistics( int theBandNo,
374+
int theStats = QgsRasterBandStats::All,
372375
const QgsRectangle & theExtent = QgsRectangle(),
373376
int theSampleSize = 0 );
374377

@@ -551,18 +554,19 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
551554
QList <QgsRasterHistogram> mHistograms;
552555

553556
/** Fill in histogram defaults if not specified */
554-
virtual QgsRasterHistogram histogramDefaults( int theBandNo,
555-
int theBinCount = 0,
556-
double theMinimum = std::numeric_limits<double>::quiet_NaN(),
557-
double theMaximum = std::numeric_limits<double>::quiet_NaN(),
558-
const QgsRectangle & theExtent = QgsRectangle(),
559-
int theSampleSize = 0,
560-
bool theIncludeOutOfRange = false );
557+
void initHistogram( QgsRasterHistogram &theHistogram, int theBandNo,
558+
int theBinCount = 0,
559+
double theMinimum = std::numeric_limits<double>::quiet_NaN(),
560+
double theMaximum = std::numeric_limits<double>::quiet_NaN(),
561+
const QgsRectangle & theExtent = QgsRectangle(),
562+
int theSampleSize = 0,
563+
bool theIncludeOutOfRange = false );
561564

562565
/** Fill in statistics defaults if not specified */
563-
virtual QgsRasterBandStats statisticsDefaults( int theBandNo,
564-
const QgsRectangle & theExtent = QgsRectangle(),
565-
int theBinCount = 0 );
566+
void initStatistics( QgsRasterBandStats &theStatistics, int theBandNo,
567+
int theStats = QgsRasterBandStats::All,
568+
const QgsRectangle & theExtent = QgsRectangle(),
569+
int theBinCount = 0 );
566570

567571
};
568572
#endif

‎src/core/raster/qgsrasterbandstats.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,23 @@
3333
class CORE_EXPORT QgsRasterBandStats
3434
{
3535
public:
36+
enum Stats
37+
{
38+
None = 0,
39+
Min = 1,
40+
Max = 1 << 1,
41+
Range = 1 << 2,
42+
Sum = 1 << 3,
43+
Mean = 1 << 4,
44+
StdDev = 1 << 5,
45+
SumOfSquares = 1 << 6,
46+
All = Min | Max | Range | Sum | Mean | StdDev | SumOfSquares
47+
};
48+
3649
QgsRasterBandStats()
3750
{
3851
bandName = "";
39-
statsGathered = false;
52+
statsGathered = None;
4053
minimumValue = std::numeric_limits<double>::max();
4154
maximumValue = std::numeric_limits<double>::min();
4255
range = 0.0;
@@ -50,12 +63,13 @@ class CORE_EXPORT QgsRasterBandStats
5063
}
5164

5265
/*! Compares region, size etc. not collected statistics */
53-
bool operator==( const QgsRasterBandStats &s ) const
66+
bool contains( const QgsRasterBandStats &s ) const
5467
{
5568
return ( s.bandNumber == bandNumber &&
5669
s.extent == extent &&
5770
s.width == width &&
58-
s.height == height );
71+
s.height == height &&
72+
s.statsGathered == ( statsGathered & s.statsGathered ) );
5973
}
6074

6175
/** \brief The name of the band that these stats belong to. */
@@ -88,9 +102,8 @@ class CORE_EXPORT QgsRasterBandStats
88102
/** \brief The standard deviation of the cell values. */
89103
double stdDev;
90104

91-
/** \brief A flag to indicate whether this RasterBandStats struct
92-
* is completely populated */
93-
bool statsGathered;
105+
/** \brief Collected statistics */
106+
int statsGathered;
94107

95108
/** \brief The sum of all cells in the band. NO_DATA values are excluded. */
96109
double sum;

‎src/core/raster/qgsrasterlayer.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ unsigned int QgsRasterLayer::bandCount() const
287287

288288
const QString QgsRasterLayer::bandName( int theBandNo )
289289
{
290+
#if 0
290291
if ( theBandNo <= mRasterStatsList.size() && theBandNo > 0 )
291292
{
292293
//vector starts at base 0, band counts at base1!
@@ -296,23 +297,30 @@ const QString QgsRasterLayer::bandName( int theBandNo )
296297
{
297298
return QString( "" );
298299
}
300+
#endif
301+
return dataProvider()->generateBandName( theBandNo );
299302
}
300303

301304
int QgsRasterLayer::bandNumber( QString const & theBandName ) const
302305
{
303-
for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
306+
if ( !mDataProvider ) return 0;
307+
for ( int myIterator = 1; myIterator <= dataProvider()->bandCount(); ++myIterator )
304308
{
305309
//find out the name of this band
310+
#if 0
306311
QgsRasterBandStats myRasterBandStats = mRasterStatsList[myIterator];
307312
QgsDebugMsg( "myRasterBandStats.bandName: " + myRasterBandStats.bandName + " :: theBandName: "
308313
+ theBandName );
309314

310315
if ( myRasterBandStats.bandName == theBandName )
316+
#endif
317+
QString myBandName = dataProvider()->generateBandName( myIterator );
318+
if ( myBandName == theBandName )
311319
{
312-
QgsDebugMsg( "********** band " + QString::number( myRasterBandStats.bandNumber ) +
320+
QgsDebugMsg( "********** band " + QString::number( myIterator ) +
313321
" was found in bandNumber " + theBandName );
314322

315-
return myRasterBandStats.bandNumber;
323+
return myIterator;
316324
}
317325
}
318326
QgsDebugMsg( "********** no band was found in bandNumber " + theBandName );
@@ -612,11 +620,13 @@ bool QgsRasterLayer::copySymbologySettings( const QgsMapLayer& theOther )
612620

613621
/**
614622
* @param theBandNo the band number
615-
* @return pointer to the color table
623+
* @return ointer to the color table
616624
*/
617-
QList<QgsColorRampShader::ColorRampItem>* QgsRasterLayer::colorTable( int theBandNo )
625+
QList<QgsColorRampShader::ColorRampItem> QgsRasterLayer::colorTable( int theBandNo )
618626
{
619-
return &( mRasterStatsList[theBandNo-1].colorTable );
627+
//return &( mRasterStatsList[theBandNo-1].colorTable );
628+
if ( !mDataProvider ) return QList<QgsColorRampShader::ColorRampItem>();
629+
return dataProvider()->colorTable( theBandNo );
620630
}
621631

622632
/**
@@ -1707,6 +1717,7 @@ void QgsRasterLayer::setDataProvider( QString const & provider )
17071717
mBandCount = mDataProvider->bandCount( );
17081718
for ( int i = 1; i <= mBandCount; i++ )
17091719
{
1720+
#if 0
17101721
QgsRasterBandStats myRasterBandStats;
17111722
myRasterBandStats.bandName = mDataProvider->generateBandName( i );
17121723
myRasterBandStats.bandNumber = i;
@@ -1718,6 +1729,7 @@ void QgsRasterLayer::setDataProvider( QString const & provider )
17181729
myRasterBandStats.colorTable = ct;
17191730

17201731
mRasterStatsList.push_back( myRasterBandStats );
1732+
#endif
17211733

17221734
//Build a new contrast enhancement for the band and store in list
17231735
//QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )mDataProvider->dataType( i ) );
@@ -1814,7 +1826,7 @@ void QgsRasterLayer::closeDataProvider()
18141826
mPipe.remove( mDataProvider );
18151827
mDataProvider = 0;
18161828

1817-
mRasterStatsList.clear();
1829+
//mRasterStatsList.clear();
18181830
mContrastEnhancementList.clear();
18191831

18201832
mHasPyramids = false;
@@ -2066,12 +2078,15 @@ void QgsRasterLayer::setNoDataValue( double theNoDataValue )
20662078
mNoDataValue = theNoDataValue;
20672079
mValidNoDataValue = true;
20682080
//Basically set the raster stats as invalid
2081+
// TODO! No data value must be set on provider and stats cleared
2082+
#if 0
20692083
QList<QgsRasterBandStats>::iterator myIterator = mRasterStatsList.begin();
20702084
while ( myIterator != mRasterStatsList.end() )
20712085
{
20722086
( *myIterator ).statsGathered = false;
20732087
++myIterator;
20742088
}
2089+
#endif
20752090
}
20762091
}
20772092

@@ -2651,19 +2666,22 @@ QString QgsRasterLayer::validateBandName( QString const & theBandName )
26512666
return TRSTRING_NOT_SET;
26522667
}
26532668

2669+
if ( !mDataProvider ) return TRSTRING_NOT_SET;
2670+
26542671
//check that a valid band name was passed
26552672
QgsDebugMsg( "Looking through raster band stats for matching band name" );
2656-
for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
2673+
for ( int myIterator = 1; myIterator < mDataProvider->bandCount(); ++myIterator )
26572674
{
26582675
//find out the name of this band
2659-
if ( mRasterStatsList[myIterator].bandName == theBandName )
2676+
if ( mDataProvider->generateBandName( myIterator ) == theBandName );
26602677
{
26612678
QgsDebugMsg( "Matching band name found" );
26622679
return theBandName;
26632680
}
26642681
}
26652682
QgsDebugMsg( "No matching band name found in raster band stats" );
26662683

2684+
#if 0
26672685
QgsDebugMsg( "Testing for non zero-buffered names" );
26682686
//TODO Remove test in v2.0 or earlier
26692687
QStringList myBandNameComponents = theBandName.split( " " );
@@ -2702,6 +2720,7 @@ QString QgsRasterLayer::validateBandName( QString const & theBandName )
27022720
}
27032721
}
27042722
}
2723+
#endif
27052724

27062725
//if no matches were found default to not set
27072726
QgsDebugMsg( "All checks failed, returning '" + QSTRING_NOT_SET + "'" );

‎src/core/raster/qgsrasterlayer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
430430
bool copySymbologySettings( const QgsMapLayer& theOther );
431431

432432
/** \brief Get a pointer to the color table */
433-
QList<QgsColorRampShader::ColorRampItem>* colorTable( int theBandNoInt );
433+
QList<QgsColorRampShader::ColorRampItem> colorTable( int theBandNoInt );
434434

435435
/** Returns the data provider */
436436
QgsRasterDataProvider* dataProvider();
@@ -530,7 +530,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
530530
/** \brief Returns the number of raster units per each raster pixel. In a world file, this is normally the first row (without the sign) */
531531
double rasterUnitsPerPixel();
532532

533-
const RasterStatsList rasterStatsList() const { return mRasterStatsList; }
533+
//const RasterStatsList rasterStatsList() const { return mRasterStatsList; }
534534

535535
/** \brief Read color table from GDAL raster band */
536536
// Keep this for QgsRasterLayerProperties
@@ -844,7 +844,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
844844
RasterPyramidList mPyramidList;
845845

846846
/** \brief A collection of stats - one for each band in the layer */
847-
RasterStatsList mRasterStatsList;
847+
//RasterStatsList mRasterStatsList;
848848

849849
LayerType mRasterType;
850850

‎src/gui/raster/qgspalettedrendererwidget.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ void QgsPalettedRendererWidget::setFromRenderer( const QgsRasterRenderer* r )
9191
else
9292
{
9393
//read default palette settings from layer
94-
QList<QgsColorRampShader::ColorRampItem>* itemList =
94+
QList<QgsColorRampShader::ColorRampItem> itemList =
9595
mRasterLayer->colorTable( mBandComboBox->itemData( mBandComboBox->currentIndex() ).toInt() );
96-
QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList->constBegin();
96+
QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList.constBegin();
9797
int index = 0;
98-
for ( ; itemIt != itemList->constEnd(); ++itemIt )
98+
for ( ; itemIt != itemList.constEnd(); ++itemIt )
9999
{
100100
QTreeWidgetItem* item = new QTreeWidgetItem( mTreeWidget );
101101
item->setText( 0, QString::number( index ) );

‎src/gui/raster/qgsrasterhistogramwidget.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,9 @@ void QgsRasterHistogramWidget::refreshHistogram()
406406
if ( ! mySelectedBands.contains( myIteratorInt ) )
407407
continue;
408408
}
409-
QgsRasterBandStats myRasterBandStats = mRasterLayer->dataProvider()->bandStatistics( myIteratorInt );
410-
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
411409
int sampleSize = 250000; // number of sample cells
410+
//QgsRasterBandStats myRasterBandStats = mRasterLayer->dataProvider()->bandStatistics( myIteratorInt );
411+
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
412412
QgsRasterHistogram myHistogram = mRasterLayer->dataProvider()->histogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );
413413

414414
QwtPlotCurve * mypCurve = new QwtPlotCurve( tr( "Band %1" ).arg( myIteratorInt ) );
@@ -424,8 +424,10 @@ void QgsRasterHistogramWidget::refreshHistogram()
424424
// calculate first bin x value and bin step size if not Byte data
425425
if ( mRasterLayer->dataProvider()->srcDataType( myIteratorInt ) != QgsRasterDataProvider::Byte )
426426
{
427-
myBinXStep = myRasterBandStats.range / BINCOUNT;
428-
myBinX = myRasterBandStats.minimumValue + myBinXStep / 2.0;
427+
//myBinXStep = myRasterBandStats.range / BINCOUNT;
428+
//myBinX = myRasterBandStats.minimumValue + myBinXStep / 2.0;
429+
myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / BINCOUNT;
430+
myBinX = myHistogram.minimum + myBinXStep / 2.0;
429431
}
430432
else
431433
{
@@ -451,13 +453,13 @@ void QgsRasterHistogramWidget::refreshHistogram()
451453
mypCurve->setData( myX2Data, myY2Data );
452454
#endif
453455
mypCurve->attach( mpPlot );
454-
if ( myFirstIteration || mHistoMin > myRasterBandStats.minimumValue )
456+
if ( myFirstIteration || mHistoMin > myHistogram.minimum )
455457
{
456-
mHistoMin = myRasterBandStats.minimumValue;
458+
mHistoMin = myHistogram.minimum;
457459
}
458-
if ( myFirstIteration || mHistoMax < myRasterBandStats.maximumValue )
460+
if ( myFirstIteration || mHistoMax < myHistogram.maximum )
459461
{
460-
mHistoMax = myRasterBandStats.maximumValue;
462+
mHistoMax = myHistogram.maximum;
461463
}
462464
QgsDebugMsg( QString( "computed histo min = %1 max = %2" ).arg( mHistoMin ).arg( mHistoMax ) );
463465
myFirstIteration = false;

‎src/gui/raster/qgsrasterminmaxwidget.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
#include "qgsrasterminmaxwidget.h"
2020

2121
QgsRasterMinMaxWidget::QgsRasterMinMaxWidget( QgsRasterLayer* theLayer, QWidget *parent ):
22-
QWidget( parent )
23-
,mLayer ( theLayer )
22+
QWidget( parent )
23+
, mLayer( theLayer )
2424
{
25-
QgsDebugMsg("Entered.");
25+
QgsDebugMsg( "Entered." );
2626
setupUi( this );
2727
}
2828

@@ -32,12 +32,12 @@ QgsRasterMinMaxWidget::~QgsRasterMinMaxWidget()
3232

3333
void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
3434
{
35-
QgsDebugMsg("Entered.");
35+
QgsDebugMsg( "Entered." );
3636

37-
foreach ( int myBand, mBands )
37+
foreach( int myBand, mBands )
3838
{
39-
QgsDebugMsg( QString("myBand = %1").arg(myBand));
40-
if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
39+
QgsDebugMsg( QString( "myBand = %1" ).arg( myBand ) );
40+
if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
4141
{
4242
continue;
4343
}
@@ -46,10 +46,10 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
4646

4747
QgsRectangle myExtent; // empty == full
4848
if ( mCurrentExtentRadioButton->isChecked() )
49-
{
49+
{
5050
myExtent = mExtent; // current
5151
}
52-
QgsDebugMsg( QString("myExtent.isEmpty() = %1").arg(myExtent.isEmpty()) );
52+
QgsDebugMsg( QString( "myExtent.isEmpty() = %1" ).arg( myExtent.isEmpty() ) );
5353

5454
int mySampleSize = 0; // 0 == exact
5555
if ( mEstimateRadioButton->isChecked() )
@@ -59,24 +59,24 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
5959

6060
if ( mCumulativeCutRadioButton->isChecked() )
6161
{
62-
mLayer->dataProvider()->cumulativeCut ( myBand, 0.02, 0.98, myMin, myMax, myExtent, mySampleSize );
63-
}
62+
mLayer->dataProvider()->cumulativeCut( myBand, 0.02, 0.98, myMin, myMax, myExtent, mySampleSize );
63+
}
6464
else if ( mMinMaxRadioButton->isChecked() )
6565
{
6666
// TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
67-
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, myExtent, mySampleSize );
67+
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, myExtent, mySampleSize );
6868
myMin = myRasterBandStats.minimumValue;
6969
myMax = myRasterBandStats.maximumValue;
7070
}
7171
else if ( mStdDevRadioButton->isChecked() )
7272
{
73-
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, myExtent, mySampleSize );
73+
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean, myExtent, mySampleSize );
7474
double myStdDev = mStdDevSpinBox->value();
7575
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
7676
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
7777

7878
}
7979

80-
emit load ( myBand, myMin, myMax );
80+
emit load( myBand, myMin, myMax );
8181
}
8282
}

‎src/providers/gdal/qgsgdalprovider.cpp

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,8 @@ bool QgsGdalProvider::hasHistogram( int theBandNo,
12581258
return true;
12591259
}
12601260

1261-
QgsRasterHistogram myHistogram = histogramDefaults( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
1261+
QgsRasterHistogram myHistogram;
1262+
initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
12621263

12631264
// If not cached, check if supported by GDAL
12641265
if ( myHistogram.extent != extent() )
@@ -1329,7 +1330,8 @@ QgsRasterHistogram QgsGdalProvider::histogram( int theBandNo,
13291330
{
13301331
QgsDebugMsg( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ) );
13311332

1332-
QgsRasterHistogram myHistogram = histogramDefaults( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
1333+
QgsRasterHistogram myHistogram;
1334+
initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
13331335

13341336
// Find cached
13351337
foreach( QgsRasterHistogram histogram, mHistograms )
@@ -2002,21 +2004,28 @@ QGISEXTERN bool isValidRasterFileName( QString const & theFileNameQString, QStri
20022004
}
20032005

20042006
bool QgsGdalProvider::hasStatistics( int theBandNo,
2007+
int theStats,
20052008
const QgsRectangle & theExtent,
20062009
int theSampleSize )
20072010
{
20082011
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
20092012

20102013
// First check if cached in mStatistics
2011-
if ( QgsRasterDataProvider::hasStatistics( theBandNo, theExtent, theSampleSize ) )
2014+
if ( QgsRasterDataProvider::hasStatistics( theBandNo, theStats, theExtent, theSampleSize ) )
20122015
{
20132016
return true;
20142017
}
20152018

2016-
QgsRasterBandStats myRasterBandStats = statisticsDefaults( theBandNo, theExtent, theSampleSize );
2019+
QgsRasterBandStats myRasterBandStats;
2020+
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
20172021

20182022
// If not cached, check if supported by GDAL
2019-
if ( myRasterBandStats.extent != extent() )
2023+
int supportedStats = QgsRasterBandStats::Min | QgsRasterBandStats::Max
2024+
| QgsRasterBandStats::Range | QgsRasterBandStats::Mean
2025+
| QgsRasterBandStats::StdDev;
2026+
2027+
if ( myRasterBandStats.extent != extent() ||
2028+
( theStats & ( ~supportedStats ) ) )
20202029
{
20212030
QgsDebugMsg( "Not supported by GDAL." );
20222031
return false;
@@ -2041,13 +2050,19 @@ bool QgsGdalProvider::hasStatistics( int theBandNo,
20412050

20422051
// Params in GDALGetRasterStatistics must not be NULL otherwise GDAL returns
20432052
// without error even if stats are not cached
2044-
double pdfMin;
2045-
double pdfMax;
2046-
double pdfMean;
2047-
double pdfStdDev;
2053+
double dfMin, dfMax, dfMean, dfStdDev;
2054+
double *pdfMin = &dfMin;
2055+
double *pdfMax = &dfMax;
2056+
double *pdfMean = &dfMean;
2057+
double *pdfStdDev = &dfStdDev;
2058+
2059+
if ( !( theStats & QgsRasterBandStats::Min ) ) pdfMin = NULL;
2060+
if ( !( theStats & QgsRasterBandStats::Max ) ) pdfMax = NULL;
2061+
if ( !( theStats & QgsRasterBandStats::Mean ) ) pdfMean = NULL;
2062+
if ( !( theStats & QgsRasterBandStats::StdDev ) ) pdfStdDev = NULL;
20482063

20492064
// try to fetch the cached stats (bForce=FALSE)
2050-
CPLErr myerval = GDALGetRasterStatistics( myGdalBand, bApproxOK, FALSE, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev );
2065+
CPLErr myerval = GDALGetRasterStatistics( myGdalBand, bApproxOK, FALSE, pdfMin, pdfMax, pdfMean, pdfStdDev );
20512066

20522067
if ( CE_None == myerval ) // CE_Warning if cached not found
20532068
{
@@ -2058,29 +2073,40 @@ bool QgsGdalProvider::hasStatistics( int theBandNo,
20582073
return false;
20592074
}
20602075

2061-
QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, const QgsRectangle & theExtent, int theSampleSize )
2076+
QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, int theStats, const QgsRectangle & theExtent, int theSampleSize )
20622077
{
20632078
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
2079+
2080+
// TODO: null values set on raster layer!!!
2081+
20642082
// Currently there is no API in GDAL to collect statistics of specified extent
20652083
// or with defined sample size. We check first if we have cached stats, if not,
20662084
// and it is not possible to use GDAL we call generic provider method,
20672085
// otherwise we use GDAL (faster, cache)
20682086

2069-
QgsRasterBandStats myRasterBandStats = statisticsDefaults( theBandNo, theExtent, theSampleSize );
2087+
QgsRasterBandStats myRasterBandStats;
2088+
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
20702089

20712090
foreach( QgsRasterBandStats stats, mStatistics )
20722091
{
2073-
if ( stats == myRasterBandStats )
2092+
if ( stats.contains( myRasterBandStats ) )
20742093
{
20752094
QgsDebugMsg( "Using cached statistics." );
20762095
return stats;
20772096
}
20782097
}
20792098

2080-
if ( myRasterBandStats.extent != extent() )
2099+
int supportedStats = QgsRasterBandStats::Min | QgsRasterBandStats::Max
2100+
| QgsRasterBandStats::Range | QgsRasterBandStats::Mean
2101+
| QgsRasterBandStats::StdDev;
2102+
2103+
QgsDebugMsg( QString( "theStats = %1 supportedStats = %2" ).arg( theStats, 0, 2 ).arg( supportedStats, 0, 2 ) );
2104+
2105+
if ( myRasterBandStats.extent != extent() ||
2106+
( theStats & ( ~supportedStats ) ) )
20812107
{
20822108
QgsDebugMsg( "Using generic statistics." );
2083-
return QgsRasterDataProvider::bandStatistics( theBandNo, theExtent, theSampleSize );
2109+
return QgsRasterDataProvider::bandStatistics( theBandNo, theStats, theExtent, theSampleSize );
20842110
}
20852111

20862112
QgsDebugMsg( "Using GDAL statistics." );
@@ -2131,10 +2157,14 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, const QgsRect
21312157
//calculate the mean
21322158
myRasterBandStats.mean = pdfMean;
21332159
myRasterBandStats.sum = 0; //not available via gdal
2134-
myRasterBandStats.elementCount = mWidth * mHeight;
2160+
//myRasterBandStats.elementCount = mWidth * mHeight;
2161+
// Sum of non NULL
2162+
myRasterBandStats.elementCount = 0; //not available via gdal
21352163
myRasterBandStats.sumOfSquares = 0; //not available via gdal
21362164
myRasterBandStats.stdDev = pdfStdDev;
2137-
myRasterBandStats.statsGathered = true;
2165+
myRasterBandStats.statsGathered = QgsRasterBandStats::Min | QgsRasterBandStats::Max
2166+
| QgsRasterBandStats::Range | QgsRasterBandStats::Mean
2167+
| QgsRasterBandStats::StdDev;
21382168

21392169
#ifdef QGISDEBUG
21402170
QgsDebugMsg( "************ STATS **************" );
@@ -2145,9 +2175,6 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, const QgsRect
21452175
QgsDebugMsg( QString( "MEAN %1" ).arg( myRasterBandStats.mean ) );
21462176
QgsDebugMsg( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ) );
21472177
#endif
2148-
2149-
myRasterBandStats.statsGathered = true;
2150-
21512178
}
21522179

21532180
mStatistics.append( myRasterBandStats );

‎src/providers/gdal/qgsgdalprovider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,12 @@ class QgsGdalProvider : public QgsRasterDataProvider
239239
static QStringList subLayers( GDALDatasetH dataset );
240240

241241
bool hasStatistics( int theBandNo,
242+
int theStats = QgsRasterBandStats::All,
242243
const QgsRectangle & theExtent = QgsRectangle(),
243244
int theSampleSize = 0 );
244245

245246
QgsRasterBandStats bandStatistics( int theBandNo,
247+
int theStats = QgsRasterBandStats::All,
246248
const QgsRectangle & theExtent = QgsRectangle(),
247249
int theSampleSize = 0 );
248250

‎tests/src/core/testqgsrasterlayer.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,26 +183,32 @@ void TestQgsRasterLayer::landsatBasic875Qml()
183183
}
184184
void TestQgsRasterLayer::checkDimensions()
185185
{
186+
mReport += "<h2>Check Dimensions</h2>\n";
186187
QVERIFY( mpRasterLayer->width() == 10 );
187188
QVERIFY( mpRasterLayer->height() == 10 );
188189
// regression check for ticket #832
189190
// note bandStatistics call is base 1
190-
QVERIFY( mpRasterLayer->dataProvider()->bandStatistics( 1 ).elementCount == 100 );
191-
mReport += "<h2>Check Dimensions</h2>\n";
191+
// TODO: elementCount is not collected by GDAL, use other stats.
192+
//QVERIFY( mpRasterLayer->dataProvider()->bandStatistics( 1 ).elementCount == 100 );
192193
mReport += "<p>Passed</p>";
193194
}
194195
void TestQgsRasterLayer::checkStats()
195196
{
196-
QgsRasterBandStats myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1 );
197+
mReport += "<h2>Check Stats</h2>\n";
198+
QgsRasterBandStats myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1,
199+
QgsRasterBandStats::Min | QgsRasterBandStats::Max |
200+
QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev );
197201
QVERIFY( mpRasterLayer->width() == 10 );
198202
QVERIFY( mpRasterLayer->height() == 10 );
199-
QVERIFY( myStatistics.elementCount == 100 );
203+
//QVERIFY( myStatistics.elementCount == 100 );
200204
QVERIFY( myStatistics.minimumValue == 0 );
201205
QVERIFY( myStatistics.maximumValue == 9 );
202206
QVERIFY( myStatistics.mean == 4.5 );
203-
QVERIFY( fabs( myStatistics.stdDev - 2.87228132326901431 )
207+
double stdDev = 2.87228132326901431;
208+
// TODO: verify why GDAL stdDev is so different from generic (2.88675)
209+
mReport += QString( "stdDev = %1 expected = %2<br>\n" ).arg( myStatistics.stdDev ).arg( stdDev );
210+
QVERIFY( fabs( myStatistics.stdDev - stdDev )
204211
< 0.0000000000000001 );
205-
mReport += "<h2>Check Stats</h2>\n";
206212
mReport += "<p>Passed</p>";
207213
}
208214

0 commit comments

Comments
 (0)
Please sign in to comment.