QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
24 #include <qmath.h>
25 
26 #include "qgslogger.h"
27 #include "qgsrasterbandstats.h"
28 #include "qgsrasterhistogram.h"
29 #include "qgsrasterinterface.h"
30 #include "qgsrectangle.h"
31 
33  : mInput( input )
34  , mOn( true )
35 {
36 }
37 
39 {
40 }
41 
43  int theBandNo,
44  int theStats,
45  const QgsRectangle & theExtent,
46  int theSampleSize )
47 {
48  QgsDebugMsgLevel( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ), 4 );
49 
50  theStatistics.bandNumber = theBandNo;
51  theStatistics.statsGathered = theStats;
52 
53  QgsRectangle myExtent;
54  if ( theExtent.isEmpty() )
55  {
56  myExtent = extent();
57  }
58  else
59  {
60  myExtent = extent().intersect( &theExtent );
61  }
62  theStatistics.extent = myExtent;
63 
64  if ( theSampleSize > 0 )
65  {
66  // Calc resolution from theSampleSize
67  double xRes, yRes;
68  xRes = yRes = sqrt(( myExtent.width() * myExtent.height() ) / theSampleSize );
69 
70  // But limit by physical resolution
71  if ( capabilities() & Size )
72  {
73  double srcXRes = extent().width() / xSize();
74  double srcYRes = extent().height() / ySize();
75  if ( xRes < srcXRes ) xRes = srcXRes;
76  if ( yRes < srcYRes ) yRes = srcYRes;
77  }
78  QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
79 
80  theStatistics.width = static_cast <int>( myExtent.width() / xRes );
81  theStatistics.height = static_cast <int>( myExtent.height() / yRes );
82  }
83  else
84  {
85  if ( capabilities() & Size )
86  {
87  theStatistics.width = xSize();
88  theStatistics.height = ySize();
89  }
90  else
91  {
92  theStatistics.width = 1000;
93  theStatistics.height = 1000;
94  }
95  }
96  QgsDebugMsgLevel( QString( "theStatistics.width = %1 theStatistics.height = %2" ).arg( theStatistics.width ).arg( theStatistics.height ), 4 );
97 }
98 
100  int theStats,
101  const QgsRectangle & theExtent,
102  int theSampleSize )
103 {
104  QgsDebugMsgLevel( QString( "theBandNo = %1 theStats = %2 theSampleSize = %3" ).arg( theBandNo ).arg( theStats ).arg( theSampleSize ), 4 );
105  if ( mStatistics.isEmpty() ) return false;
106 
107  QgsRasterBandStats myRasterBandStats;
108  initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
109 
110  Q_FOREACH ( const QgsRasterBandStats& stats, mStatistics )
111  {
112  if ( stats.contains( myRasterBandStats ) )
113  {
114  QgsDebugMsgLevel( "Has cached statistics.", 4 );
115  return true;
116  }
117  }
118  return false;
119 }
120 
122  int theStats,
123  const QgsRectangle & theExtent,
124  int theSampleSize )
125 {
126  QgsDebugMsgLevel( QString( "theBandNo = %1 theStats = %2 theSampleSize = %3" ).arg( theBandNo ).arg( theStats ).arg( theSampleSize ), 4 );
127 
128  // TODO: null values set on raster layer!!!
129 
130  QgsRasterBandStats myRasterBandStats;
131  initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );
132 
133  Q_FOREACH ( const QgsRasterBandStats& stats, mStatistics )
134  {
135  if ( stats.contains( myRasterBandStats ) )
136  {
137  QgsDebugMsgLevel( "Using cached statistics.", 4 );
138  return stats;
139  }
140  }
141 
142  QgsRectangle myExtent = myRasterBandStats.extent;
143  int myWidth = myRasterBandStats.width;
144  int myHeight = myRasterBandStats.height;
145 
146  //int myDataType = dataType( theBandNo );
147 
148  int myXBlockSize = xBlockSize();
149  int myYBlockSize = yBlockSize();
150  if ( myXBlockSize == 0 ) // should not happen, but happens
151  {
152  myXBlockSize = 500;
153  }
154  if ( myYBlockSize == 0 ) // should not happen, but happens
155  {
156  myYBlockSize = 500;
157  }
158 
159  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
160  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
161 
162  double myXRes = myExtent.width() / myWidth;
163  double myYRes = myExtent.height() / myHeight;
164  // TODO: progress signals
165 
166  // used by single pass stdev
167  double myMean = 0;
168  double mySumOfSquares = 0;
169 
170  bool myFirstIterationFlag = true;
171  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
172  {
173  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
174  {
175  QgsDebugMsgLevel( QString( "myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
176  int myBlockWidth = qMin( myXBlockSize, myWidth - myXBlock * myXBlockSize );
177  int myBlockHeight = qMin( 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  QgsRasterBlock* blk = block( theBandNo, myPartExtent, myBlockWidth, myBlockHeight );
187 
188  // Collect the histogram counts.
189  for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
190  {
191  if ( blk->isNoData( i ) ) continue; // NULL
192 
193  double myValue = blk->value( i );
194 
195  myRasterBandStats.sum += myValue;
196  myRasterBandStats.elementCount++;
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  delete blk;
222  }
223  }
224 
225  myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
226  myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;
227 
228  myRasterBandStats.sumOfSquares = mySumOfSquares; // OK with single pass?
229 
230  // stdDev may differ from GDAL stats, because GDAL is using naive single pass
231  // algorithm which is more error prone (because of rounding errors)
232  // Divide result by sample size - 1 and get square root to get stdev
233  myRasterBandStats.stdDev = sqrt( mySumOfSquares / ( myRasterBandStats.elementCount - 1 ) );
234 
235  QgsDebugMsgLevel( "************ STATS **************", 4 );
236  QgsDebugMsgLevel( QString( "MIN %1" ).arg( myRasterBandStats.minimumValue ), 4 );
237  QgsDebugMsgLevel( QString( "MAX %1" ).arg( myRasterBandStats.maximumValue ), 4 );
238  QgsDebugMsgLevel( QString( "RANGE %1" ).arg( myRasterBandStats.range ), 4 );
239  QgsDebugMsgLevel( QString( "MEAN %1" ).arg( myRasterBandStats.mean ), 4 );
240  QgsDebugMsgLevel( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ), 4 );
241 
242  myRasterBandStats.statsGathered = QgsRasterBandStats::All;
243  mStatistics.append( myRasterBandStats );
244 
245  return myRasterBandStats;
246 }
247 
249  int theBandNo,
250  int theBinCount,
251  double theMinimum, double theMaximum,
252  const QgsRectangle & theExtent,
253  int theSampleSize,
254  bool theIncludeOutOfRange )
255 {
256  theHistogram.bandNumber = theBandNo;
257  theHistogram.minimum = theMinimum;
258  theHistogram.maximum = theMaximum;
259  theHistogram.includeOutOfRange = theIncludeOutOfRange;
260 
261  int mySrcDataType = srcDataType( theBandNo );
262 
263  if ( qIsNaN( theHistogram.minimum ) )
264  {
265  // TODO: this was OK when stats/histogram were calced in provider,
266  // but what TODO in other interfaces? Check for mInput for now.
267  if ( !mInput && mySrcDataType == QGis::Byte )
268  {
269  theHistogram.minimum = 0; // see histogram() for shift for rounding
270  }
271  else
272  {
273  // We need statistics -> avoid histogramDefaults in hasHistogram if possible
274  // TODO: use approximated statistics if aproximated histogram is requested
275  // (theSampleSize > 0)
276  QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
277  theHistogram.minimum = stats.minimumValue;
278  }
279  }
280  if ( qIsNaN( theHistogram.maximum ) )
281  {
282  if ( !mInput && mySrcDataType == QGis::Byte )
283  {
284  theHistogram.maximum = 255;
285  }
286  else
287  {
288  QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Max, theExtent, theSampleSize );
289  theHistogram.maximum = stats.maximumValue;
290  }
291  }
292 
293  QgsRectangle myExtent;
294  if ( theExtent.isEmpty() )
295  {
296  myExtent = extent();
297  }
298  else
299  {
300  myExtent = extent().intersect( &theExtent );
301  }
302  theHistogram.extent = myExtent;
303 
304  if ( theSampleSize > 0 )
305  {
306  // Calc resolution from theSampleSize
307  double xRes, yRes;
308  xRes = yRes = sqrt(( myExtent.width() * myExtent.height() ) / theSampleSize );
309 
310  // But limit by physical resolution
311  if ( capabilities() & Size )
312  {
313  double srcXRes = extent().width() / xSize();
314  double srcYRes = extent().height() / ySize();
315  if ( xRes < srcXRes ) xRes = srcXRes;
316  if ( yRes < srcYRes ) yRes = srcYRes;
317  }
318  QgsDebugMsgLevel( QString( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
319 
320  theHistogram.width = static_cast <int>( myExtent.width() / xRes );
321  theHistogram.height = static_cast <int>( myExtent.height() / yRes );
322  }
323  else
324  {
325  if ( capabilities() & Size )
326  {
327  theHistogram.width = xSize();
328  theHistogram.height = ySize();
329  }
330  else
331  {
332  theHistogram.width = 1000;
333  theHistogram.height = 1000;
334  }
335  }
336  QgsDebugMsgLevel( QString( "theHistogram.width = %1 theHistogram.height = %2" ).arg( theHistogram.width ).arg( theHistogram.height ), 4 );
337 
338  int myBinCount = theBinCount;
339  if ( myBinCount == 0 )
340  {
341  // TODO: this was OK when stats/histogram were calced in provider,
342  // but what TODO in other interfaces? Check for mInput for now.
343  if ( !mInput && mySrcDataType == QGis::Byte )
344  {
345  myBinCount = 256; // Cannot store more values in byte
346  }
347  else
348  {
349  // 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;
350  myBinCount = theHistogram.width * theHistogram.height;
351  if ( myBinCount > 1000 ) myBinCount = 1000;
352 
353  // for Int16/Int32 make sure bin count <= actual range, because there is no sense in having
354  // bins at fractional values
355  if ( !mInput && (
356  mySrcDataType == QGis::Int16 || mySrcDataType == QGis::Int32 ||
357  mySrcDataType == QGis::UInt16 || mySrcDataType == QGis::UInt32 ) )
358  {
359  if ( myBinCount > theHistogram.maximum - theHistogram.minimum + 1 )
360  myBinCount = int( ceil( theHistogram.maximum - theHistogram.minimum + 1 ) );
361  }
362  }
363  }
364  theHistogram.binCount = myBinCount;
365  QgsDebugMsgLevel( QString( "theHistogram.binCount = %1" ).arg( theHistogram.binCount ), 4 );
366 }
367 
368 
370  int theBinCount,
371  double theMinimum, double theMaximum,
372  const QgsRectangle & theExtent,
373  int theSampleSize,
374  bool theIncludeOutOfRange )
375 {
376  QgsDebugMsgLevel( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ), 4 );
377  // histogramDefaults() needs statistics if theMinimum or theMaximum is NaN ->
378  // do other checks which don't need statistics before histogramDefaults()
379  if ( mHistograms.isEmpty() ) return false;
380 
381  QgsRasterHistogram myHistogram;
382  initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
383 
384  Q_FOREACH ( const QgsRasterHistogram& histogram, mHistograms )
385  {
386  if ( histogram == myHistogram )
387  {
388  QgsDebugMsgLevel( "Has cached histogram.", 4 );
389  return true;
390  }
391  }
392  return false;
393 }
394 
396  int theBinCount,
397  double theMinimum, double theMaximum,
398  const QgsRectangle & theExtent,
399  int theSampleSize,
400  bool theIncludeOutOfRange )
401 {
402  QgsDebugMsgLevel( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ), 4 );
403 
404  QgsRasterHistogram myHistogram;
405  initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
406 
407  // Find cached
408  Q_FOREACH ( const QgsRasterHistogram& histogram, mHistograms )
409  {
410  if ( histogram == myHistogram )
411  {
412  QgsDebugMsgLevel( "Using cached histogram.", 4 );
413  return histogram;
414  }
415  }
416 
417  int myBinCount = myHistogram.binCount;
418  int myWidth = myHistogram.width;
419  int myHeight = myHistogram.height;
420  QgsRectangle myExtent = myHistogram.extent;
421  myHistogram.histogramVector.resize( myBinCount );
422 
423  int myXBlockSize = xBlockSize();
424  int myYBlockSize = yBlockSize();
425  if ( myXBlockSize == 0 ) // should not happen, but happens
426  {
427  myXBlockSize = 500;
428  }
429  if ( myYBlockSize == 0 ) // should not happen, but happens
430  {
431  myYBlockSize = 500;
432  }
433 
434  int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
435  int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
436 
437  double myXRes = myExtent.width() / myWidth;
438  double myYRes = myExtent.height() / myHeight;
439 
440  double myMinimum = myHistogram.minimum;
441  double myMaximum = myHistogram.maximum;
442 
443  // To avoid rounding errors
444  // TODO: check this
445  double myerval = ( myMaximum - myMinimum ) / myHistogram.binCount;
446  myMinimum -= 0.1 * myerval;
447  myMaximum += 0.1 * myerval;
448 
449  QgsDebugMsgLevel( QString( "binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
450 
451  double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
452 
453  // TODO: progress signals
454  for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
455  {
456  for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
457  {
458  int myBlockWidth = qMin( myXBlockSize, myWidth - myXBlock * myXBlockSize );
459  int myBlockHeight = qMin( 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  QgsRasterBlock* blk = block( theBandNo, myPartExtent, myBlockWidth, myBlockHeight );
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>( qFloor(( myValue - myMinimum ) / myBinSize ) );
480 
481  if (( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !theIncludeOutOfRange )
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  delete blk;
492  }
493  }
494 
495  myHistogram.valid = true;
496  mHistograms.append( myHistogram );
497 
498 #ifdef QGISDEBUG
499  QString hist;
500  for ( int i = 0; i < qMin( myHistogram.histogramVector.size(), 500 ); i++ )
501  {
502  hist += QString::number( myHistogram.histogramVector.value( i ) ) + ' ';
503  }
504  QgsDebugMsgLevel( "Histogram (max first 500 bins): " + hist, 4 );
505 #endif
506 
507  return myHistogram;
508 }
509 
511  double theLowerCount, double theUpperCount,
512  double &theLowerValue, double &theUpperValue,
513  const QgsRectangle & theExtent,
514  int theSampleSize )
515 {
516  QgsDebugMsgLevel( QString( "theBandNo = %1 theLowerCount = %2 theUpperCount = %3 theSampleSize = %4" ).arg( theBandNo ).arg( theLowerCount ).arg( theUpperCount ).arg( theSampleSize ), 4 );
517 
518  int mySrcDataType = srcDataType( theBandNo );
519 
520  // Init to NaN is better than histogram min/max to catch errors
521  theLowerValue = std::numeric_limits<double>::quiet_NaN();
522  theUpperValue = std::numeric_limits<double>::quiet_NaN();
523 
524  //get band stats to specify real histogram min/max (fix #9793 Byte bands)
525  QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
526  if ( stats.maximumValue < stats.minimumValue )
527  return;
528 
529  // for byte bands make sure bin count == actual range
530  int myBinCount = ( mySrcDataType == QGis::Byte ) ? int( ceil( stats.maximumValue - stats.minimumValue + 1 ) ) : 0;
531  QgsRasterHistogram myHistogram = histogram( theBandNo, myBinCount, stats.minimumValue, stats.maximumValue, theExtent, theSampleSize );
532  //QgsRasterHistogram myHistogram = histogram( theBandNo, 0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), theExtent, theSampleSize );
533 
534  double myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / myHistogram.binCount;
535  int myCount = 0;
536  int myMinCount = static_cast< int >( qRound( theLowerCount * myHistogram.nonNullCount ) );
537  int myMaxCount = static_cast< int >( qRound( theUpperCount * myHistogram.nonNullCount ) );
538  bool myLowerFound = false;
539  QgsDebugMsgLevel( QString( "binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.binCount ).arg( myHistogram.minimum ).arg( myHistogram.maximum ).arg( myBinXStep ), 4 );
540  QgsDebugMsgLevel( QString( "myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
541 
542  for ( int myBin = 0; myBin < myHistogram.histogramVector.size(); myBin++ )
543  {
544  int myBinValue = myHistogram.histogramVector.value( myBin );
545  myCount += myBinValue;
546  if ( !myLowerFound && myCount > myMinCount )
547  {
548  theLowerValue = myHistogram.minimum + myBin * myBinXStep;
549  myLowerFound = true;
550  QgsDebugMsgLevel( QString( "found lowerValue %1 at bin %2" ).arg( theLowerValue ).arg( myBin ), 4 );
551  }
552  if ( myCount >= myMaxCount )
553  {
554  theUpperValue = myHistogram.minimum + myBin * myBinXStep;
555  QgsDebugMsgLevel( QString( "found upperValue %1 at bin %2" ).arg( theUpperValue ).arg( myBin ), 4 );
556  break;
557  }
558  }
559 
560  // fix integer data - round down/up
561  if ( mySrcDataType == QGis::Byte ||
562  mySrcDataType == QGis::Int16 || mySrcDataType == QGis::Int32 ||
563  mySrcDataType == QGis::UInt16 || mySrcDataType == QGis::UInt32 )
564  {
565  if ( theLowerValue != std::numeric_limits<double>::quiet_NaN() )
566  theLowerValue = floor( theLowerValue );
567  if ( theUpperValue != std::numeric_limits<double>::quiet_NaN() )
568  theUpperValue = ceil( theUpperValue );
569  }
570 }
571 
573 {
574  QStringList abilitiesList;
575 
576  int abilities = capabilities();
577 
578  // Not all all capabilities are here (Size, IdentifyValue, IdentifyText,
579  // IdentifyHtml, IdentifyFeature) because those are quite technical and probably
580  // would be confusing for users
581 
582  if ( abilities & QgsRasterInterface::Identify )
583  {
584  abilitiesList += tr( "Identify" );
585  }
586 
587  if ( abilities & QgsRasterInterface::Create )
588  {
589  abilitiesList += tr( "Create Datasources" );
590  }
591 
592  if ( abilities & QgsRasterInterface::Remove )
593  {
594  abilitiesList += tr( "Remove Datasources" );
595  }
596 
597  if ( abilities & QgsRasterInterface::BuildPyramids )
598  {
599  abilitiesList += tr( "Build Pyramids" );
600  }
601 
602  QgsDebugMsgLevel( "Capability: " + abilitiesList.join( ", " ), 4 );
603 
604  return abilitiesList.join( ", " );
605 }
Eight bit unsigned integer (quint8)
Definition: qgis.h:136
A rectangle specified with double values.
Definition: qgsrectangle.h:35
double sum
The sum of all cells in the band.
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.
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.
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
QString join(const QString &separator) const
int height
Number of rows used to calc histogram.
bool isNoData(int row, int column)
Check if value at position is no data.
bool contains(const QgsRasterBandStats &s) const
Compares region, size etc.
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.
T value(int i) const
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.
QString number(int n, int base)
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band.
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...
void append(const T &value)
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:137
void resize(int size)
QgsRasterInterface(QgsRasterInterface *input=nullptr)
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
bool isEmpty() const
test if rectangle is empty.
Thirty two bit signed integer (qint32)
Definition: qgis.h:140
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:207
bool isEmpty() const
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
qgssize elementCount
The number of not no data cells in the band.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:139
int statsGathered
Collected statistics.
QString capabilitiesString() const
Returns the above in friendly format.
virtual QGis::DataType srcDataType(int bandNo) const
Returns source data type for the band specified by number, source data type may be shorter than dataT...
Base class for processing filters like renderers, reprojector, resampler etc.
Sixteen bit signed integer (qint16)
Definition: qgis.h:138
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:500
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 QgsRectangle extent()
Get the extent of the interface.
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.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height)=0
Read block of data using given extent and size.
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:192
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:197
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
int size() const
QgsRectangle extent
Extent used to calc histogram.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
virtual int xSize() const
Get raster size.
bool includeOutOfRange
Whether histogram includes out of range values (in first and last bin)
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:212
double sumOfSquares
The sum of the squares.
int width
Number of columns used to calc statistics.
int nonNullCount
The number of non NULL cells used to calculate histogram.