@@ -325,7 +325,6 @@ const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
325325 QgsRasterBandStats myNullReturnStats;
326326 return myNullReturnStats;
327327 }
328-
329328 // check if we have received a valid band number
330329 if (( mDataProvider ->bandCount () < theBandNo ) && mRasterType != Palette )
331330 {
@@ -339,7 +338,6 @@ const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
339338 QgsRasterBandStats myNullReturnStats;
340339 return myNullReturnStats;
341340 }
342-
343341 // check if we have previously gathered stats for this band...
344342 if ( theBandNo < 1 || theBandNo > mRasterStatsList .size () )
345343 {
@@ -356,174 +354,23 @@ const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
356354 {
357355 return myRasterBandStats;
358356 }
359- // only print message if we are actually gathering the stats
360- emit statusChanged ( tr ( " Retrieving stats for %1" ).arg ( name () ) );
361- qApp->processEvents ();
362- QgsDebugMsg ( " stats for band " + QString::number ( theBandNo ) );
363-
364- myRasterBandStats.elementCount = 0 ; // because we'll be counting only VALID pixels later
365-
366- emit statusChanged ( tr ( " Calculating stats for %1" ).arg ( name () ) );
367- // reset the main app progress bar
368- emit drawingProgress ( 0 , 0 );
369-
370- int myDataType = mDataProvider ->dataType ( theBandNo );
371-
372- int myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
373- myXBlockSize = mDataProvider ->xBlockSize ();
374- myYBlockSize = mDataProvider ->yBlockSize ();
375-
376- myNXBlocks = ( mDataProvider ->xSize () + myXBlockSize - 1 ) / myXBlockSize;
377- myNYBlocks = ( mDataProvider ->ySize () + myYBlockSize - 1 ) / myYBlockSize;
378-
379- void *myData = CPLMalloc ( myXBlockSize * myYBlockSize * ( mDataProvider ->dataTypeSize ( theBandNo ) / 8 ) );
380-
381- // unfortunately we need to make two passes through the data to calculate stddev
382- bool myFirstIterationFlag = true ;
383-
384- int myBandXSize = mDataProvider ->xSize ();
385- int myBandYSize = mDataProvider ->ySize ();
386- for ( int iYBlock = 0 ; iYBlock < myNYBlocks; iYBlock++ )
387- {
388- emit drawingProgress ( iYBlock, myNYBlocks * 2 );
389-
390- for ( int iXBlock = 0 ; iXBlock < myNXBlocks; iXBlock++ )
391- {
392- int nXValid, nYValid;
393- mDataProvider ->readBlock ( theBandNo, iXBlock, iYBlock, myData );
394-
395- // Compute the portion of the block that is valid
396- // for partial edge blocks.
397- if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
398- nXValid = myBandXSize - iXBlock * myXBlockSize;
399- else
400- nXValid = myXBlockSize;
401-
402- if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
403- nYValid = myBandYSize - iYBlock * myYBlockSize;
404- else
405- nYValid = myYBlockSize;
406-
407- // Collect the histogram counts.
408- for ( int iY = 0 ; iY < nYValid; iY++ )
409- {
410- for ( int iX = 0 ; iX < nXValid; iX++ )
411- {
412- double myValue = readValue ( myData, myDataType, iX + ( iY * myXBlockSize ) );
413- // QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (iX).arg(iY).arg( myValue ) );
414-
415- if ( mValidNoDataValue && ( qAbs ( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
416- {
417- continue ; // NULL
418- }
419-
420- myRasterBandStats.sum += myValue;
421- ++myRasterBandStats.elementCount ;
422- // only use this element if we have a non null element
423- if ( myFirstIterationFlag )
424- {
425- // this is the first iteration so initialise vars
426- myFirstIterationFlag = false ;
427- myRasterBandStats.minimumValue = myValue;
428- myRasterBandStats.maximumValue = myValue;
429- } // end of true part for first iteration check
430- else
431- {
432- // this is done for all subsequent iterations
433- if ( myValue < myRasterBandStats.minimumValue )
434- {
435- myRasterBandStats.minimumValue = myValue;
436- }
437- if ( myValue > myRasterBandStats.maximumValue )
438- {
439- myRasterBandStats.maximumValue = myValue;
440- }
441- } // end of false part for first iteration check
442- }
443- }
444- } // end of column wise loop
445- } // end of row wise loop
446-
447-
448- // end of first pass through data now calculate the range
449- myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue ;
450- // calculate the mean
451- myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount ;
452-
453- // for the second pass we will get the sum of the squares / mean
454- for ( int iYBlock = 0 ; iYBlock < myNYBlocks; iYBlock++ )
455- {
456- emit drawingProgress ( iYBlock + myNYBlocks, myNYBlocks * 2 );
457-
458- for ( int iXBlock = 0 ; iXBlock < myNXBlocks; iXBlock++ )
459- {
460- int nXValid, nYValid;
461-
462- mDataProvider ->readBlock ( theBandNo, iXBlock, iYBlock, myData );
463-
464- // Compute the portion of the block that is valid
465- // for partial edge blocks.
466- if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
467- nXValid = myBandXSize - iXBlock * myXBlockSize;
468- else
469- nXValid = myXBlockSize;
470-
471- if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
472- nYValid = myBandYSize - iYBlock * myYBlockSize;
473- else
474- nYValid = myYBlockSize;
475-
476- // Collect the histogram counts.
477- for ( int iY = 0 ; iY < nYValid; iY++ )
478- {
479- for ( int iX = 0 ; iX < nXValid; iX++ )
480- {
481- double myValue = readValue ( myData, myDataType, iX + ( iY * myXBlockSize ) );
482- // QgsDebugMsg ( "myValue = " + QString::number(myValue) );
483-
484- if ( mValidNoDataValue && ( qAbs ( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
485- {
486- continue ; // NULL
487- }
488-
489- myRasterBandStats.sumOfSquares += static_cast < double >
490- ( pow ( myValue - myRasterBandStats.mean , 2 ) );
491- }
492- }
493- } // end of column wise loop
494- } // end of row wise loop
495-
496- // divide result by sample size - 1 and get square root to get stdev
497- myRasterBandStats.stdDev = static_cast < double >( sqrt ( myRasterBandStats.sumOfSquares /
498- ( myRasterBandStats.elementCount - 1 ) ) );
499-
500- #ifdef QGISDEBUG
501- QgsLogger::debug ( " ************ STATS **************" , 1 , __FILE__, __FUNCTION__, __LINE__ );
502- QgsLogger::debug ( " VALID NODATA" , mValidNoDataValue , 1 , __FILE__, __FUNCTION__, __LINE__ );
503- QgsLogger::debug ( " NULL" , mNoDataValue , 1 , __FILE__, __FUNCTION__, __LINE__ );
504- QgsLogger::debug ( " MIN" , myRasterBandStats.minimumValue , 1 , __FILE__, __FUNCTION__, __LINE__ );
505- QgsLogger::debug ( " MAX" , myRasterBandStats.maximumValue , 1 , __FILE__, __FUNCTION__, __LINE__ );
506- QgsLogger::debug ( " RANGE" , myRasterBandStats.range , 1 , __FILE__, __FUNCTION__, __LINE__ );
507- QgsLogger::debug ( " MEAN" , myRasterBandStats.mean , 1 , __FILE__, __FUNCTION__, __LINE__ );
508- QgsLogger::debug ( " STDDEV" , myRasterBandStats.stdDev , 1 , __FILE__, __FUNCTION__, __LINE__ );
509- #endif
510-
511- CPLFree ( myData );
512- myRasterBandStats.statsGathered = true ;
513357
358+ myRasterBandStats = mDataProvider ->bandStatistics ( theBandNo );
514359 QgsDebugMsg ( " adding stats to stats collection at position " + QString::number ( theBandNo - 1 ) );
515360 // add this band to the class stats map
516361 mRasterStatsList [theBandNo - 1 ] = myRasterBandStats;
517362 emit drawingProgress ( mHeight , mHeight ); // reset progress
518- // QApplication::restoreOverrideCursor(); //restore the cursor
519363 QgsDebugMsg ( " Stats collection completed returning" );
520364 return myRasterBandStats;
521-
522365} // QgsRasterLayer::bandStatistics
523366
524367const QgsRasterBandStats QgsRasterLayer::bandStatistics ( QString const & theBandName )
525368{
526-
369+ // only print message if we are actually gathering the stats
370+ emit statusChanged ( tr ( " Retrieving stats for %1" ).arg ( name () ) );
371+ qApp->processEvents ();
372+ // reset the main app progress bar
373+ emit drawingProgress ( 0 , 0 );
527374 // we cant use a vector iterator because the iterator is astruct not a class
528375 // and the qvector model does not like this.
529376 for ( int i = 1 ; i <= mDataProvider ->bandCount (); i++ )
0 commit comments