QGIS API Documentation  2.99.0-Master (19b062c)
qgszonalstatistics.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgszonalstatistics.cpp - description
3  ----------------------------
4  begin : August 29th, 2009
5  copyright : (C) 2009 by Marco Hugentobler
6  email : marco at hugis dot net
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 "qgszonalstatistics.h"
19 #include "qgsfeatureiterator.h"
20 #include "qgsfeedback.h"
21 #include "qgsgeometry.h"
22 #include "qgsvectordataprovider.h"
23 #include "qgsvectorlayer.h"
24 #include "qgsrasterdataprovider.h"
25 #include "qgsrasterlayer.h"
26 #include "qgsrasterblock.h"
27 #include "qgslogger.h"
28 #include "qgsgeos.h"
29 
30 #include <QFile>
31 
32 QgsZonalStatistics::QgsZonalStatistics( QgsVectorLayer *polygonLayer, QgsRasterLayer *rasterLayer, const QString &attributePrefix, int rasterBand, QgsZonalStatistics::Statistics stats )
33  : mRasterLayer( rasterLayer )
34  , mRasterBand( rasterBand )
35  , mPolygonLayer( polygonLayer )
36  , mAttributePrefix( attributePrefix )
37  , mStatistics( stats )
38 {}
39 
41 {
42  if ( !mPolygonLayer || mPolygonLayer->geometryType() != QgsWkbTypes::PolygonGeometry )
43  {
44  return 1;
45  }
46 
47  QgsVectorDataProvider *vectorProvider = mPolygonLayer->dataProvider();
48  if ( !vectorProvider )
49  {
50  return 2;
51  }
52 
53  if ( !mRasterLayer )
54  {
55  return 3;
56  }
57 
58  if ( mRasterLayer->bandCount() < mRasterBand )
59  {
60  return 4;
61  }
62 
63  mRasterProvider = mRasterLayer->dataProvider();
64  mInputNodataValue = mRasterProvider->sourceNoDataValue( mRasterBand );
65 
66  //get geometry info about raster layer
67  int nCellsXProvider = mRasterProvider->xSize();
68  int nCellsYProvider = mRasterProvider->ySize();
69  double cellsizeX = mRasterLayer->rasterUnitsPerPixelX();
70  if ( cellsizeX < 0 )
71  {
72  cellsizeX = -cellsizeX;
73  }
74  double cellsizeY = mRasterLayer->rasterUnitsPerPixelY();
75  if ( cellsizeY < 0 )
76  {
77  cellsizeY = -cellsizeY;
78  }
79  QgsRectangle rasterBBox = mRasterProvider->extent();
80 
81  //add the new fields to the provider
82  QList<QgsField> newFieldList;
83  QString countFieldName;
84  if ( mStatistics & QgsZonalStatistics::Count )
85  {
86  countFieldName = getUniqueFieldName( mAttributePrefix + "count", newFieldList );
87  QgsField countField( countFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
88  newFieldList.push_back( countField );
89  }
90  QString sumFieldName;
91  if ( mStatistics & QgsZonalStatistics::Sum )
92  {
93  sumFieldName = getUniqueFieldName( mAttributePrefix + "sum", newFieldList );
94  QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
95  newFieldList.push_back( sumField );
96  }
97  QString meanFieldName;
98  if ( mStatistics & QgsZonalStatistics::Mean )
99  {
100  meanFieldName = getUniqueFieldName( mAttributePrefix + "mean", newFieldList );
101  QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
102  newFieldList.push_back( meanField );
103  }
104  QString medianFieldName;
105  if ( mStatistics & QgsZonalStatistics::Median )
106  {
107  medianFieldName = getUniqueFieldName( mAttributePrefix + "median", newFieldList );
108  QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
109  newFieldList.push_back( medianField );
110  }
111  QString stdevFieldName;
112  if ( mStatistics & QgsZonalStatistics::StDev )
113  {
114  stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev", newFieldList );
115  QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
116  newFieldList.push_back( stdField );
117  }
118  QString minFieldName;
119  if ( mStatistics & QgsZonalStatistics::Min )
120  {
121  minFieldName = getUniqueFieldName( mAttributePrefix + "min", newFieldList );
122  QgsField minField( minFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
123  newFieldList.push_back( minField );
124  }
125  QString maxFieldName;
126  if ( mStatistics & QgsZonalStatistics::Max )
127  {
128  maxFieldName = getUniqueFieldName( mAttributePrefix + "max", newFieldList );
129  QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
130  newFieldList.push_back( maxField );
131  }
132  QString rangeFieldName;
133  if ( mStatistics & QgsZonalStatistics::Range )
134  {
135  rangeFieldName = getUniqueFieldName( mAttributePrefix + "range", newFieldList );
136  QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
137  newFieldList.push_back( rangeField );
138  }
139  QString minorityFieldName;
140  if ( mStatistics & QgsZonalStatistics::Minority )
141  {
142  minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority", newFieldList );
143  QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
144  newFieldList.push_back( minorityField );
145  }
146  QString majorityFieldName;
147  if ( mStatistics & QgsZonalStatistics::Majority )
148  {
149  majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority", newFieldList );
150  QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
151  newFieldList.push_back( majField );
152  }
153  QString varietyFieldName;
154  if ( mStatistics & QgsZonalStatistics::Variety )
155  {
156  varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety", newFieldList );
157  QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) );
158  newFieldList.push_back( varietyField );
159  }
160  QString varianceFieldName;
161  if ( mStatistics & QgsZonalStatistics::Variance )
162  {
163  varianceFieldName = getUniqueFieldName( mAttributePrefix + "variance", newFieldList );
164  QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
165  newFieldList.push_back( varianceField );
166  }
167  vectorProvider->addAttributes( newFieldList );
168 
169  //index of the new fields
170  int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1;
171  int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1;
172  int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1;
173  int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1;
174  int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1;
175  int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1;
176  int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1;
177  int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1;
178  int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1;
179  int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1;
180  int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1;
181  int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->fieldNameIndex( varianceFieldName ) : -1;
182 
183  if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
184  || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
185  || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 )
186  || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 )
187  || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 )
188  || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 )
189  || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 )
190  || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 )
191  || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
192  || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
193  || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
194  || ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 )
195  )
196  {
197  //failed to create a required field
198  return 8;
199  }
200 
201  //progress dialog
202  long featureCount = vectorProvider->featureCount();
203 
204  //iterate over each polygon
205  QgsFeatureRequest request;
207  QgsFeatureIterator fi = vectorProvider->getFeatures( request );
208  QgsFeature f;
209 
210  bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) ||
211  ( mStatistics & QgsZonalStatistics::StDev ) ||
212  ( mStatistics & QgsZonalStatistics::Variance );
213  bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) ||
214  ( mStatistics & QgsZonalStatistics::Majority );
215 
216  FeatureStats featureStats( statsStoreValues, statsStoreValueCount );
217  int featureCounter = 0;
218 
219  QgsChangedAttributesMap changeMap;
220  while ( fi.nextFeature( f ) )
221  {
222  if ( feedback && feedback->isCanceled() )
223  {
224  break;
225  }
226 
227  if ( feedback )
228  {
229  feedback->setProgress( 100.0 * static_cast< double >( featureCounter ) / featureCount );
230  }
231 
232  if ( !f.hasGeometry() )
233  {
234  ++featureCounter;
235  continue;
236  }
237  QgsGeometry featureGeometry = f.geometry();
238 
239  QgsRectangle featureRect = featureGeometry.boundingBox().intersect( &rasterBBox );
240  if ( featureRect.isEmpty() )
241  {
242  ++featureCounter;
243  continue;
244  }
245 
246  int offsetX, offsetY, nCellsX, nCellsY;
247  if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 )
248  {
249  ++featureCounter;
250  continue;
251  }
252 
253  //avoid access to cells outside of the raster (may occur because of rounding)
254  if ( ( offsetX + nCellsX ) > nCellsXProvider )
255  {
256  nCellsX = nCellsXProvider - offsetX;
257  }
258  if ( ( offsetY + nCellsY ) > nCellsYProvider )
259  {
260  nCellsY = nCellsYProvider - offsetY;
261  }
262 
263  statisticsFromMiddlePointTest( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
264  rasterBBox, featureStats );
265 
266  if ( featureStats.count <= 1 )
267  {
268  //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case
269  statisticsFromPreciseIntersection( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
270  rasterBBox, featureStats );
271  }
272 
273  //write the statistics value to the vector data provider
274  QgsAttributeMap changeAttributeMap;
275  if ( mStatistics & QgsZonalStatistics::Count )
276  changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) );
277  if ( mStatistics & QgsZonalStatistics::Sum )
278  changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) );
279  if ( featureStats.count > 0 )
280  {
281  double mean = featureStats.sum / featureStats.count;
282  if ( mStatistics & QgsZonalStatistics::Mean )
283  changeAttributeMap.insert( meanIndex, QVariant( mean ) );
284  if ( mStatistics & QgsZonalStatistics::Median )
285  {
286  std::sort( featureStats.values.begin(), featureStats.values.end() );
287  int size = featureStats.values.count();
288  bool even = ( size % 2 ) < 1;
289  double medianValue;
290  if ( even )
291  {
292  medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2;
293  }
294  else //odd
295  {
296  medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 );
297  }
298  changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
299  }
300  if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance )
301  {
302  double sumSquared = 0;
303  for ( int i = 0; i < featureStats.values.count(); ++i )
304  {
305  double diff = featureStats.values.at( i ) - mean;
306  sumSquared += diff * diff;
307  }
308  double variance = sumSquared / featureStats.values.count();
309  if ( mStatistics & QgsZonalStatistics::StDev )
310  {
311  double stdev = std::pow( variance, 0.5 );
312  changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
313  }
314  if ( mStatistics & QgsZonalStatistics::Variance )
315  changeAttributeMap.insert( varianceIndex, QVariant( variance ) );
316  }
317  if ( mStatistics & QgsZonalStatistics::Min )
318  changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
319  if ( mStatistics & QgsZonalStatistics::Max )
320  changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) );
321  if ( mStatistics & QgsZonalStatistics::Range )
322  changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) );
323  if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority )
324  {
325  QList<int> vals = featureStats.valueCount.values();
326  std::sort( vals.begin(), vals.end() );
327  if ( mStatistics & QgsZonalStatistics::Minority )
328  {
329  float minorityKey = featureStats.valueCount.key( vals.first() );
330  changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) );
331  }
332  if ( mStatistics & QgsZonalStatistics::Majority )
333  {
334  float majKey = featureStats.valueCount.key( vals.last() );
335  changeAttributeMap.insert( majorityIndex, QVariant( majKey ) );
336  }
337  }
338  if ( mStatistics & QgsZonalStatistics::Variety )
339  changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) );
340  }
341 
342  changeMap.insert( f.id(), changeAttributeMap );
343  ++featureCounter;
344  }
345 
346  vectorProvider->changeAttributeValues( changeMap );
347 
348  if ( feedback )
349  {
350  feedback->setProgress( 100 );
351  }
352 
353  mPolygonLayer->updateFields();
354 
355  if ( feedback && feedback->isCanceled() )
356  {
357  return 9;
358  }
359 
360  return 0;
361 }
362 
363 int QgsZonalStatistics::cellInfoForBBox( const QgsRectangle &rasterBBox, const QgsRectangle &featureBBox, double cellSizeX, double cellSizeY,
364  int &offsetX, int &offsetY, int &nCellsX, int &nCellsY ) const
365 {
366  //get intersecting bbox
367  QgsRectangle intersectBox = rasterBBox.intersect( &featureBBox );
368  if ( intersectBox.isEmpty() )
369  {
370  nCellsX = 0;
371  nCellsY = 0;
372  offsetX = 0;
373  offsetY = 0;
374  return 0;
375  }
376 
377  //get offset in pixels in x- and y- direction
378  offsetX = ( int )( ( intersectBox.xMinimum() - rasterBBox.xMinimum() ) / cellSizeX );
379  offsetY = ( int )( ( rasterBBox.yMaximum() - intersectBox.yMaximum() ) / cellSizeY );
380 
381  int maxColumn = ( int )( ( intersectBox.xMaximum() - rasterBBox.xMinimum() ) / cellSizeX ) + 1;
382  int maxRow = ( int )( ( rasterBBox.yMaximum() - intersectBox.yMinimum() ) / cellSizeY ) + 1;
383 
384  nCellsX = maxColumn - offsetX;
385  nCellsY = maxRow - offsetY;
386 
387  return 0;
388 }
389 
390 void QgsZonalStatistics::statisticsFromMiddlePointTest( const QgsGeometry &poly, int pixelOffsetX,
391  int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
392 {
393  double cellCenterX, cellCenterY;
394 
395  cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
396  stats.reset();
397 
398  geos::unique_ptr polyGeos( poly.exportToGeos() );
399  if ( !polyGeos )
400  {
401  return;
402  }
403 
404  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
405  geos::prepared_unique_ptr polyGeosPrepared( GEOSPrepare_r( geosctxt, polyGeos.get() ) );
406  if ( !polyGeosPrepared )
407  {
408  return;
409  }
410 
411  GEOSCoordSequence *cellCenterCoords = nullptr;
412  geos::unique_ptr currentCellCenter;
413 
414  QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox );
415  QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox );
416 
417  std::unique_ptr< QgsRasterBlock > block( mRasterProvider->block( mRasterBand, intersectBBox, nCellsX, nCellsY ) );
418  for ( int i = 0; i < nCellsY; ++i )
419  {
420  cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2;
421  for ( int j = 0; j < nCellsX; ++j )
422  {
423  if ( validPixel( block->value( i, j ) ) )
424  {
425  cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
426  GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX );
427  GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY );
428  currentCellCenter.reset( GEOSGeom_createPoint_r( geosctxt, cellCenterCoords ) );
429  if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared.get(), currentCellCenter.get() ) )
430  {
431  stats.addValue( block->value( i, j ) );
432  }
433  }
434  cellCenterX += cellSizeX;
435  }
436  cellCenterY -= cellSizeY;
437  }
438 }
439 
440 void QgsZonalStatistics::statisticsFromPreciseIntersection( const QgsGeometry &poly, int pixelOffsetX,
441  int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
442 {
443  stats.reset();
444 
445  double currentY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
446  QgsGeometry pixelRectGeometry;
447 
448  double hCellSizeX = cellSizeX / 2.0;
449  double hCellSizeY = cellSizeY / 2.0;
450  double pixelArea = cellSizeX * cellSizeY;
451  double weight = 0;
452 
453  QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox );
454  QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox );
455 
456  QgsRasterBlock *block = mRasterProvider->block( mRasterBand, intersectBBox, nCellsX, nCellsY );
457  for ( int i = 0; i < nCellsY; ++i )
458  {
459  double currentX = rasterBBox.xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX;
460  for ( int j = 0; j < nCellsX; ++j )
461  {
462  if ( !validPixel( block->value( i, j ) ) )
463  {
464  continue;
465  }
466 
467  pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
468  if ( !pixelRectGeometry.isNull() )
469  {
470  //intersection
471  QgsGeometry intersectGeometry = pixelRectGeometry.intersection( poly );
472  if ( !intersectGeometry.isNull() )
473  {
474  double intersectionArea = intersectGeometry.area();
475  if ( intersectionArea >= 0.0 )
476  {
477  weight = intersectionArea / pixelArea;
478  stats.addValue( block->value( i, j ), weight );
479  }
480  }
481  pixelRectGeometry = QgsGeometry();
482  }
483  currentX += cellSizeX;
484  }
485  currentY -= cellSizeY;
486  }
487  delete block;
488 }
489 
490 bool QgsZonalStatistics::validPixel( float value ) const
491 {
492  return !( value == mInputNodataValue || std::isnan( value ) );
493 }
494 
495 QString QgsZonalStatistics::getUniqueFieldName( const QString &fieldName, const QList<QgsField> &newFields )
496 {
497  QgsVectorDataProvider *dp = mPolygonLayer->dataProvider();
498 
499  if ( !dp->storageType().contains( QLatin1String( "ESRI Shapefile" ) ) )
500  {
501  return fieldName;
502  }
503 
504  QList<QgsField> allFields = dp->fields().toList();
505  allFields.append( newFields );
506  QString shortName = fieldName.mid( 0, 10 );
507 
508  bool found = false;
509  for ( int idx = 0; idx < allFields.count(); ++idx )
510  {
511  if ( shortName == allFields.at( idx ).name() )
512  {
513  found = true;
514  break;
515  }
516  }
517 
518  if ( !found )
519  {
520  return shortName;
521  }
522 
523  int n = 1;
524  shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
525  found = true;
526  while ( found )
527  {
528  found = false;
529  for ( int idx = 0; idx < allFields.count(); ++idx )
530  {
531  if ( shortName == allFields.at( idx ).name() )
532  {
533  n += 1;
534  if ( n < 9 )
535  {
536  shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
537  }
538  else
539  {
540  shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n );
541  }
542  found = true;
543  }
544  }
545  }
546  return shortName;
547 }
virtual QgsRectangle extent() const override=0
Returns the extent of the layer.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider...
QgsFeatureId id
Definition: qgsfeature.h:71
Wrapper for iterator of features from vector data provider or vector layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:39
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes to the provider.
int bandCount() const
Get the number of bands in this layer.
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter > prepared_unique_ptr
Scoped GEOS prepared geometry pointer.
Definition: qgsgeos.h:79
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis. In a world file, this is normally the first row (without the sign)
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
virtual int ySize() const
QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis. In a world file, this is normally the first row (without the sign)
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
QgsRectangle intersect(const QgsRectangle *rect) const
Return the intersection with the given rectangle.
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
virtual QgsFields fields() const override=0
Returns the fields associated with this data provider.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:190
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
Median of pixel values.
Minority of pixel values.
Variety (count of distinct) pixel values.
Base class for feedback objects to be used for cancelation of something running in a worker thread...
Definition: qgsfeedback.h:44
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
Variance of pixel values.
QgsRasterDataProvider * dataProvider() override
Raster data container.
bool isEmpty() const
Returns true if the rectangle is empty.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
Definition: qgsgeos.h:74
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:39
Sum of pixel values.
Majority of pixel values.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:101
int calculateStatistics(QgsFeedback *feedback)
Starts the calculation.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override=0
Query the provider for features specified in request.
Max of pixel values.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:126
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:111
Mean of pixel values.
Range of pixel values (max - min)
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:528
static GEOSContextHandle_t getGEOSHandler()
Return GEOS context handle.
GEOSGeometry * exportToGeos(double precision=0) const
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
QgsZonalStatistics(QgsVectorLayer *polygonLayer, QgsRasterLayer *rasterLayer, const QString &attributePrefix=QString(), int rasterBand=1, QgsZonalStatistics::Statistics stats=QgsZonalStatistics::Statistics(QgsZonalStatistics::Count|QgsZonalStatistics::Sum|QgsZonalStatistics::Mean))
Constructor for QgsZonalStatistics.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
Definition: qgsfields.cpp:194
QgsVectorDataProvider * dataProvider() override
Returns the layer&#39;s data provider.
double value(int row, int column) const
Read a single value if type of block is numeric.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:116
virtual long featureCount() const override=0
Number of features in the layer.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:121
Min of pixel values.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QList< int > QgsAttributeList
Definition: qgsfield.h:27
double area() const
Returns the area of the geometry using GEOS.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
Represents a vector layer which manages a vector based data sets.
virtual int xSize() const
Get raster size.
Standard deviation of pixel values.