QGIS API Documentation 3.40.0-Bratislava (b56115d8743)
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,
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
62void 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< QgsGeos > polyEngine = std::make_unique< QgsGeos >( 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 if ( polyEngine->contains( cellCenterX, cellCenterY ) )
94 {
95 addValue( pixelValue );
96 }
97 }
98 cellCenterX += cellSizeX;
99 }
100 cellCenterY -= cellSizeY;
101 }
102 }
103}
104
105void 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 )
106{
107 QgsGeometry pixelRectGeometry;
108
109 const double hCellSizeX = cellSizeX / 2.0;
110 const double hCellSizeY = cellSizeY / 2.0;
111 const double pixelArea = cellSizeX * cellSizeY;
112 double weight = 0;
113
114 std::unique_ptr< QgsGeometryEngine > polyEngine( QgsGeometry::createGeometryEngine( poly.constGet( ) ) );
115 if ( !polyEngine )
116 {
117 return;
118 }
119 polyEngine->prepareGeometry();
120
121 QgsRasterIterator iter( rasterInterface );
122 iter.startRasterRead( rasterBand, nCellsX, nCellsY, rasterBBox );
123
124 std::unique_ptr< QgsRasterBlock > block;
125 int iterLeft = 0;
126 int iterTop = 0;
127 int iterCols = 0;
128 int iterRows = 0;
129 QgsRectangle blockExtent;
130 bool isNoData = false;
131 while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
132 {
133 double currentY = blockExtent.yMaximum() - 0.5 * cellSizeY;
134 for ( int row = 0; row < iterRows; ++row )
135 {
136 double currentX = blockExtent.xMinimum() + 0.5 * cellSizeX;
137 for ( int col = 0; col < iterCols; ++col )
138 {
139 const double pixelValue = block->valueAndNoData( row, col, isNoData );
140 if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
141 {
142 pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
143 // GEOS intersects tests on prepared geometry is MAGNITUDES faster than calculating the intersection itself,
144 // so we first test to see if there IS an intersection before doing the actual calculation
145 if ( !pixelRectGeometry.isNull() && polyEngine->intersects( pixelRectGeometry.constGet() ) )
146 {
147 //intersection
148 const QgsGeometry intersectGeometry = pixelRectGeometry.intersection( poly );
149 if ( !intersectGeometry.isEmpty() )
150 {
151 const double intersectionArea = intersectGeometry.area();
152 if ( intersectionArea > 0.0 )
153 {
154 weight = intersectionArea / pixelArea;
155 addValue( pixelValue, weight );
156 }
157 }
158 }
159 }
160 currentX += cellSizeX;
161 }
162 currentY -= cellSizeY;
163 }
164 }
165}
166
167bool QgsRasterAnalysisUtils::validPixel( double value )
168{
169 return !std::isnan( value );
170}
171
172void QgsRasterAnalysisUtils::mapToPixel( const double x, const double y, const QgsRectangle bounds, const double unitsPerPixelX, const double unitsPerPixelY, int &px, int &py )
173{
174 px = trunc( ( x - bounds.xMinimum() ) / unitsPerPixelX );
175 py = trunc( ( y - bounds.yMaximum() ) / -unitsPerPixelY );
176}
177
178void QgsRasterAnalysisUtils::pixelToMap( const int px, const int py, const QgsRectangle bounds, const double unitsPerPixelX, const double unitsPerPixelY, double &x, double &y )
179{
180 x = bounds.xMinimum() + ( px + 0.5 ) * unitsPerPixelX;
181 y = bounds.yMaximum() - ( py + 0.5 ) * unitsPerPixelY;
182}
183
184static QVector< QPair< QString, Qgis::DataType > > sDataTypes;
185
186void populateDataTypes()
187{
188 if ( sDataTypes.empty() )
189 {
190 sDataTypes.append( qMakePair( QStringLiteral( "Byte" ), Qgis::DataType::Byte ) );
191 sDataTypes.append( qMakePair( QStringLiteral( "Int16" ), Qgis::DataType::Int16 ) );
192 sDataTypes.append( qMakePair( QStringLiteral( "UInt16" ), Qgis::DataType::UInt16 ) );
193 sDataTypes.append( qMakePair( QStringLiteral( "Int32" ), Qgis::DataType::Int32 ) );
194 sDataTypes.append( qMakePair( QStringLiteral( "UInt32" ), Qgis::DataType::UInt32 ) );
195 sDataTypes.append( qMakePair( QStringLiteral( "Float32" ), Qgis::DataType::Float32 ) );
196 sDataTypes.append( qMakePair( QStringLiteral( "Float64" ), Qgis::DataType::Float64 ) );
197 sDataTypes.append( qMakePair( QStringLiteral( "CInt16" ), Qgis::DataType::CInt16 ) );
198 sDataTypes.append( qMakePair( QStringLiteral( "CInt32" ), Qgis::DataType::CInt32 ) );
199 sDataTypes.append( qMakePair( QStringLiteral( "CFloat32" ), Qgis::DataType::CFloat32 ) );
200 sDataTypes.append( qMakePair( QStringLiteral( "CFloat64" ), Qgis::DataType::CFloat64 ) );
201 sDataTypes.append( qMakePair( QStringLiteral( "Int8" ), Qgis::DataType::Int8 ) );
202 }
203}
204
205std::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
223Qgis::DataType QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( int choice )
224{
225 if ( choice < 0 || choice >= sDataTypes.count() )
227
228 return sDataTypes.value( choice ).second;
229}
230
231void 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
290std::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
322double 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
329double 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
344double 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
351double 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
363double QgsRasterAnalysisUtils::maximumFromCellValues( std::vector<double> &cellValues )
364{
365 return *std::max_element( cellValues.begin(), cellValues.end() );
366}
367
368double QgsRasterAnalysisUtils::minimumFromCellValues( std::vector<double> &cellValues )
369{
370 return *std::min_element( cellValues.begin(), cellValues.end() );
371}
372
373double 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
421double 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
469double 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
476double QgsRasterAnalysisUtils::varietyFromCellValues( std::vector<double> &cellValues )
477{
478 const std::unordered_set<double> uniqueValues( cellValues.begin(), cellValues.end() );
479 return uniqueValues.size();
480}
481
482double 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
496double 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
528double 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
548double 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
575double 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
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)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
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() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
bool isEmpty() const
Returns true if the rectangle has no area.
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:6465
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:5917