QGIS API Documentation  2.99.0-Master (19b062c)
qgsrasterinterface.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterface.cpp - Internal raster processing modules interface
3  --------------------------------------
4  Date : Jun 21, 2012
5  Copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <limits>
19 #include <typeinfo>
20 
21 #include <QByteArray>
22 #include <QTime>
23 #include <QStringList>
24 
25 #include "qgslogger.h"
26 #include "qgsrasterbandstats.h"
27 #include "qgsrasterhistogram.h"
28 #include "qgsrasterinterface.h"
29 #include "qgsrectangle.h"
30 
32  : mInput( input )
33 {
34 }
35 
37  int bandNo,
38  int stats,
39  const QgsRectangle &boundingBox,
40  int sampleSize )
41 {
42  QgsDebugMsgLevel( QString( "theBandNo = %1 sampleSize = %2" ).arg( bandNo ).arg( sampleSize ), 4 );
43 
44  statistics.bandNumber = bandNo;
45  statistics.statsGathered = stats;
46 
47  QgsRectangle finalExtent;
48  if ( boundingBox.isEmpty() )
49  {
50  finalExtent = extent();
51  }
52  else
53  {
54  finalExtent = extent().intersect( &boundingBox );
55  }
56  statistics.extent = finalExtent;
57 
58  if ( sampleSize > 0 )
59  {
60  // Calc resolution from theSampleSize
61  double xRes, yRes;
62  xRes = yRes = std::sqrt( ( finalExtent.width() * finalExtent.height() ) / sampleSize );
63 
64  // But limit by physical resolution
65  if ( capabilities() & Size )
66  {
67  double srcXRes = extent().width() / xSize();
68  double srcYRes = extent().height() / ySize();
69  if ( xRes < srcXRes ) xRes = srcXRes;
70  if ( yRes < srcYRes ) yRes = srcYRes;
71  }
72  QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
73 
74  statistics.width = static_cast <int>( finalExtent.width() / xRes );
75  statistics.height = static_cast <int>( finalExtent.height() / yRes );
76  }
77  else
78  {
79  if ( capabilities() & Size )
80  {
81  statistics.width = xSize();
82  statistics.height = ySize();
83  }
84  else
85  {
86  statistics.width = 1000;
87  statistics.height = 1000;
88  }
89  }
90  QgsDebugMsgLevel( QString( "theStatistics.width = %1 statistics.height = %2" ).arg( statistics.width ).arg( statistics.height ), 4 );
91 }
92 
94  int stats,
95  const QgsRectangle &extent,
96  int sampleSize )
97 {
98  QgsDebugMsgLevel( QString( "theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
99  if ( mStatistics.isEmpty() ) return false;
100 
101  QgsRasterBandStats myRasterBandStats;
102  initStatistics( myRasterBandStats, bandNo, stats, extent, sampleSize );
103 
104  Q_FOREACH ( const QgsRasterBandStats &stats, mStatistics )
105  {
106  if ( stats.contains( myRasterBandStats ) )
107  {
108  QgsDebugMsgLevel( "Has cached statistics.", 4 );
109  return true;
110  }
111  }
112  return false;
113 }
114 
116  int stats,
117  const QgsRectangle &extent,
118  int sampleSize, QgsRasterBlockFeedback *feedback )
119 {
120  QgsDebugMsgLevel( QString( "theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
121 
122  // TODO: null values set on raster layer!!!
123 
124  QgsRasterBandStats myRasterBandStats;
125  initStatistics( myRasterBandStats, bandNo, stats, extent, sampleSize );
126 
127  Q_FOREACH ( const QgsRasterBandStats &stats, mStatistics )
128  {
129  if ( stats.contains( myRasterBandStats ) )
130  {
131  QgsDebugMsgLevel( "Using cached statistics.", 4 );
132  return stats;
133  }
134  }
135 
136  QgsRectangle myExtent = myRasterBandStats.extent;
137  int myWidth = myRasterBandStats.width;
138  int myHeight = myRasterBandStats.height;
139 
140  //int myDataType = dataType( bandNo );
141 
142  int myXBlockSize = xBlockSize();
143  int myYBlockSize = yBlockSize();
144  if ( myXBlockSize == 0 ) // should not happen, but happens
145  {
146  myXBlockSize = 500;
147  }
148  if ( myYBlockSize == 0 ) // should not happen, but happens
149  {
150  myYBlockSize = 500;
151  }
152 
153  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
154  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
155 
156  double myXRes = myExtent.width() / myWidth;
157  double myYRes = myExtent.height() / myHeight;
158  // TODO: progress signals
159 
160  // used by single pass stdev
161  double myMean = 0;
162  double mySumOfSquares = 0;
163 
164  bool myFirstIterationFlag = true;
165  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
166  {
167  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
168  {
169  if ( feedback && feedback->isCanceled() )
170  return myRasterBandStats;
171 
172  QgsDebugMsgLevel( QString( "myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
173  int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
174  int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
175 
176  double xmin = myExtent.xMinimum() + myXBlock * myXBlockSize * myXRes;
177  double xmax = xmin + myBlockWidth * myXRes;
178  double ymin = myExtent.yMaximum() - myYBlock * myYBlockSize * myYRes;
179  double ymax = ymin - myBlockHeight * myYRes;
180 
181  QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
182 
183  QgsRasterBlock *blk = block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback );
184 
185  // Collect the histogram counts.
186  for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
187  {
188  if ( blk->isNoData( i ) ) continue; // NULL
189 
190  double myValue = blk->value( i );
191 
192  myRasterBandStats.sum += myValue;
193  myRasterBandStats.elementCount++;
194 
195  if ( myFirstIterationFlag )
196  {
197  myFirstIterationFlag = false;
198  myRasterBandStats.minimumValue = myValue;
199  myRasterBandStats.maximumValue = myValue;
200  }
201  else
202  {
203  if ( myValue < myRasterBandStats.minimumValue )
204  {
205  myRasterBandStats.minimumValue = myValue;
206  }
207  if ( myValue > myRasterBandStats.maximumValue )
208  {
209  myRasterBandStats.maximumValue = myValue;
210  }
211  }
212 
213  // Single pass stdev
214  double myDelta = myValue - myMean;
215  myMean += myDelta / myRasterBandStats.elementCount;
216  mySumOfSquares += myDelta * ( myValue - myMean );
217  }
218  delete blk;
219  }
220  }
221 
222  myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
223  myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;
224 
225  myRasterBandStats.sumOfSquares = mySumOfSquares; // OK with single pass?
226 
227  // stdDev may differ from GDAL stats, because GDAL is using naive single pass
228  // algorithm which is more error prone (because of rounding errors)
229  // Divide result by sample size - 1 and get square root to get stdev
230  myRasterBandStats.stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.elementCount - 1 ) );
231 
232  QgsDebugMsgLevel( "************ STATS **************", 4 );
233  QgsDebugMsgLevel( QString( "MIN %1" ).arg( myRasterBandStats.minimumValue ), 4 );
234  QgsDebugMsgLevel( QString( "MAX %1" ).arg( myRasterBandStats.maximumValue ), 4 );
235  QgsDebugMsgLevel( QString( "RANGE %1" ).arg( myRasterBandStats.range ), 4 );
236  QgsDebugMsgLevel( QString( "MEAN %1" ).arg( myRasterBandStats.mean ), 4 );
237  QgsDebugMsgLevel( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ), 4 );
238 
239  myRasterBandStats.statsGathered = QgsRasterBandStats::All;
240  mStatistics.append( myRasterBandStats );
241 
242  return myRasterBandStats;
243 }
244 
246  int bandNo,
247  int binCount,
248  double minimum, double maximum,
249  const QgsRectangle &boundingBox,
250  int sampleSize,
251  bool includeOutOfRange )
252 {
253  histogram.bandNumber = bandNo;
254  histogram.minimum = minimum;
255  histogram.maximum = maximum;
256  histogram.includeOutOfRange = includeOutOfRange;
257 
258  int mySrcDataType = sourceDataType( bandNo );
259 
260  if ( std::isnan( histogram.minimum ) )
261  {
262  // TODO: this was OK when stats/histogram were calced in provider,
263  // but what TODO in other interfaces? Check for mInput for now.
264  if ( !mInput && mySrcDataType == Qgis::Byte )
265  {
266  histogram.minimum = 0; // see histogram() for shift for rounding
267  }
268  else
269  {
270  // We need statistics -> avoid histogramDefaults in hasHistogram if possible
271  // TODO: use approximated statistics if approximated histogram is requested
272  // (theSampleSize > 0)
273  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Min, boundingBox, sampleSize );
274  histogram.minimum = stats.minimumValue;
275  }
276  }
277  if ( std::isnan( histogram.maximum ) )
278  {
279  if ( !mInput && mySrcDataType == Qgis::Byte )
280  {
281  histogram.maximum = 255;
282  }
283  else
284  {
285  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Max, boundingBox, sampleSize );
286  histogram.maximum = stats.maximumValue;
287  }
288  }
289 
290  QgsRectangle finalExtent;
291  if ( boundingBox.isEmpty() )
292  {
293  finalExtent = extent();
294  }
295  else
296  {
297  finalExtent = extent().intersect( &boundingBox );
298  }
299  histogram.extent = finalExtent;
300 
301  if ( sampleSize > 0 )
302  {
303  // Calc resolution from theSampleSize
304  double xRes, yRes;
305  xRes = yRes = std::sqrt( ( finalExtent.width() * finalExtent.height() ) / sampleSize );
306 
307  // But limit by physical resolution
308  if ( capabilities() & Size )
309  {
310  double srcXRes = extent().width() / xSize();
311  double srcYRes = extent().height() / ySize();
312  if ( xRes < srcXRes ) xRes = srcXRes;
313  if ( yRes < srcYRes ) yRes = srcYRes;
314  }
315  QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
316 
317  histogram.width = static_cast <int>( finalExtent.width() / xRes );
318  histogram.height = static_cast <int>( finalExtent.height() / yRes );
319  }
320  else
321  {
322  if ( capabilities() & Size )
323  {
324  histogram.width = xSize();
325  histogram.height = ySize();
326  }
327  else
328  {
329  histogram.width = 1000;
330  histogram.height = 1000;
331  }
332  }
333  QgsDebugMsgLevel( QString( "theHistogram.width = %1 histogram.height = %2" ).arg( histogram.width ).arg( histogram.height ), 4 );
334 
335  int myBinCount = binCount;
336  if ( myBinCount == 0 )
337  {
338  // TODO: this was OK when stats/histogram were calced in provider,
339  // but what TODO in other interfaces? Check for mInput for now.
340  if ( !mInput && mySrcDataType == Qgis::Byte )
341  {
342  myBinCount = 256; // Cannot store more values in byte
343  }
344  else
345  {
346  // 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;
347  myBinCount = histogram.width * histogram.height;
348  if ( myBinCount > 1000 ) myBinCount = 1000;
349 
350  // for Int16/Int32 make sure bin count <= actual range, because there is no sense in having
351  // bins at fractional values
352  if ( !mInput && (
353  mySrcDataType == Qgis::Int16 || mySrcDataType == Qgis::Int32 ||
354  mySrcDataType == Qgis::UInt16 || mySrcDataType == Qgis::UInt32 ) )
355  {
356  if ( myBinCount > histogram.maximum - histogram.minimum + 1 )
357  myBinCount = int( std::ceil( histogram.maximum - histogram.minimum + 1 ) );
358  }
359  }
360  }
361  histogram.binCount = myBinCount;
362  QgsDebugMsgLevel( QString( "theHistogram.binCount = %1" ).arg( histogram.binCount ), 4 );
363 }
364 
365 
367  int binCount,
368  double minimum, double maximum,
369  const QgsRectangle &extent,
370  int sampleSize,
371  bool includeOutOfRange )
372 {
373  QgsDebugMsgLevel( QString( "theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
374  // histogramDefaults() needs statistics if minimum or maximum is NaN ->
375  // do other checks which don't need statistics before histogramDefaults()
376  if ( mHistograms.isEmpty() ) return false;
377 
378  QgsRasterHistogram myHistogram;
379  initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
380 
381  Q_FOREACH ( const QgsRasterHistogram &histogram, mHistograms )
382  {
383  if ( histogram == myHistogram )
384  {
385  QgsDebugMsgLevel( "Has cached histogram.", 4 );
386  return true;
387  }
388  }
389  return false;
390 }
391 
393  int binCount,
394  double minimum, double maximum,
395  const QgsRectangle &extent,
396  int sampleSize,
397  bool includeOutOfRange, QgsRasterBlockFeedback *feedback )
398 {
399  QgsDebugMsgLevel( QString( "theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
400 
401  QgsRasterHistogram myHistogram;
402  initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
403 
404  // Find cached
405  Q_FOREACH ( const QgsRasterHistogram &histogram, mHistograms )
406  {
407  if ( histogram == myHistogram )
408  {
409  QgsDebugMsgLevel( "Using cached histogram.", 4 );
410  return histogram;
411  }
412  }
413 
414  int myBinCount = myHistogram.binCount;
415  int myWidth = myHistogram.width;
416  int myHeight = myHistogram.height;
417  QgsRectangle myExtent = myHistogram.extent;
418  myHistogram.histogramVector.resize( myBinCount );
419 
420  int myXBlockSize = xBlockSize();
421  int myYBlockSize = yBlockSize();
422  if ( myXBlockSize == 0 ) // should not happen, but happens
423  {
424  myXBlockSize = 500;
425  }
426  if ( myYBlockSize == 0 ) // should not happen, but happens
427  {
428  myYBlockSize = 500;
429  }
430 
431  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
432  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
433 
434  double myXRes = myExtent.width() / myWidth;
435  double myYRes = myExtent.height() / myHeight;
436 
437  double myMinimum = myHistogram.minimum;
438  double myMaximum = myHistogram.maximum;
439 
440  // To avoid rounding errors
441  // TODO: check this
442  double myerval = ( myMaximum - myMinimum ) / myHistogram.binCount;
443  myMinimum -= 0.1 * myerval;
444  myMaximum += 0.1 * myerval;
445 
446  QgsDebugMsgLevel( QString( "binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
447 
448  double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
449 
450  // TODO: progress signals
451  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
452  {
453  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
454  {
455  if ( feedback && feedback->isCanceled() )
456  return myHistogram;
457 
458  int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
459  int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
460 
461  double xmin = myExtent.xMinimum() + myXBlock * myXBlockSize * myXRes;
462  double xmax = xmin + myBlockWidth * myXRes;
463  double ymin = myExtent.yMaximum() - myYBlock * myYBlockSize * myYRes;
464  double ymax = ymin - myBlockHeight * myYRes;
465 
466  QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
467 
468  QgsRasterBlock *blk = block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback );
469 
470  // Collect the histogram counts.
471  for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
472  {
473  if ( blk->isNoData( i ) )
474  {
475  continue; // NULL
476  }
477  double myValue = blk->value( i );
478 
479  int myBinIndex = static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
480 
481  if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
482  {
483  continue;
484  }
485  if ( myBinIndex < 0 ) myBinIndex = 0;
486  if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
487 
488  myHistogram.histogramVector[myBinIndex] += 1;
489  myHistogram.nonNullCount++;
490  }
491  delete blk;
492  }
493  }
494 
495  myHistogram.valid = true;
496  mHistograms.append( myHistogram );
497 
498 #ifdef QGISDEBUG
499  QString hist;
500  for ( int i = 0; i < std::min( myHistogram.histogramVector.size(), 500 ); i++ )
501  {
502  hist += QString::number( myHistogram.histogramVector.value( i ) ) + ' ';
503  }
504  QgsDebugMsgLevel( "Histogram (max first 500 bins): " + hist, 4 );
505 #endif
506 
507  return myHistogram;
508 }
509 
511  double lowerCount, double upperCount,
512  double &lowerValue, double &upperValue,
513  const QgsRectangle &extent,
514  int sampleSize )
515 {
516  QgsDebugMsgLevel( QString( "theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
517 
518  int mySrcDataType = sourceDataType( bandNo );
519 
520  // Init to NaN is better than histogram min/max to catch errors
521  lowerValue = std::numeric_limits<double>::quiet_NaN();
522  upperValue = std::numeric_limits<double>::quiet_NaN();
523 
524  //get band stats to specify real histogram min/max (fix #9793 Byte bands)
525  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Min, extent, sampleSize );
526  if ( stats.maximumValue < stats.minimumValue )
527  return;
528 
529  // for byte bands make sure bin count == actual range
530  int myBinCount = ( mySrcDataType == Qgis::Byte ) ? int( std::ceil( stats.maximumValue - stats.minimumValue + 1 ) ) : 0;
531  QgsRasterHistogram myHistogram = histogram( bandNo, myBinCount, stats.minimumValue, stats.maximumValue, extent, sampleSize );
532  //QgsRasterHistogram myHistogram = histogram( bandNo, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), extent, sampleSize );
533 
534  double myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
535  int myCount = 0;
536  int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.nonNullCount ) );
537  int myMaxCount = static_cast< int >( std::round( upperCount * myHistogram.nonNullCount ) );
538  bool myLowerFound = false;
539  QgsDebugMsgLevel( QString( "binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.binCount ).arg( myHistogram.minimum ).arg( myHistogram.maximum ).arg( myBinXStep ), 4 );
540  QgsDebugMsgLevel( QString( "myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
541 
542  for ( int myBin = 0; myBin < myHistogram.histogramVector.size(); myBin++ )
543  {
544  int myBinValue = myHistogram.histogramVector.value( myBin );
545  myCount += myBinValue;
546  if ( !myLowerFound && myCount > myMinCount )
547  {
548  lowerValue = myHistogram.minimum + myBin * myBinXStep;
549  myLowerFound = true;
550  QgsDebugMsgLevel( QString( "found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
551  }
552  if ( myCount >= myMaxCount )
553  {
554  upperValue = myHistogram.minimum + myBin * myBinXStep;
555  QgsDebugMsgLevel( QString( "found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
556  break;
557  }
558  }
559 
560  // fix integer data - round down/up
561  if ( mySrcDataType == Qgis::Byte ||
562  mySrcDataType == Qgis::Int16 || mySrcDataType == Qgis::Int32 ||
563  mySrcDataType == Qgis::UInt16 || mySrcDataType == Qgis::UInt32 )
564  {
565  if ( lowerValue != std::numeric_limits<double>::quiet_NaN() )
566  lowerValue = std::floor( lowerValue );
567  if ( upperValue != std::numeric_limits<double>::quiet_NaN() )
568  upperValue = std::ceil( upperValue );
569  }
570 }
571 
573 {
574  QStringList abilitiesList;
575 
576  int abilities = capabilities();
577 
578  // Not all all capabilities are here (Size, IdentifyValue, IdentifyText,
579  // IdentifyHtml, IdentifyFeature) because those are quite technical and probably
580  // would be confusing for users
581 
582  if ( abilities & QgsRasterInterface::Identify )
583  {
584  abilitiesList += tr( "Identify" );
585  }
586 
587  if ( abilities & QgsRasterInterface::Create )
588  {
589  abilitiesList += tr( "Create Datasources" );
590  }
591 
592  if ( abilities & QgsRasterInterface::Remove )
593  {
594  abilitiesList += tr( "Remove Datasources" );
595  }
596 
597  if ( abilities & QgsRasterInterface::BuildPyramids )
598  {
599  abilitiesList += tr( "Build Pyramids" );
600  }
601 
602  QgsDebugMsgLevel( "Capability: " + abilitiesList.join( ", " ), 4 );
603 
604  return abilitiesList.join( QStringLiteral( ", " ) );
605 }
A rectangle specified with double values.
Definition: qgsrectangle.h:39
Thirty two bit signed integer (qint32)
Definition: qgis.h:85
virtual bool hasHistogram(int bandNo, int binCount, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false)
Returns true if histogram is available (cached, already calculated)
double sum
The sum of all cells in the band. NO_DATA values are excluded.
virtual QgsRectangle extent() const
Get the extent of the interface.
int bandNumber
The gdal band number (starts at 1)
int width
Number of columns used to calc histogram.
int height
Number of rows used to calc statistics.
int bandNumber
The gdal band number (starts at 1)
double minimum
The minimum histogram value.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:84
double maximumValue
The maximum cell value in the raster band.
virtual int ySize() const
QgsRectangle intersect(const QgsRectangle *rect) const
Return the intersection with the given rectangle.
int height
Number of rows used to calc histogram.
virtual QgsRasterHistogram histogram(int bandNo, int binCount=0, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false, QgsRasterBlockFeedback *feedback=nullptr)
Get histogram.
virtual void cumulativeCut(int bandNo, double lowerCount, double upperCount, double &lowerValue, double &upperValue, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Find values for cumulative pixel count cut.
Sixteen bit signed integer (qint16)
Definition: qgis.h:83
bool isNoData(int row, int column)
Check if value at position is no data.
bool contains(const QgsRasterBandStats &s) const
Compares region, size etc. not collected statistics.
virtual int xBlockSize() const
Get block size.
QgsRectangle extent
Extent used to calc statistics.
double stdDev
The standard deviation of the cell values.
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
void initStatistics(QgsRasterBandStats &statistics, int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &boundingBox=QgsRectangle(), int binCount=0)
Fill in statistics defaults if not specified.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:38
bool isEmpty() const
Returns true if the rectangle is empty.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:138
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
qgssize elementCount
The number of not no data cells in the band.
virtual bool hasStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Returns true if histogram is available (cached, already calculated).
int statsGathered
Collected statistics.
QString capabilitiesString() const
Returns the above in friendly format.
QgsRasterHistogram::HistogramVector histogramVector
Store the histogram for a given layer.
virtual Qgis::DataType sourceDataType(int bandNo) const
Returns source data type for the band specified by number, source data type may be shorter than dataT...
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:82
Base class for processing filters like renderers, reprojector, resampler etc.
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
Definition: qgis.h:452
double maximum
The maximum histogram value.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Get band statistics.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
virtual int yBlockSize() const
double range
The range is the distance between min & max.
double value(int row, int column) const
Read a single value if type of block is numeric.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:116
double minimumValue
The minimum cell value in the raster band.
The QgsRasterHistogram is a container for histogram of a single raster band.
int binCount
Number of bins (intervals,buckets) in histogram.
void initHistogram(QgsRasterHistogram &histogram, int bandNo, int binCount, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &boundingBox=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false)
Fill in histogram defaults if not specified.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:121
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
bool valid
Histogram is valid.
QgsRasterInterface * mInput
QgsRectangle extent
Extent used to calc histogram.
Feedback object tailored for raster block reading.
virtual int xSize() const
Get raster size.
Eight bit unsigned integer (quint8)
Definition: qgis.h:81
bool includeOutOfRange
Whether histogram includes out of range values (in first and last bin)
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:145
double sumOfSquares
The sum of the squares. Used to calculate standard deviation.
int width
Number of columns used to calc statistics.
int nonNullCount
The number of non NULL cells used to calculate histogram.