QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrasteranalysisutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasteranalysisutils.cpp
3  ---------------------
4  Date : June 2018
5  Copyright : (C) 2018 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsrasteranalysisutils.h"
17 
18 #include "qgsfeedback.h"
19 #include "qgsrasterblock.h"
20 #include "qgsrasteriterator.h"
21 #include "qgsgeos.h"
23 #include <map>
24 #include <unordered_map>
25 #include <unordered_set>
26 #include <cmath>
28 
29 void QgsRasterAnalysisUtils::cellInfoForBBox( const QgsRectangle &rasterBBox, const QgsRectangle &featureBBox, double cellSizeX, double cellSizeY,
30  int &nCellsX, int &nCellsY, int rasterWidth, int rasterHeight, QgsRectangle &rasterBlockExtent )
31 {
32  //get intersecting bbox
33  const QgsRectangle intersectBox = rasterBBox.intersect( featureBBox );
34  if ( intersectBox.isEmpty() )
35  {
36  nCellsX = 0;
37  nCellsY = 0;
38  rasterBlockExtent = QgsRectangle();
39  return;
40  }
41 
42  //get offset in pixels in x- and y- direction
43  const int offsetX = static_cast< int >( std::floor( ( intersectBox.xMinimum() - rasterBBox.xMinimum() ) / cellSizeX ) );
44  const int offsetY = static_cast< int >( std::floor( ( rasterBBox.yMaximum() - intersectBox.yMaximum() ) / cellSizeY ) );
45 
46  const int maxColumn = static_cast< int >( std::floor( ( intersectBox.xMaximum() - rasterBBox.xMinimum() ) / cellSizeX ) ) + 1;
47  const int maxRow = static_cast< int >( std::floor( ( rasterBBox.yMaximum() - intersectBox.yMinimum() ) / cellSizeY ) ) + 1;
48 
49  nCellsX = maxColumn - offsetX;
50  nCellsY = maxRow - offsetY;
51 
52  //avoid access to cells outside of the raster (may occur because of rounding)
53  nCellsX = std::min( offsetX + nCellsX, rasterWidth ) - offsetX;
54  nCellsY = std::min( offsetY + nCellsY, rasterHeight ) - offsetY;
55 
56  rasterBlockExtent = QgsRectangle( rasterBBox.xMinimum() + offsetX * cellSizeX,
57  rasterBBox.yMaximum() - offsetY * cellSizeY,
58  rasterBBox.xMinimum() + ( nCellsX + offsetX ) * cellSizeX,
59  rasterBBox.yMaximum() - ( nCellsY + offsetY ) * cellSizeY );
60 }
61 
62 void QgsRasterAnalysisUtils::statisticsFromMiddlePointTest( QgsRasterInterface *rasterInterface, int rasterBand, const QgsGeometry &poly, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, const std::function<void( double )> &addValue, bool skipNodata )
63 {
64  std::unique_ptr< QgsGeometryEngine > polyEngine( QgsGeometry::createGeometryEngine( poly.constGet( ) ) );
65  if ( !polyEngine )
66  {
67  return;
68  }
69  polyEngine->prepareGeometry();
70 
71  QgsRasterIterator iter( rasterInterface );
72  iter.startRasterRead( rasterBand, nCellsX, nCellsY, rasterBBox );
73 
74  std::unique_ptr< QgsRasterBlock > block;
75  int iterLeft = 0;
76  int iterTop = 0;
77  int iterCols = 0;
78  int iterRows = 0;
79  QgsRectangle blockExtent;
80  bool isNoData = false;
81  while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
82  {
83  double cellCenterY = blockExtent.yMaximum() - 0.5 * cellSizeY;
84 
85  for ( int row = 0; row < iterRows; ++row )
86  {
87  double cellCenterX = blockExtent.xMinimum() + 0.5 * cellSizeX;
88  for ( int col = 0; col < iterCols; ++col )
89  {
90  const double pixelValue = block->valueAndNoData( row, col, isNoData );
91  if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
92  {
93  QgsPoint cellCenter( cellCenterX, cellCenterY );
94  if ( polyEngine->contains( &cellCenter ) )
95  {
96  addValue( pixelValue );
97  }
98  }
99  cellCenterX += cellSizeX;
100  }
101  cellCenterY -= cellSizeY;
102  }
103  }
104 }
105 
106 void QgsRasterAnalysisUtils::statisticsFromPreciseIntersection( QgsRasterInterface *rasterInterface, int rasterBand, const QgsGeometry &poly, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, const std::function<void( double, double )> &addValue, bool skipNodata )
107 {
108  QgsGeometry pixelRectGeometry;
109 
110  const double hCellSizeX = cellSizeX / 2.0;
111  const double hCellSizeY = cellSizeY / 2.0;
112  const double pixelArea = cellSizeX * cellSizeY;
113  double weight = 0;
114 
115  std::unique_ptr< QgsGeometryEngine > polyEngine( QgsGeometry::createGeometryEngine( poly.constGet( ) ) );
116  if ( !polyEngine )
117  {
118  return;
119  }
120  polyEngine->prepareGeometry();
121 
122  QgsRasterIterator iter( rasterInterface );
123  iter.startRasterRead( rasterBand, nCellsX, nCellsY, rasterBBox );
124 
125  std::unique_ptr< QgsRasterBlock > block;
126  int iterLeft = 0;
127  int iterTop = 0;
128  int iterCols = 0;
129  int iterRows = 0;
130  QgsRectangle blockExtent;
131  bool isNoData = false;
132  while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
133  {
134  double currentY = blockExtent.yMaximum() - 0.5 * cellSizeY;
135  for ( int row = 0; row < iterRows; ++row )
136  {
137  double currentX = blockExtent.xMinimum() + 0.5 * cellSizeX;
138  for ( int col = 0; col < iterCols; ++col )
139  {
140  const double pixelValue = block->valueAndNoData( row, col, isNoData );
141  if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
142  {
143  pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
144  // GEOS intersects tests on prepared geometry is MAGNITUDES faster than calculating the intersection itself,
145  // so we first test to see if there IS an intersection before doing the actual calculation
146  if ( !pixelRectGeometry.isNull() && polyEngine->intersects( pixelRectGeometry.constGet() ) )
147  {
148  //intersection
149  const QgsGeometry intersectGeometry = pixelRectGeometry.intersection( poly );
150  if ( !intersectGeometry.isEmpty() )
151  {
152  const double intersectionArea = intersectGeometry.area();
153  if ( intersectionArea > 0.0 )
154  {
155  weight = intersectionArea / pixelArea;
156  addValue( pixelValue, weight );
157  }
158  }
159  }
160  }
161  currentX += cellSizeX;
162  }
163  currentY -= cellSizeY;
164  }
165  }
166 }
167 
168 bool QgsRasterAnalysisUtils::validPixel( double value )
169 {
170  return !std::isnan( value );
171 }
172 
173 void QgsRasterAnalysisUtils::mapToPixel( const double x, const double y, const QgsRectangle bounds, const double unitsPerPixelX, const double unitsPerPixelY, int &px, int &py )
174 {
175  px = trunc( ( x - bounds.xMinimum() ) / unitsPerPixelX );
176  py = trunc( ( y - bounds.yMaximum() ) / -unitsPerPixelY );
177 }
178 
179 void QgsRasterAnalysisUtils::pixelToMap( const int px, const int py, const QgsRectangle bounds, const double unitsPerPixelX, const double unitsPerPixelY, double &x, double &y )
180 {
181  x = bounds.xMinimum() + ( px + 0.5 ) * unitsPerPixelX;
182  y = bounds.yMaximum() - ( py + 0.5 ) * unitsPerPixelY;
183 }
184 
185 static QVector< QPair< QString, Qgis::DataType > > sDataTypes;
186 
187 void populateDataTypes()
188 {
189  if ( sDataTypes.empty() )
190  {
191  sDataTypes.append( qMakePair( QStringLiteral( "Byte" ), Qgis::DataType::Byte ) );
192  sDataTypes.append( qMakePair( QStringLiteral( "Int16" ), Qgis::DataType::Int16 ) );
193  sDataTypes.append( qMakePair( QStringLiteral( "UInt16" ), Qgis::DataType::UInt16 ) );
194  sDataTypes.append( qMakePair( QStringLiteral( "Int32" ), Qgis::DataType::Int32 ) );
195  sDataTypes.append( qMakePair( QStringLiteral( "UInt32" ), Qgis::DataType::UInt32 ) );
196  sDataTypes.append( qMakePair( QStringLiteral( "Float32" ), Qgis::DataType::Float32 ) );
197  sDataTypes.append( qMakePair( QStringLiteral( "Float64" ), Qgis::DataType::Float64 ) );
198  sDataTypes.append( qMakePair( QStringLiteral( "CInt16" ), Qgis::DataType::CInt16 ) );
199  sDataTypes.append( qMakePair( QStringLiteral( "CInt32" ), Qgis::DataType::CInt32 ) );
200  sDataTypes.append( qMakePair( QStringLiteral( "CFloat32" ), Qgis::DataType::CFloat32 ) );
201  sDataTypes.append( qMakePair( QStringLiteral( "CFloat64" ), Qgis::DataType::CFloat64 ) );
202  }
203 }
204 
205 std::unique_ptr<QgsProcessingParameterDefinition> QgsRasterAnalysisUtils::createRasterTypeParameter( const QString &name, const QString &description, Qgis::DataType defaultType )
206 {
207  populateDataTypes();
208 
209  QStringList names;
210  int defaultChoice = 0;
211  int i = 0;
212  for ( auto it = sDataTypes.constBegin(); it != sDataTypes.constEnd(); ++it )
213  {
214  names.append( it->first );
215  if ( it->second == defaultType )
216  defaultChoice = i;
217  i++;
218  }
219 
220  return std::make_unique< QgsProcessingParameterEnum >( name, description, names, false, defaultChoice );
221 }
222 
223 Qgis::DataType QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( int choice )
224 {
225  if ( choice < 0 || choice >= sDataTypes.count() )
227 
228  return sDataTypes.value( choice ).second;
229 }
230 
231 void QgsRasterAnalysisUtils::applyRasterLogicOperator( const std::vector< QgsRasterAnalysisUtils::RasterLogicInput > &inputs, QgsRasterDataProvider *destinationRaster, double outputNoDataValue, const bool treatNoDataAsFalse,
232  int width, int height, const QgsRectangle &extent, QgsFeedback *feedback,
233  std::function<void( const std::vector< std::unique_ptr< QgsRasterBlock > > &, bool &, bool &, int, int, bool )> &applyLogicFunc,
234  qgssize &noDataCount, qgssize &trueCount, qgssize &falseCount )
235 {
238  const int nbBlocksWidth = static_cast< int>( std::ceil( 1.0 * width / maxWidth ) );
239  const int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * height / maxHeight ) );
240  const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
241 
242  destinationRaster->setEditable( true );
243  QgsRasterIterator outputIter( destinationRaster );
244  outputIter.startRasterRead( 1, width, height, extent );
245 
246  int iterLeft = 0;
247  int iterTop = 0;
248  int iterCols = 0;
249  int iterRows = 0;
250  QgsRectangle blockExtent;
251  std::unique_ptr< QgsRasterBlock > outputBlock;
252  while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
253  {
254  std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
255  for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : inputs )
256  {
257  for ( const int band : i.bands )
258  {
259  std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
260  inputBlocks.emplace_back( std::move( b ) );
261  }
262  }
263 
264  feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
265  for ( int row = 0; row < iterRows; row++ )
266  {
267  if ( feedback->isCanceled() )
268  break;
269 
270  for ( int column = 0; column < iterCols; column++ )
271  {
272  bool res = false;
273  bool resIsNoData = false;
274  applyLogicFunc( inputBlocks, res, resIsNoData, row, column, treatNoDataAsFalse );
275  if ( resIsNoData )
276  noDataCount++;
277  else if ( res )
278  trueCount++;
279  else
280  falseCount++;
281 
282  outputBlock->setValue( row, column, resIsNoData ? outputNoDataValue : ( res ? 1 : 0 ) );
283  }
284  }
285  destinationRaster->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
286  }
287  destinationRaster->setEditable( false );
288 }
289 
290 std::vector<double> QgsRasterAnalysisUtils::getCellValuesFromBlockStack( const std::vector< std::unique_ptr< QgsRasterBlock > > &inputBlocks, int &row, int &col, bool &noDataInStack )
291 {
292  //get all values from inputBlocks
293  std::vector<double> cellValues;
294  bool hasNoData = false;
295  cellValues.reserve( inputBlocks.size() );
296 
297  for ( auto &block : inputBlocks )
298  {
299  double value = 0;
300  if ( !block || !block->isValid() )
301  {
302  noDataInStack = true;
303  break;
304  }
305  else
306  {
307  value = block->valueAndNoData( row, col, hasNoData );
308  if ( hasNoData )
309  {
310  noDataInStack = true;
311  continue; //NoData is not included in the cell value vector
312  }
313  else
314  {
315  cellValues.push_back( value );
316  }
317  }
318  }
319  return cellValues;
320 }
321 
322 double QgsRasterAnalysisUtils::meanFromCellValues( std::vector<double> &cellValues, int stackSize )
323 {
324  const double sum = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
325  const double mean = sum / static_cast<double>( stackSize );
326  return mean;
327 }
328 
329 double QgsRasterAnalysisUtils::medianFromCellValues( std::vector<double> &cellValues, int stackSize )
330 {
331  std::sort( cellValues.begin(), cellValues.end() );
332  const bool even = ( stackSize % 2 ) < 1;
333  if ( even )
334  {
335  return ( cellValues[stackSize / 2 - 1] + cellValues[stackSize / 2] ) / 2.0;
336  }
337  else //odd
338  {
339  return cellValues[( stackSize + 1 ) / 2 - 1];
340  }
341 }
342 
343 
344 double QgsRasterAnalysisUtils::stddevFromCellValues( std::vector<double> &cellValues, int stackSize )
345 {
346  const double variance = varianceFromCellValues( cellValues, stackSize );
347  const double stddev = std::sqrt( variance );
348  return stddev;
349 }
350 
351 double QgsRasterAnalysisUtils::varianceFromCellValues( std::vector<double> &cellValues, int stackSize )
352 {
353  const double mean = meanFromCellValues( cellValues, stackSize );
354  double accum = 0.0;
355  for ( int i = 0; i < stackSize; i++ )
356  {
357  accum += std::pow( ( cellValues.at( i ) - mean ), 2.0 );
358  }
359  const double variance = accum / static_cast<double>( stackSize );
360  return variance;
361 }
362 
363 double QgsRasterAnalysisUtils::maximumFromCellValues( std::vector<double> &cellValues )
364 {
365  return *std::max_element( cellValues.begin(), cellValues.end() );
366 }
367 
368 double QgsRasterAnalysisUtils::minimumFromCellValues( std::vector<double> &cellValues )
369 {
370  return *std::min_element( cellValues.begin(), cellValues.end() );
371 }
372 
373 double QgsRasterAnalysisUtils::majorityFromCellValues( std::vector<double> &cellValues, const double noDataValue, int stackSize )
374 {
375  if ( stackSize == 1 )
376  {
377  //output will be same as input if only one layer is entered
378  return cellValues[0];
379  }
380  else if ( stackSize == 2 )
381  {
382  //if only two layers are input, return NoData if values are not the same (eg. no Majority could be found)
383  return ( qgsDoubleNear( cellValues[0], cellValues[1] ) ) ? cellValues[0] : noDataValue;
384  }
385  else if ( std::adjacent_find( cellValues.begin(), cellValues.end(), std::not_equal_to<double>() ) == cellValues.end() )
386  {
387  //check if all values in cellValues are equal
388  //output will be same as input if all cellValues of the stack are the same
389  return cellValues[0];
390  }
391  else
392  {
393  //search for majority using hash map [O(n)]
394  std::unordered_map<double, int> map;
395 
396  for ( int i = 0; i < stackSize; i++ )
397  {
398  map[cellValues[i]]++;
399  }
400 
401  int maxCount = 0;
402  bool multipleMajorities = false;
403  double result = noDataValue;
404  for ( const auto &pair : std::as_const( map ) )
405  {
406  if ( maxCount < pair.second )
407  {
408  result = pair.first;
409  maxCount = pair.second;
410  multipleMajorities = false;
411  }
412  else if ( maxCount == pair.second )
413  {
414  multipleMajorities = true;
415  }
416  }
417  return multipleMajorities ? noDataValue : result;
418  }
419 }
420 
421 double QgsRasterAnalysisUtils::minorityFromCellValues( std::vector<double> &cellValues, const double noDataValue, int stackSize )
422 {
423  if ( stackSize == 1 )
424  {
425  //output will be same as input if only one layer is entered
426  return cellValues[0];
427  }
428  else if ( stackSize == 2 )
429  {
430  //if only two layers are input, return NoData if values are not the same (eg. no minority could be found)
431  return ( qgsDoubleNear( cellValues[0], cellValues[1] ) ) ? cellValues[0] : noDataValue;
432  }
433  else if ( std::adjacent_find( cellValues.begin(), cellValues.end(), std::not_equal_to<double>() ) == cellValues.end() )
434  {
435  //check if all values in cellValues are equal
436  //output will be same as input if all cellValues of the stack are the same
437  return cellValues[0];
438  }
439  else
440  {
441  //search for minority using hash map [O(n)]
442  std::unordered_map<double, int> map;
443 
444  for ( int i = 0; i < stackSize; i++ )
445  {
446  map[cellValues[i]]++;
447  }
448 
449  int minCount = stackSize;
450  bool multipleMinorities = false;
451  double result = noDataValue; //result will stay NoData if no minority value exists
452  for ( const auto &pair : std::as_const( map ) )
453  {
454  if ( minCount > pair.second )
455  {
456  result = pair.first;
457  minCount = pair.second;
458  multipleMinorities = false;
459  }
460  else if ( minCount == pair.second )
461  {
462  multipleMinorities = true;
463  }
464  }
465  return multipleMinorities ? noDataValue : result;
466  }
467 }
468 
469 double QgsRasterAnalysisUtils::rangeFromCellValues( std::vector<double> &cellValues )
470 {
471  const double max = *std::max_element( cellValues.begin(), cellValues.end() );
472  const double min = *std::min_element( cellValues.begin(), cellValues.end() );
473  return max - min;
474 }
475 
476 double QgsRasterAnalysisUtils::varietyFromCellValues( std::vector<double> &cellValues )
477 {
478  const std::unordered_set<double> uniqueValues( cellValues.begin(), cellValues.end() );
479  return uniqueValues.size();
480 }
481 
482 double QgsRasterAnalysisUtils::nearestRankPercentile( std::vector<double> &cellValues, int stackSize, double percentile )
483 {
484  //if percentile equals 0 -> pick the first element of the ordered list
485  std::sort( cellValues.begin(), cellValues.end() );
486 
487  int i = 0;
488  if ( percentile > 0 )
489  {
490  i = std::ceil( percentile * static_cast<double>( stackSize ) ) - 1;
491  }
492 
493  return cellValues[i];
494 }
495 
496 double QgsRasterAnalysisUtils::interpolatedPercentileInc( std::vector<double> &cellValues, int stackSize, double percentile )
497 {
498  std::sort( cellValues.begin(), cellValues.end() );
499 
500  if ( qgsDoubleNear( percentile, 1.0 ) )
501  {
502  return cellValues[stackSize - 1 ];
503  }
504  else if ( qgsDoubleNear( percentile, 0.0 ) )
505  {
506  return cellValues[0];
507  }
508 
509  const double x = ( percentile * ( stackSize - 1 ) );
510 
511  const int i = static_cast<int>( std::floor( x ) );
512  const double xFraction = std::fmod( x, 1 );
513 
514  if ( stackSize == 1 )
515  {
516  return cellValues[0];
517  }
518  else if ( stackSize == 2 )
519  {
520  return cellValues[0] + ( cellValues[1] - cellValues[0] ) * percentile;
521  }
522  else
523  {
524  return cellValues[i] + ( cellValues[i + 1] - cellValues[i] ) * xFraction;
525  }
526 }
527 
528 double QgsRasterAnalysisUtils::interpolatedPercentileExc( std::vector<double> &cellValues, int stackSize, double percentile, double noDataValue )
529 {
530  std::sort( cellValues.begin(), cellValues.end() );
531  const double x = ( percentile * ( stackSize + 1 ) );
532 
533  const int i = static_cast<int>( std::floor( x ) ) - 1;
534  const double xFraction = std::fmod( x, 1 );
535  const double lowerExcValue = 1.0 / ( static_cast<double>( stackSize ) + 1.0 );
536  const double upperExcValue = static_cast<double>( stackSize ) / ( static_cast<double>( stackSize ) + 1.0 );
537 
538  if ( stackSize < 2 || ( ( percentile < lowerExcValue || percentile > upperExcValue ) ) )
539  {
540  return noDataValue;
541  }
542  else
543  {
544  return cellValues[i] + ( cellValues[i + 1] - cellValues[i] ) * xFraction;
545  }
546 }
547 
548 double QgsRasterAnalysisUtils::interpolatedPercentRankInc( std::vector<double> &cellValues, int stackSize, double value, double noDataValue )
549 {
550  std::sort( cellValues.begin(), cellValues.end() );
551 
552  if ( value < cellValues[0] || value > cellValues[stackSize - 1] )
553  {
554  return noDataValue;
555  }
556  else
557  {
558  for ( int i = 0; i < stackSize - 1; i++ )
559  {
560  if ( cellValues[i] <= value && cellValues[i + 1] >= value )
561  {
562  double fraction = 0.0;
563 
564  //make sure that next number in the distribution is not the same to prevent NaN fractions
565  if ( !qgsDoubleNear( cellValues[i], cellValues[i + 1] ) )
566  fraction = ( value - cellValues[i] ) / ( cellValues[i + 1] - cellValues[i] );
567 
568  return ( fraction + i ) / ( stackSize - 1 );
569  }
570  }
571  return noDataValue;
572  }
573 }
574 
575 double QgsRasterAnalysisUtils::interpolatedPercentRankExc( std::vector<double> &cellValues, int stackSize, double value, double noDataValue )
576 {
577  std::sort( cellValues.begin(), cellValues.end() );
578 
579  if ( value < cellValues[0] || value > cellValues[stackSize - 1] )
580  {
581  return noDataValue;
582  }
583  else
584  {
585  for ( int i = 0; i < stackSize - 1; i++ )
586  {
587  if ( cellValues[i] <= value && cellValues[i + 1] >= value )
588  {
589  double fraction = 0.0;
590 
591  //make sure that next number in the distribution is not the same to prevent NaN fractions
592  if ( !qgsDoubleNear( cellValues[i], cellValues[i + 1] ) )
593  fraction = ( value - cellValues[i] ) / ( cellValues[i + 1] - cellValues[i] );
594 
595  return ( ( i + 1 ) + fraction ) / ( stackSize + 1 );
596  }
597  }
598  return noDataValue;
599  }
600 }
601 
602 
604 
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:76
Qgis::DataType::CInt16
@ CInt16
Complex Int16.
Qgis::DataType::UInt32
@ UInt32
Thirty two bit unsigned integer (quint32)
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
Qgis::DataType
DataType
Raster data types.
Definition: qgis.h:128
Qgis::DataType::Byte
@ Byte
Eight bit unsigned integer (quint8)
QgsFeedback::isCanceled
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:67
Qgis::DataType::Int32
@ Int32
Thirty two bit signed integer (qint32)
QgsRasterDataProvider::setEditable
virtual bool setEditable(bool enabled)
Turns on/off editing mode of the provider.
Definition: qgsrasterdataprovider.h:479
qgsrasteranalysisutils.h
QgsRectangle::intersect
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:333
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsGeometry::intersection
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
Definition: qgsgeometry.cpp:2616
qgsrasteriterator.h
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
qgsrasterblock.h
QgsRasterDataProvider::writeBlock
bool writeBlock(QgsRasterBlock *block, int band, int xOffset=0, int yOffset=0)
Writes pixel data from a raster block into the provider data source.
Definition: qgsrasterdataprovider.cpp:357
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsRasterIterator::DEFAULT_MAXIMUM_TILE_HEIGHT
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
Definition: qgsrasteriterator.h:170
Qgis::DataType::Float64
@ Float64
Sixty four bit floating point (double)
Qgis::DataType::CInt32
@ CInt32
Complex Int32.
Qgis::DataType::Int16
@ Int16
Sixteen bit signed integer (qint16)
QgsGeometry::isEmpty
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Definition: qgsgeometry.cpp:379
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsRasterIterator
Iterator for sequentially processing raster cells.
Definition: qgsrasteriterator.h:34
Qgis::DataType::UInt16
@ UInt16
Sixteen bit unsigned integer (quint16)
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
qgsprocessingparameters.h
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
Definition: qgsgeometry.cpp:3972
QgsRasterInterface
Base class for processing filters like renderers, reprojector, resampler etc.
Definition: qgsrasterinterface.h:135
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
Qgis::DataType::Float32
@ Float32
Thirty two bit floating point (float)
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsGeometry::fromRect
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
Definition: qgsgeometry.cpp:241
QgsRasterIterator::DEFAULT_MAXIMUM_TILE_WIDTH
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
Definition: qgsrasteriterator.h:167
Qgis::DataType::CFloat64
@ CFloat64
Complex Float64.
Qgis::DataType::CFloat32
@ CFloat32
Complex Float32.
qgsfeedback.h
QgsRectangle::isEmpty
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
QgsGeometry::area
double area() const
Returns the planar, 2-dimensional area of the geometry.
Definition: qgsgeometry.cpp:1880
QgsRasterDataProvider
Base class for raster data providers.
Definition: qgsrasterdataprovider.h:88
qgsgeos.h
qgssize
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:2791