QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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  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( QStringLiteral( "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  std::unique_ptr< 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  }
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( QStringLiteral( "************ STATS **************" ), 4 );
233  QgsDebugMsgLevel( QStringLiteral( "MIN %1" ).arg( myRasterBandStats.minimumValue ), 4 );
234  QgsDebugMsgLevel( QStringLiteral( "MAX %1" ).arg( myRasterBandStats.maximumValue ), 4 );
235  QgsDebugMsgLevel( QStringLiteral( "RANGE %1" ).arg( myRasterBandStats.range ), 4 );
236  QgsDebugMsgLevel( QStringLiteral( "MEAN %1" ).arg( myRasterBandStats.mean ), 4 );
237  QgsDebugMsgLevel( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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( QStringLiteral( "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  std::unique_ptr< 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  }
492  }
493 
494  myHistogram.valid = true;
495  mHistograms.append( myHistogram );
496 
497 #ifdef QGISDEBUG
498  QString hist;
499  for ( int i = 0; i < std::min( myHistogram.histogramVector.size(), 500 ); i++ )
500  {
501  hist += QString::number( myHistogram.histogramVector.value( i ) ) + ' ';
502  }
503  QgsDebugMsgLevel( QStringLiteral( "Histogram (max first 500 bins): " ) + hist, 4 );
504 #endif
505 
506  return myHistogram;
507 }
508 
510  double lowerCount, double upperCount,
511  double &lowerValue, double &upperValue,
512  const QgsRectangle &extent,
513  int sampleSize )
514 {
515  QgsDebugMsgLevel( QStringLiteral( "theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
516 
517  int mySrcDataType = sourceDataType( bandNo );
518 
519  // Init to NaN is better than histogram min/max to catch errors
520  lowerValue = std::numeric_limits<double>::quiet_NaN();
521  upperValue = std::numeric_limits<double>::quiet_NaN();
522 
523  //get band stats to specify real histogram min/max (fix #9793 Byte bands)
524  QgsRasterBandStats stats = bandStatistics( bandNo, QgsRasterBandStats::Min, extent, sampleSize );
525  if ( stats.maximumValue < stats.minimumValue )
526  return;
527 
528  // for byte bands make sure bin count == actual range
529  int myBinCount = ( mySrcDataType == Qgis::Byte ) ? int( std::ceil( stats.maximumValue - stats.minimumValue + 1 ) ) : 0;
530  QgsRasterHistogram myHistogram = histogram( bandNo, myBinCount, stats.minimumValue, stats.maximumValue, extent, sampleSize );
531  //QgsRasterHistogram myHistogram = histogram( bandNo, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), extent, sampleSize );
532 
533  double myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
534  int myCount = 0;
535  int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.nonNullCount ) );
536  int myMaxCount = static_cast< int >( std::round( upperCount * myHistogram.nonNullCount ) );
537  bool myLowerFound = false;
538  QgsDebugMsgLevel( QStringLiteral( "binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.binCount ).arg( myHistogram.minimum ).arg( myHistogram.maximum ).arg( myBinXStep ), 4 );
539  QgsDebugMsgLevel( QStringLiteral( "myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
540 
541  for ( int myBin = 0; myBin < myHistogram.histogramVector.size(); myBin++ )
542  {
543  int myBinValue = myHistogram.histogramVector.value( myBin );
544  myCount += myBinValue;
545  if ( !myLowerFound && myCount > myMinCount )
546  {
547  lowerValue = myHistogram.minimum + myBin * myBinXStep;
548  myLowerFound = true;
549  QgsDebugMsgLevel( QStringLiteral( "found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
550  }
551  if ( myCount >= myMaxCount )
552  {
553  upperValue = myHistogram.minimum + myBin * myBinXStep;
554  QgsDebugMsgLevel( QStringLiteral( "found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
555  break;
556  }
557  }
558 
559  // fix integer data - round down/up
560  if ( mySrcDataType == Qgis::Byte ||
561  mySrcDataType == Qgis::Int16 || mySrcDataType == Qgis::Int32 ||
562  mySrcDataType == Qgis::UInt16 || mySrcDataType == Qgis::UInt32 )
563  {
564  if ( !std::isnan( lowerValue ) )
565  lowerValue = std::floor( lowerValue );
566  if ( !std::isnan( upperValue ) )
567  upperValue = std::ceil( upperValue );
568  }
569 }
570 
572 {
573  QStringList abilitiesList;
574 
575  int abilities = capabilities();
576 
577  // Not all all capabilities are here (Size, IdentifyValue, IdentifyText,
578  // IdentifyHtml, IdentifyFeature) because those are quite technical and probably
579  // would be confusing for users
580 
581  if ( abilities & QgsRasterInterface::Identify )
582  {
583  abilitiesList += tr( "Identify" );
584  }
585 
586  if ( abilities & QgsRasterInterface::Create )
587  {
588  abilitiesList += tr( "Create Datasources" );
589  }
590 
591  if ( abilities & QgsRasterInterface::Remove )
592  {
593  abilitiesList += tr( "Remove Datasources" );
594  }
595 
596  if ( abilities & QgsRasterInterface::BuildPyramids )
597  {
598  abilitiesList += tr( "Build Pyramids" );
599  }
600 
601  QgsDebugMsgLevel( "Capability: " + abilitiesList.join( QStringLiteral( ", " ) ), 4 );
602 
603  return abilitiesList.join( QStringLiteral( ", " ) );
604 }
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
A rectangle specified with double values.
Definition: qgsrectangle.h:40
Thirty two bit signed integer (qint32)
Definition: qgis.h:99
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:425
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.
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.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:171
int bandNumber
The gdal band number (starts at 1)
virtual int xBlockSize() const
Gets block size.
double minimum
The minimum histogram value.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:98
virtual int yBlockSize() const
double maximumValue
The maximum cell value in the raster band.
QString capabilitiesString() const
Returns the above in friendly format.
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:97
virtual int ySize() const
bool contains(const QgsRasterBandStats &s) const
Compares region, size etc. not collected statistics.
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...
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
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.
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.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:96
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:586
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:311
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
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.
virtual int xSize() const
Gets raster size.
virtual QgsRectangle extent() const
Gets the extent of the interface.
double range
The range is the distance between min & max.
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.
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
bool valid
Histogram is valid.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:201
QgsRasterInterface * mInput
QgsRectangle extent
Extent used to calc histogram.
Feedback object tailored for raster block reading.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:166
Eight bit unsigned integer (quint8)
Definition: qgis.h:95
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.