QGIS API Documentation  3.2.0-Bonn (bc43194)
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  myRasterBandStats.sum += myValue;
192  myRasterBandStats.elementCount++;
193 
194  if ( !std::isfinite( myValue ) ) continue; // inf
195 
196  if ( myFirstIterationFlag )
197  {
198  myFirstIterationFlag = false;
199  myRasterBandStats.minimumValue = myValue;
200  myRasterBandStats.maximumValue = myValue;
201  }
202  else
203  {
204  if ( myValue < myRasterBandStats.minimumValue )
205  {
206  myRasterBandStats.minimumValue = myValue;
207  }
208  if ( myValue > myRasterBandStats.maximumValue )
209  {
210  myRasterBandStats.maximumValue = myValue;
211  }
212  }
213 
214  // Single pass stdev
215  double myDelta = myValue - myMean;
216  myMean += myDelta / myRasterBandStats.elementCount;
217  mySumOfSquares += myDelta * ( myValue - myMean );
218  }
219  delete blk;
220  }
221  }
222 
223  myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
224  myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;
225 
226  myRasterBandStats.sumOfSquares = mySumOfSquares; // OK with single pass?
227 
228  // stdDev may differ from GDAL stats, because GDAL is using naive single pass
229  // algorithm which is more error prone (because of rounding errors)
230  // Divide result by sample size - 1 and get square root to get stdev
231  myRasterBandStats.stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.elementCount - 1 ) );
232 
233  QgsDebugMsgLevel( "************ STATS **************", 4 );
234  QgsDebugMsgLevel( QString( "MIN %1" ).arg( myRasterBandStats.minimumValue ), 4 );
235  QgsDebugMsgLevel( QString( "MAX %1" ).arg( myRasterBandStats.maximumValue ), 4 );
236  QgsDebugMsgLevel( QString( "RANGE %1" ).arg( myRasterBandStats.range ), 4 );
237  QgsDebugMsgLevel( QString( "MEAN %1" ).arg( myRasterBandStats.mean ), 4 );
238  QgsDebugMsgLevel( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ), 4 );
239 
240  myRasterBandStats.statsGathered = QgsRasterBandStats::All;
241  mStatistics.append( myRasterBandStats );
242 
243  return myRasterBandStats;
244 }
245 
247  int bandNo,
248  int binCount,
249  double minimum, double maximum,
250  const QgsRectangle &boundingBox,
251  int sampleSize,
252  bool includeOutOfRange )
253 {
254  histogram.bandNumber = bandNo;
255  histogram.minimum = minimum;
256  histogram.maximum = maximum;
257  histogram.includeOutOfRange = includeOutOfRange;
258 
259  int mySrcDataType = sourceDataType( bandNo );
260 
261  if ( std::isnan( histogram.minimum ) )
262  {
263  // TODO: this was OK when stats/histogram were calced in provider,
264  // but what TODO in other interfaces? Check for mInput for now.
265  if ( !mInput && mySrcDataType == Qgis::Byte )
266  {
267  histogram.minimum = 0; // see histogram() for shift for rounding
268  }
269  else
270  {
271  // We need statistics -> avoid histogramDefaults in hasHistogram if possible
272  // TODO: use approximated statistics if approximated histogram is requested
273  // (theSampleSize > 0)
274  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Min, boundingBox, sampleSize );
275  histogram.minimum = stats.minimumValue;
276  }
277  }
278  if ( std::isnan( histogram.maximum ) )
279  {
280  if ( !mInput && mySrcDataType == Qgis::Byte )
281  {
282  histogram.maximum = 255;
283  }
284  else
285  {
286  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Max, boundingBox, sampleSize );
287  histogram.maximum = stats.maximumValue;
288  }
289  }
290 
291  QgsRectangle finalExtent;
292  if ( boundingBox.isEmpty() )
293  {
294  finalExtent = extent();
295  }
296  else
297  {
298  finalExtent = extent().intersect( boundingBox );
299  }
300  histogram.extent = finalExtent;
301 
302  if ( sampleSize > 0 )
303  {
304  // Calc resolution from theSampleSize
305  double xRes, yRes;
306  xRes = yRes = std::sqrt( ( finalExtent.width() * finalExtent.height() ) / sampleSize );
307 
308  // But limit by physical resolution
309  if ( capabilities() & Size )
310  {
311  double srcXRes = extent().width() / xSize();
312  double srcYRes = extent().height() / ySize();
313  if ( xRes < srcXRes ) xRes = srcXRes;
314  if ( yRes < srcYRes ) yRes = srcYRes;
315  }
316  QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
317 
318  histogram.width = static_cast <int>( finalExtent.width() / xRes );
319  histogram.height = static_cast <int>( finalExtent.height() / yRes );
320  }
321  else
322  {
323  if ( capabilities() & Size )
324  {
325  histogram.width = xSize();
326  histogram.height = ySize();
327  }
328  else
329  {
330  histogram.width = 1000;
331  histogram.height = 1000;
332  }
333  }
334  QgsDebugMsgLevel( QString( "theHistogram.width = %1 histogram.height = %2" ).arg( histogram.width ).arg( histogram.height ), 4 );
335 
336  int myBinCount = binCount;
337  if ( myBinCount == 0 )
338  {
339  // TODO: this was OK when stats/histogram were calced in provider,
340  // but what TODO in other interfaces? Check for mInput for now.
341  if ( !mInput && mySrcDataType == Qgis::Byte )
342  {
343  myBinCount = 256; // Cannot store more values in byte
344  }
345  else
346  {
347  // 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;
348  myBinCount = histogram.width * histogram.height;
349  if ( myBinCount > 1000 ) myBinCount = 1000;
350 
351  // for Int16/Int32 make sure bin count <= actual range, because there is no sense in having
352  // bins at fractional values
353  if ( !mInput && (
354  mySrcDataType == Qgis::Int16 || mySrcDataType == Qgis::Int32 ||
355  mySrcDataType == Qgis::UInt16 || mySrcDataType == Qgis::UInt32 ) )
356  {
357  if ( myBinCount > histogram.maximum - histogram.minimum + 1 )
358  myBinCount = int( std::ceil( histogram.maximum - histogram.minimum + 1 ) );
359  }
360  }
361  }
362  histogram.binCount = myBinCount;
363  QgsDebugMsgLevel( QString( "theHistogram.binCount = %1" ).arg( histogram.binCount ), 4 );
364 }
365 
366 
368  int binCount,
369  double minimum, double maximum,
370  const QgsRectangle &extent,
371  int sampleSize,
372  bool includeOutOfRange )
373 {
374  QgsDebugMsgLevel( QString( "theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
375  // histogramDefaults() needs statistics if minimum or maximum is NaN ->
376  // do other checks which don't need statistics before histogramDefaults()
377  if ( mHistograms.isEmpty() ) return false;
378 
379  QgsRasterHistogram myHistogram;
380  initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
381 
382  Q_FOREACH ( const QgsRasterHistogram &histogram, mHistograms )
383  {
384  if ( histogram == myHistogram )
385  {
386  QgsDebugMsgLevel( "Has cached histogram.", 4 );
387  return true;
388  }
389  }
390  return false;
391 }
392 
394  int binCount,
395  double minimum, double maximum,
396  const QgsRectangle &extent,
397  int sampleSize,
398  bool includeOutOfRange, QgsRasterBlockFeedback *feedback )
399 {
400  QgsDebugMsgLevel( QString( "theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
401 
402  QgsRasterHistogram myHistogram;
403  initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
404 
405  // Find cached
406  Q_FOREACH ( const QgsRasterHistogram &histogram, mHistograms )
407  {
408  if ( histogram == myHistogram )
409  {
410  QgsDebugMsgLevel( "Using cached histogram.", 4 );
411  return histogram;
412  }
413  }
414 
415  int myBinCount = myHistogram.binCount;
416  int myWidth = myHistogram.width;
417  int myHeight = myHistogram.height;
418  QgsRectangle myExtent = myHistogram.extent;
419  myHistogram.histogramVector.resize( myBinCount );
420 
421  int myXBlockSize = xBlockSize();
422  int myYBlockSize = yBlockSize();
423  if ( myXBlockSize == 0 ) // should not happen, but happens
424  {
425  myXBlockSize = 500;
426  }
427  if ( myYBlockSize == 0 ) // should not happen, but happens
428  {
429  myYBlockSize = 500;
430  }
431 
432  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
433  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
434 
435  double myXRes = myExtent.width() / myWidth;
436  double myYRes = myExtent.height() / myHeight;
437 
438  double myMinimum = myHistogram.minimum;
439  double myMaximum = myHistogram.maximum;
440 
441  // To avoid rounding errors
442  // TODO: check this
443  double myerval = ( myMaximum - myMinimum ) / myHistogram.binCount;
444  myMinimum -= 0.1 * myerval;
445  myMaximum += 0.1 * myerval;
446 
447  QgsDebugMsgLevel( QString( "binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
448 
449  double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
450 
451  // TODO: progress signals
452  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
453  {
454  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
455  {
456  if ( feedback && feedback->isCanceled() )
457  return myHistogram;
458 
459  int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
460  int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
461 
462  double xmin = myExtent.xMinimum() + myXBlock * myXBlockSize * myXRes;
463  double xmax = xmin + myBlockWidth * myXRes;
464  double ymin = myExtent.yMaximum() - myYBlock * myYBlockSize * myYRes;
465  double ymax = ymin - myBlockHeight * myYRes;
466 
467  QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
468 
469  QgsRasterBlock *blk = block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback );
470 
471  // Collect the histogram counts.
472  for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
473  {
474  if ( blk->isNoData( i ) )
475  {
476  continue; // NULL
477  }
478  double myValue = blk->value( i );
479 
480  int myBinIndex = static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
481 
482  if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
483  {
484  continue;
485  }
486  if ( myBinIndex < 0 ) myBinIndex = 0;
487  if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
488 
489  myHistogram.histogramVector[myBinIndex] += 1;
490  myHistogram.nonNullCount++;
491  }
492  delete blk;
493  }
494  }
495 
496  myHistogram.valid = true;
497  mHistograms.append( myHistogram );
498 
499 #ifdef QGISDEBUG
500  QString hist;
501  for ( int i = 0; i < std::min( myHistogram.histogramVector.size(), 500 ); i++ )
502  {
503  hist += QString::number( myHistogram.histogramVector.value( i ) ) + ' ';
504  }
505  QgsDebugMsgLevel( "Histogram (max first 500 bins): " + hist, 4 );
506 #endif
507 
508  return myHistogram;
509 }
510 
512  double lowerCount, double upperCount,
513  double &lowerValue, double &upperValue,
514  const QgsRectangle &extent,
515  int sampleSize )
516 {
517  QgsDebugMsgLevel( QString( "theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
518 
519  int mySrcDataType = sourceDataType( bandNo );
520 
521  // Init to NaN is better than histogram min/max to catch errors
522  lowerValue = std::numeric_limits<double>::quiet_NaN();
523  upperValue = std::numeric_limits<double>::quiet_NaN();
524 
525  //get band stats to specify real histogram min/max (fix #9793 Byte bands)
526  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Min, extent, sampleSize );
527  if ( stats.maximumValue < stats.minimumValue )
528  return;
529 
530  // for byte bands make sure bin count == actual range
531  int myBinCount = ( mySrcDataType == Qgis::Byte ) ? int( std::ceil( stats.maximumValue - stats.minimumValue + 1 ) ) : 0;
532  QgsRasterHistogram myHistogram = histogram( bandNo, myBinCount, stats.minimumValue, stats.maximumValue, extent, sampleSize );
533  //QgsRasterHistogram myHistogram = histogram( bandNo, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), extent, sampleSize );
534 
535  double myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
536  int myCount = 0;
537  int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.nonNullCount ) );
538  int myMaxCount = static_cast< int >( std::round( upperCount * myHistogram.nonNullCount ) );
539  bool myLowerFound = false;
540  QgsDebugMsgLevel( QString( "binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.binCount ).arg( myHistogram.minimum ).arg( myHistogram.maximum ).arg( myBinXStep ), 4 );
541  QgsDebugMsgLevel( QString( "myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
542 
543  for ( int myBin = 0; myBin < myHistogram.histogramVector.size(); myBin++ )
544  {
545  int myBinValue = myHistogram.histogramVector.value( myBin );
546  myCount += myBinValue;
547  if ( !myLowerFound && myCount > myMinCount )
548  {
549  lowerValue = myHistogram.minimum + myBin * myBinXStep;
550  myLowerFound = true;
551  QgsDebugMsgLevel( QString( "found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
552  }
553  if ( myCount >= myMaxCount )
554  {
555  upperValue = myHistogram.minimum + myBin * myBinXStep;
556  QgsDebugMsgLevel( QString( "found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
557  break;
558  }
559  }
560 
561  // fix integer data - round down/up
562  if ( mySrcDataType == Qgis::Byte ||
563  mySrcDataType == Qgis::Int16 || mySrcDataType == Qgis::Int32 ||
564  mySrcDataType == Qgis::UInt16 || mySrcDataType == Qgis::UInt32 )
565  {
566  if ( lowerValue != std::numeric_limits<double>::quiet_NaN() )
567  lowerValue = std::floor( lowerValue );
568  if ( upperValue != std::numeric_limits<double>::quiet_NaN() )
569  upperValue = std::ceil( upperValue );
570  }
571 }
572 
574 {
575  QStringList abilitiesList;
576 
577  int abilities = capabilities();
578 
579  // Not all all capabilities are here (Size, IdentifyValue, IdentifyText,
580  // IdentifyHtml, IdentifyFeature) because those are quite technical and probably
581  // would be confusing for users
582 
583  if ( abilities & QgsRasterInterface::Identify )
584  {
585  abilitiesList += tr( "Identify" );
586  }
587 
588  if ( abilities & QgsRasterInterface::Create )
589  {
590  abilitiesList += tr( "Create Datasources" );
591  }
592 
593  if ( abilities & QgsRasterInterface::Remove )
594  {
595  abilitiesList += tr( "Remove Datasources" );
596  }
597 
598  if ( abilities & QgsRasterInterface::BuildPyramids )
599  {
600  abilitiesList += tr( "Build Pyramids" );
601  }
602 
603  QgsDebugMsgLevel( "Capability: " + abilitiesList.join( ", " ), 4 );
604 
605  return abilitiesList.join( QStringLiteral( ", " ) );
606 }
A rectangle specified with double values.
Definition: qgsrectangle.h:40
Thirty two bit signed integer (qint32)
Definition: qgis.h:98
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
Gets 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:97
double maximumValue
The maximum cell value in the raster band.
virtual int ySize() const
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)
Returns a band 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:96
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
Gets 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:39
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:419
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:201
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:305
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:95
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:510
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)
Returns the 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:166
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:171
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
Gets raster size.
Eight bit unsigned integer (quint8)
Definition: qgis.h:94
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:208
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.