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