23 #include <QStringList>
40 int sampleSize )
const
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 const int myWidth = myRasterBandStats.
width;
140 const int myHeight = myRasterBandStats.
height;
146 if ( myXBlockSize == 0 )
150 if ( myYBlockSize == 0 )
155 const int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
156 const int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
158 const double myXRes = myExtent.
width() / myWidth;
159 const 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 const int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
177 const int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
179 const double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
180 const double xmax = xmin + myBlockWidth * myXRes;
181 const double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
182 const double ymax = ymin - myBlockHeight * myYRes;
184 const QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
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 const double myValue = blk->valueAndNoData( i, isNoData );
195 myRasterBandStats.
sum += myValue;
198 if ( !std::isfinite( myValue ) )
continue;
200 if ( myFirstIterationFlag )
202 myFirstIterationFlag =
false;
219 const 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( (
static_cast<double>( 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 qint64 myBinCount = binCount;
340 if ( myBinCount == 0 )
379 double minimum,
double maximum,
382 bool includeOutOfRange )
384 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
390 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
406 double minimum,
double maximum,
411 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
414 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
427 const int myBinCount = myHistogram.
binCount;
428 const int myWidth = myHistogram.
width;
429 const int myHeight = myHistogram.
height;
435 if ( myXBlockSize == 0 )
439 if ( myYBlockSize == 0 )
444 const int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
445 const int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
447 const double myXRes = myExtent.
width() / myWidth;
448 const double myYRes = myExtent.
height() / myHeight;
450 double myMinimum = myHistogram.
minimum;
451 double myMaximum = myHistogram.
maximum;
455 const double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
456 myMinimum -= 0.1 * myerval;
457 myMaximum += 0.1 * myerval;
459 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
461 const double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
464 bool isNoData =
false;
465 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
467 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
472 const int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
473 const int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
475 const double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
476 const double xmax = xmin + myBlockWidth * myXRes;
477 const double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
478 const double ymax = ymin - myBlockHeight * myYRes;
480 const QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
482 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
485 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
487 const double myValue = blk->valueAndNoData( i, isNoData );
493 int myBinIndex =
static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
495 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
499 if ( myBinIndex < 0 ) myBinIndex = 0;
500 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
508 myHistogram.
valid =
true;
513 for ( std::size_t i = 0; i < std::min< std::size_t >( myHistogram.
histogramVector.size(), 500 ); i++ )
515 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
517 QgsDebugMsgLevel( QStringLiteral(
"Histogram (max first 500 bins): " ) + hist, 4 );
524 double lowerCount,
double upperCount,
525 double &lowerValue,
double &upperValue,
529 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
534 lowerValue = std::numeric_limits<double>::quiet_NaN();
535 upperValue = std::numeric_limits<double>::quiet_NaN();
549 const int myMinCount =
static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
550 const int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
551 bool myLowerFound =
false;
552 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
553 QgsDebugMsgLevel( QStringLiteral(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
555 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
558 myCount += myBinValue;
559 if ( !myLowerFound && myCount > myMinCount )
561 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
563 QgsDebugMsgLevel( QStringLiteral(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
565 if ( myCount >= myMaxCount )
567 upperValue = myHistogram.
minimum + myBin * myBinXStep;
568 QgsDebugMsgLevel( QStringLiteral(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
578 if ( !std::isnan( lowerValue ) )
579 lowerValue = std::floor( lowerValue );
580 if ( !std::isnan( upperValue ) )
581 upperValue = std::ceil( upperValue );
587 QStringList abilitiesList;
597 abilitiesList += tr(
"Identify" );
602 abilitiesList += tr(
"Create Datasources" );
607 abilitiesList += tr(
"Remove Datasources" );
612 abilitiesList += tr(
"Build Pyramids" );
615 QgsDebugMsgLevel(
"Capability: " + abilitiesList.join( QLatin1String(
", " ) ), 4 );
617 return abilitiesList.join( QLatin1String(
", " ) );
625 return tr(
"Band" ) + QStringLiteral(
" %1" ) .arg( bandNumber, 1 +
static_cast< int >( std::log10(
static_cast< double >(
bandCount() ) ) ), 10, QChar(
'0' ) );
640 if ( colorInterp != QLatin1String(
"Undefined" ) )
642 name.append( QStringLiteral(
" (%1)" ).arg( colorInterp ) );
649 return mRenderContext;