23 #include <QStringList>
42 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 sampleSize = %2" ).arg( bandNo ).arg( sampleSize ), 4 );
56 statistics.
extent = finalExtent;
62 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
69 if ( xRes < srcXRes ) xRes = srcXRes;
70 if ( yRes < srcYRes ) yRes = srcYRes;
72 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
74 statistics.
width =
static_cast <int>( std::ceil( finalExtent.
width() / xRes ) );
75 statistics.
height =
static_cast <int>( std::ceil( finalExtent.
height() / yRes ) );
86 statistics.
width = 1000;
90 QgsDebugMsgLevel( QStringLiteral(
"theStatistics.width = %1 statistics.height = %2" ).arg( statistics.
width ).arg( statistics.
height ), 4 );
98 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
107 if ( stats.contains( myRasterBandStats ) )
121 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
131 if ( stats.contains( myRasterBandStats ) )
139 int myWidth = myRasterBandStats.
width;
140 int myHeight = myRasterBandStats.
height;
146 if ( myXBlockSize == 0 )
150 if ( myYBlockSize == 0 )
155 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
156 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
158 double myXRes = myExtent.
width() / myWidth;
159 double myYRes = myExtent.
height() / myHeight;
164 double mySumOfSquares = 0;
166 bool myFirstIterationFlag =
true;
167 bool isNoData =
false;
168 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
170 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
173 return myRasterBandStats;
175 QgsDebugMsgLevel( QStringLiteral(
"myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
176 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
177 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
179 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
180 double xmax = xmin + myBlockWidth * myXRes;
181 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
182 double ymax = ymin - myBlockHeight * myYRes;
186 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
189 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
191 double myValue = blk->valueAndNoData( i, isNoData );
195 myRasterBandStats.
sum += myValue;
198 if ( !std::isfinite( myValue ) )
continue;
200 if ( myFirstIterationFlag )
202 myFirstIterationFlag =
false;
219 double myDelta = myValue - myMean;
221 mySumOfSquares += myDelta * ( myValue - myMean );
234 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.
elementCount - 1 ) );
236 QgsDebugMsgLevel( QStringLiteral(
"************ STATS **************" ), 4 );
246 return myRasterBandStats;
252 double minimum,
double maximum,
255 bool includeOutOfRange )
305 if ( sampleSize > 0 )
309 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
316 if ( xRes < srcXRes ) xRes = srcXRes;
317 if ( yRes < srcYRes ) yRes = srcYRes;
319 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
339 int myBinCount = binCount;
340 if ( myBinCount == 0 )
378 double minimum,
double maximum,
381 bool includeOutOfRange )
383 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
389 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
405 double minimum,
double maximum,
410 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
413 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
426 int myBinCount = myHistogram.
binCount;
427 int myWidth = myHistogram.
width;
428 int myHeight = myHistogram.
height;
434 if ( myXBlockSize == 0 )
438 if ( myYBlockSize == 0 )
443 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
444 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
446 double myXRes = myExtent.
width() / myWidth;
447 double myYRes = myExtent.
height() / myHeight;
449 double myMinimum = myHistogram.
minimum;
450 double myMaximum = myHistogram.
maximum;
454 double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
455 myMinimum -= 0.1 * myerval;
456 myMaximum += 0.1 * myerval;
458 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
460 double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
463 bool isNoData =
false;
464 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
466 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
471 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
472 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
474 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
475 double xmax = xmin + myBlockWidth * myXRes;
476 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
477 double ymax = ymin - myBlockHeight * myYRes;
481 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
484 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
486 double myValue = blk->valueAndNoData( i, isNoData );
492 int myBinIndex =
static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
494 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
498 if ( myBinIndex < 0 ) myBinIndex = 0;
499 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
507 myHistogram.
valid =
true;
512 for (
int i = 0; i < std::min( myHistogram.
histogramVector.size(), 500 ); i++ )
514 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
516 QgsDebugMsgLevel( QStringLiteral(
"Histogram (max first 500 bins): " ) + hist, 4 );
523 double lowerCount,
double upperCount,
524 double &lowerValue,
double &upperValue,
528 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
533 lowerValue = std::numeric_limits<double>::quiet_NaN();
534 upperValue = std::numeric_limits<double>::quiet_NaN();
548 int myMinCount =
static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
549 int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
550 bool myLowerFound =
false;
551 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
552 QgsDebugMsgLevel( QStringLiteral(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
554 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
557 myCount += myBinValue;
558 if ( !myLowerFound && myCount > myMinCount )
560 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
562 QgsDebugMsgLevel( QStringLiteral(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
564 if ( myCount >= myMaxCount )
566 upperValue = myHistogram.
minimum + myBin * myBinXStep;
567 QgsDebugMsgLevel( QStringLiteral(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
577 if ( !std::isnan( lowerValue ) )
578 lowerValue = std::floor( lowerValue );
579 if ( !std::isnan( upperValue ) )
580 upperValue = std::ceil( upperValue );
586 QStringList abilitiesList;
596 abilitiesList += tr(
"Identify" );
601 abilitiesList += tr(
"Create Datasources" );
606 abilitiesList += tr(
"Remove Datasources" );
611 abilitiesList += tr(
"Build Pyramids" );
614 QgsDebugMsgLevel(
"Capability: " + abilitiesList.join( QStringLiteral(
", " ) ), 4 );
616 return abilitiesList.join( QStringLiteral(
", " ) );