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