QGIS API Documentation  2.99.0-Master (37c43df)
qgsrasterinterface.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterface.cpp - Internal raster processing modules interface
3  --------------------------------------
4  Date : Jun 21, 2012
5  Copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <limits>
19 #include <typeinfo>
20 
21 #include <QByteArray>
22 #include <QTime>
23 #include <QStringList>
24 
25 #include <qmath.h>
26 
27 #include "qgslogger.h"
28 #include "qgsrasterbandstats.h"
29 #include "qgsrasterhistogram.h"
30 #include "qgsrasterinterface.h"
31 #include "qgsrectangle.h"
32 
34  : mInput( input )
35  , mOn( true )
36 {
37 }
38 
40 {
41 }
42 
44  int theBandNo,
45  int theStats,
46  const QgsRectangle & theExtent,
47  int theSampleSize )
48 {
49  QgsDebugMsgLevel( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ), 4 );
50 
51  theStatistics.bandNumber = theBandNo;
52  theStatistics.statsGathered = theStats;
53 
54  QgsRectangle myExtent;
55  if ( theExtent.isEmpty() )
56  {
57  myExtent = extent();
58  }
59  else
60  {
61  myExtent = extent().intersect( &theExtent );
62  }
63  theStatistics.extent = myExtent;
64 
65  if ( theSampleSize > 0 )
66  {
67  // Calc resolution from theSampleSize
68  double xRes, yRes;
69  xRes = yRes = sqrt(( myExtent.width() * myExtent.height() ) / theSampleSize );
70 
71  // But limit by physical resolution
72  if ( capabilities() & Size )
73  {
74  double srcXRes = extent().width() / xSize();
75  double srcYRes = extent().height() / ySize();
76  if ( xRes < srcXRes ) xRes = srcXRes;
77  if ( yRes < srcYRes ) yRes = srcYRes;
78  }
79  QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
80 
81  theStatistics.width = static_cast <int>( myExtent.width() / xRes );
82  theStatistics.height = static_cast <int>( myExtent.height() / yRes );
83  }
84  else
85  {
86  if ( capabilities() & Size )
87  {
88  theStatistics.width = xSize();
89  theStatistics.height = ySize();
90  }
91  else
92  {
93  theStatistics.width = 1000;
94  theStatistics.height = 1000;
95  }
96  }
97  QgsDebugMsgLevel( QString( "theStatistics.width = %1 theStatistics.height = %2" ).arg( theStatistics.width ).arg( theStatistics.height ), 4 );
98 }
99 
101  int theStats,
102  const QgsRectangle & theExtent,
103  int theSampleSize )
104 {
105  QgsDebugMsgLevel( QString( "theBandNo = %1 theStats = %2 theSampleSize = %3" ).arg( theBandNo ).arg( theStats ).arg( theSampleSize ), 4 );
106  if ( mStatistics.isEmpty() ) return false;
107 
108  QgsRasterBandStats myRasterBandStats;
109  initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
110 
111  Q_FOREACH ( const QgsRasterBandStats& stats, mStatistics )
112  {
113  if ( stats.contains( myRasterBandStats ) )
114  {
115  QgsDebugMsgLevel( "Has cached statistics.", 4 );
116  return true;
117  }
118  }
119  return false;
120 }
121 
123  int theStats,
124  const QgsRectangle & theExtent,
125  int theSampleSize )
126 {
127  QgsDebugMsgLevel( QString( "theBandNo = %1 theStats = %2 theSampleSize = %3" ).arg( theBandNo ).arg( theStats ).arg( theSampleSize ), 4 );
128 
129  // TODO: null values set on raster layer!!!
130 
131  QgsRasterBandStats myRasterBandStats;
132  initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
133 
134  Q_FOREACH ( const QgsRasterBandStats& stats, mStatistics )
135  {
136  if ( stats.contains( myRasterBandStats ) )
137  {
138  QgsDebugMsgLevel( "Using cached statistics.", 4 );
139  return stats;
140  }
141  }
142 
143  QgsRectangle myExtent = myRasterBandStats.extent;
144  int myWidth = myRasterBandStats.width;
145  int myHeight = myRasterBandStats.height;
146 
147  //int myDataType = dataType( theBandNo );
148 
149  int myXBlockSize = xBlockSize();
150  int myYBlockSize = yBlockSize();
151  if ( myXBlockSize == 0 ) // should not happen, but happens
152  {
153  myXBlockSize = 500;
154  }
155  if ( myYBlockSize == 0 ) // should not happen, but happens
156  {
157  myYBlockSize = 500;
158  }
159 
160  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
161  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
162 
163  double myXRes = myExtent.width() / myWidth;
164  double myYRes = myExtent.height() / myHeight;
165  // TODO: progress signals
166 
167  // used by single pass stdev
168  double myMean = 0;
169  double mySumOfSquares = 0;
170 
171  bool myFirstIterationFlag = true;
172  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
173  {
174  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
175  {
176  QgsDebugMsgLevel( QString( "myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
177  int myBlockWidth = qMin( myXBlockSize, myWidth - myXBlock * myXBlockSize );
178  int myBlockHeight = qMin( myYBlockSize, myHeight - myYBlock * myYBlockSize );
179 
180  double xmin = myExtent.xMinimum() + myXBlock * myXBlockSize * myXRes;
181  double xmax = xmin + myBlockWidth * myXRes;
182  double ymin = myExtent.yMaximum() - myYBlock * myYBlockSize * myYRes;
183  double ymax = ymin - myBlockHeight * myYRes;
184 
185  QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
186 
187  QgsRasterBlock* blk = block( theBandNo, myPartExtent, myBlockWidth, myBlockHeight );
188 
189  // Collect the histogram counts.
190  for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
191  {
192  if ( blk->isNoData( i ) ) continue; // NULL
193 
194  double myValue = blk->value( i );
195 
196  myRasterBandStats.sum += myValue;
197  myRasterBandStats.elementCount++;
198 
199  if ( myFirstIterationFlag )
200  {
201  myFirstIterationFlag = false;
202  myRasterBandStats.minimumValue = myValue;
203  myRasterBandStats.maximumValue = myValue;
204  }
205  else
206  {
207  if ( myValue < myRasterBandStats.minimumValue )
208  {
209  myRasterBandStats.minimumValue = myValue;
210  }
211  if ( myValue > myRasterBandStats.maximumValue )
212  {
213  myRasterBandStats.maximumValue = myValue;
214  }
215  }
216 
217  // Single pass stdev
218  double myDelta = myValue - myMean;
219  myMean += myDelta / myRasterBandStats.elementCount;
220  mySumOfSquares += myDelta * ( myValue - myMean );
221  }
222  delete blk;
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 = sqrt( mySumOfSquares / ( myRasterBandStats.elementCount - 1 ) );
235 
236  QgsDebugMsgLevel( "************ STATS **************", 4 );
237  QgsDebugMsgLevel( QString( "MIN %1" ).arg( myRasterBandStats.minimumValue ), 4 );
238  QgsDebugMsgLevel( QString( "MAX %1" ).arg( myRasterBandStats.maximumValue ), 4 );
239  QgsDebugMsgLevel( QString( "RANGE %1" ).arg( myRasterBandStats.range ), 4 );
240  QgsDebugMsgLevel( QString( "MEAN %1" ).arg( myRasterBandStats.mean ), 4 );
241  QgsDebugMsgLevel( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ), 4 );
242 
243  myRasterBandStats.statsGathered = QgsRasterBandStats::All;
244  mStatistics.append( myRasterBandStats );
245 
246  return myRasterBandStats;
247 }
248 
250  int theBandNo,
251  int theBinCount,
252  double theMinimum, double theMaximum,
253  const QgsRectangle & theExtent,
254  int theSampleSize,
255  bool theIncludeOutOfRange )
256 {
257  theHistogram.bandNumber = theBandNo;
258  theHistogram.minimum = theMinimum;
259  theHistogram.maximum = theMaximum;
260  theHistogram.includeOutOfRange = theIncludeOutOfRange;
261 
262  int mySrcDataType = sourceDataType( theBandNo );
263 
264  if ( qIsNaN( theHistogram.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  theHistogram.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 aproximated histogram is requested
276  // (theSampleSize > 0)
277  QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
278  theHistogram.minimum = stats.minimumValue;
279  }
280  }
281  if ( qIsNaN( theHistogram.maximum ) )
282  {
283  if ( !mInput && mySrcDataType == Qgis::Byte )
284  {
285  theHistogram.maximum = 255;
286  }
287  else
288  {
289  QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Max, theExtent, theSampleSize );
290  theHistogram.maximum = stats.maximumValue;
291  }
292  }
293 
294  QgsRectangle myExtent;
295  if ( theExtent.isEmpty() )
296  {
297  myExtent = extent();
298  }
299  else
300  {
301  myExtent = extent().intersect( &theExtent );
302  }
303  theHistogram.extent = myExtent;
304 
305  if ( theSampleSize > 0 )
306  {
307  // Calc resolution from theSampleSize
308  double xRes, yRes;
309  xRes = yRes = sqrt(( myExtent.width() * myExtent.height() ) / theSampleSize );
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( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
320 
321  theHistogram.width = static_cast <int>( myExtent.width() / xRes );
322  theHistogram.height = static_cast <int>( myExtent.height() / yRes );
323  }
324  else
325  {
326  if ( capabilities() & Size )
327  {
328  theHistogram.width = xSize();
329  theHistogram.height = ySize();
330  }
331  else
332  {
333  theHistogram.width = 1000;
334  theHistogram.height = 1000;
335  }
336  }
337  QgsDebugMsgLevel( QString( "theHistogram.width = %1 theHistogram.height = %2" ).arg( theHistogram.width ).arg( theHistogram.height ), 4 );
338 
339  int myBinCount = theBinCount;
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 = theHistogram.width * theHistogram.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 > theHistogram.maximum - theHistogram.minimum + 1 )
361  myBinCount = int( ceil( theHistogram.maximum - theHistogram.minimum + 1 ) );
362  }
363  }
364  }
365  theHistogram.binCount = myBinCount;
366  QgsDebugMsgLevel( QString( "theHistogram.binCount = %1" ).arg( theHistogram.binCount ), 4 );
367 }
368 
369 
371  int theBinCount,
372  double theMinimum, double theMaximum,
373  const QgsRectangle & theExtent,
374  int theSampleSize,
375  bool theIncludeOutOfRange )
376 {
377  QgsDebugMsgLevel( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ), 4 );
378  // histogramDefaults() needs statistics if theMinimum or theMaximum 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, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
384 
385  Q_FOREACH ( const QgsRasterHistogram& histogram, mHistograms )
386  {
387  if ( histogram == myHistogram )
388  {
389  QgsDebugMsgLevel( "Has cached histogram.", 4 );
390  return true;
391  }
392  }
393  return false;
394 }
395 
397  int theBinCount,
398  double theMinimum, double theMaximum,
399  const QgsRectangle & theExtent,
400  int theSampleSize,
401  bool theIncludeOutOfRange )
402 {
403  QgsDebugMsgLevel( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ), 4 );
404 
405  QgsRasterHistogram myHistogram;
406  initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
407 
408  // Find cached
409  Q_FOREACH ( const QgsRasterHistogram& histogram, mHistograms )
410  {
411  if ( histogram == myHistogram )
412  {
413  QgsDebugMsgLevel( "Using cached histogram.", 4 );
414  return histogram;
415  }
416  }
417 
418  int myBinCount = myHistogram.binCount;
419  int myWidth = myHistogram.width;
420  int myHeight = myHistogram.height;
421  QgsRectangle myExtent = myHistogram.extent;
422  myHistogram.histogramVector.resize( myBinCount );
423 
424  int myXBlockSize = xBlockSize();
425  int myYBlockSize = yBlockSize();
426  if ( myXBlockSize == 0 ) // should not happen, but happens
427  {
428  myXBlockSize = 500;
429  }
430  if ( myYBlockSize == 0 ) // should not happen, but happens
431  {
432  myYBlockSize = 500;
433  }
434 
435  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
436  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
437 
438  double myXRes = myExtent.width() / myWidth;
439  double myYRes = myExtent.height() / myHeight;
440 
441  double myMinimum = myHistogram.minimum;
442  double myMaximum = myHistogram.maximum;
443 
444  // To avoid rounding errors
445  // TODO: check this
446  double myerval = ( myMaximum - myMinimum ) / myHistogram.binCount;
447  myMinimum -= 0.1 * myerval;
448  myMaximum += 0.1 * myerval;
449 
450  QgsDebugMsgLevel( QString( "binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
451 
452  double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
453 
454  // TODO: progress signals
455  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
456  {
457  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
458  {
459  int myBlockWidth = qMin( myXBlockSize, myWidth - myXBlock * myXBlockSize );
460  int myBlockHeight = qMin( 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( theBandNo, myPartExtent, myBlockWidth, myBlockHeight );
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>( qFloor(( myValue - myMinimum ) / myBinSize ) );
481 
482  if (( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !theIncludeOutOfRange )
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 < qMin( 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 theLowerCount, double theUpperCount,
513  double &theLowerValue, double &theUpperValue,
514  const QgsRectangle & theExtent,
515  int theSampleSize )
516 {
517  QgsDebugMsgLevel( QString( "theBandNo = %1 theLowerCount = %2 theUpperCount = %3 theSampleSize = %4" ).arg( theBandNo ).arg( theLowerCount ).arg( theUpperCount ).arg( theSampleSize ), 4 );
518 
519  int mySrcDataType = sourceDataType( theBandNo );
520 
521  // Init to NaN is better than histogram min/max to catch errors
522  theLowerValue = std::numeric_limits<double>::quiet_NaN();
523  theUpperValue = 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( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
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( ceil( stats.maximumValue - stats.minimumValue + 1 ) ) : 0;
532  QgsRasterHistogram myHistogram = histogram( theBandNo, myBinCount, stats.minimumValue, stats.maximumValue, theExtent, theSampleSize );
533  //QgsRasterHistogram myHistogram = histogram( theBandNo, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), theExtent, theSampleSize );
534 
535  double myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
536  int myCount = 0;
537  int myMinCount = static_cast< int >( qRound( theLowerCount * myHistogram.nonNullCount ) );
538  int myMaxCount = static_cast< int >( qRound( theUpperCount * 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  theLowerValue = myHistogram.minimum + myBin * myBinXStep;
550  myLowerFound = true;
551  QgsDebugMsgLevel( QString( "found lowerValue %1 at bin %2" ).arg( theLowerValue ).arg( myBin ), 4 );
552  }
553  if ( myCount >= myMaxCount )
554  {
555  theUpperValue = myHistogram.minimum + myBin * myBinXStep;
556  QgsDebugMsgLevel( QString( "found upperValue %1 at bin %2" ).arg( theUpperValue ).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 ( theLowerValue != std::numeric_limits<double>::quiet_NaN() )
567  theLowerValue = floor( theLowerValue );
568  if ( theUpperValue != std::numeric_limits<double>::quiet_NaN() )
569  theUpperValue = ceil( theUpperValue );
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:35
Thirty two bit signed integer (qint32)
Definition: qgis.h:67
double sum
The sum of all cells in the band. NO_DATA values are excluded.
void initHistogram(QgsRasterHistogram &theHistogram, int theBandNo, int theBinCount=0, double theMinimum=std::numeric_limits< double >::quiet_NaN(), double theMaximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0, bool theIncludeOutOfRange=false)
Fill in histogram defaults if not specified.
virtual QgsRectangle extent() const
Get the extent of the interface.
int bandNumber
The gdal band number (starts at 1)
int width
Number of columns used to calc histogram.
int height
Number of rows used to calc statistics.
int bandNumber
The gdal band number (starts at 1)
double minimum
The minimum histogram value.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:66
double maximumValue
The maximum cell value in the raster band.
virtual int ySize() const
QgsRectangle intersect(const QgsRectangle *rect) const
return the intersection with the given rectangle
int height
Number of rows used to calc histogram.
Sixteen bit signed integer (qint16)
Definition: qgis.h:65
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.
void initStatistics(QgsRasterBandStats &theStatistics, int theBandNo, int theStats=QgsRasterBandStats::All, const QgsRectangle &theExtent=QgsRectangle(), int theBinCount=0)
Fill in statistics defaults if not specified.
virtual int xBlockSize() const
Get block size.
QgsRectangle extent
Extent used to calc statistics.
virtual QgsRasterBandStats bandStatistics(int theBandNo, int theStats=QgsRasterBandStats::All, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Get band 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.
virtual bool hasHistogram(int theBandNo, int theBinCount, double theMinimum=std::numeric_limits< double >::quiet_NaN(), double theMaximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0, bool theIncludeOutOfRange=false)
Returns true if histogram is available (cached, already calculated), the parameters are the same as i...
QgsRasterInterface(QgsRasterInterface *input=nullptr)
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
bool isEmpty() const
test if rectangle is empty.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:211
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
qgssize elementCount
The number of not no data cells in the band.
int statsGathered
Collected statistics.
QString capabilitiesString() const
Returns the above in friendly format.
virtual Qgis::DataType sourceDataType(int bandNo) const
Returns source data type for the band specified by number, source data type may be shorter than dataT...
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:64
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:336
virtual QgsRasterHistogram histogram(int theBandNo, int theBinCount=0, double theMinimum=std::numeric_limits< double >::quiet_NaN(), double theMaximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0, bool theIncludeOutOfRange=false)
Get histogram.
double maximum
The maximum histogram value.
virtual bool hasStatistics(int theBandNo, int theStats=QgsRasterBandStats::All, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Returns true if histogram is available (cached, already calculated).
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
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:196
double minimumValue
The minimum cell value in the raster band.
The QgsRasterHistogram is a container for histogram of a single raster band.
int binCount
Number of bins (intervals,buckets) in histogram.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:201
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
HistogramVector histogramVector
Store the histogram for a given layer.
bool valid
Histogram is valid.
virtual void cumulativeCut(int theBandNo, double theLowerCount, double theUpperCount, double &theLowerValue, double &theUpperValue, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Find values for cumulative pixel count cut.
QgsRasterInterface * mInput
QgsRectangle extent
Extent used to calc histogram.
virtual int xSize() const
Get raster size.
Eight bit unsigned integer (quint8)
Definition: qgis.h:63
bool includeOutOfRange
Whether histogram includes out of range values (in first and last bin)
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:216
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.