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