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