QGIS API Documentation  2.99.0-Master (9fdd060)
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 
29 #include <QFile>
30 
31 QgsZonalStatistics::QgsZonalStatistics( QgsVectorLayer *polygonLayer, QgsRasterLayer *rasterLayer, const QString &attributePrefix, int rasterBand, QgsZonalStatistics::Statistics stats )
32  : mRasterLayer( rasterLayer )
33  , mRasterBand( rasterBand )
34  , mPolygonLayer( polygonLayer )
35  , mAttributePrefix( attributePrefix )
36  , mStatistics( stats )
37 {}
38 
40 {
41  if ( !mPolygonLayer || mPolygonLayer->geometryType() != QgsWkbTypes::PolygonGeometry )
42  {
43  return 1;
44  }
45 
46  QgsVectorDataProvider *vectorProvider = mPolygonLayer->dataProvider();
47  if ( !vectorProvider )
48  {
49  return 2;
50  }
51 
52  if ( !mRasterLayer )
53  {
54  return 3;
55  }
56 
57  if ( mRasterLayer->bandCount() < mRasterBand )
58  {
59  return 4;
60  }
61 
62  mRasterProvider = mRasterLayer->dataProvider();
63  mInputNodataValue = mRasterProvider->sourceNoDataValue( mRasterBand );
64 
65  //get geometry info about raster layer
66  int nCellsXProvider = mRasterProvider->xSize();
67  int nCellsYProvider = mRasterProvider->ySize();
68  double cellsizeX = mRasterLayer->rasterUnitsPerPixelX();
69  if ( cellsizeX < 0 )
70  {
71  cellsizeX = -cellsizeX;
72  }
73  double cellsizeY = mRasterLayer->rasterUnitsPerPixelY();
74  if ( cellsizeY < 0 )
75  {
76  cellsizeY = -cellsizeY;
77  }
78  QgsRectangle rasterBBox = mRasterProvider->extent();
79 
80  //add the new fields to the provider
81  QList<QgsField> newFieldList;
82  QString countFieldName;
83  if ( mStatistics & QgsZonalStatistics::Count )
84  {
85  countFieldName = getUniqueFieldName( mAttributePrefix + "count", newFieldList );
86  QgsField countField( countFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
87  newFieldList.push_back( countField );
88  }
89  QString sumFieldName;
90  if ( mStatistics & QgsZonalStatistics::Sum )
91  {
92  sumFieldName = getUniqueFieldName( mAttributePrefix + "sum", newFieldList );
93  QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
94  newFieldList.push_back( sumField );
95  }
96  QString meanFieldName;
97  if ( mStatistics & QgsZonalStatistics::Mean )
98  {
99  meanFieldName = getUniqueFieldName( mAttributePrefix + "mean", newFieldList );
100  QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
101  newFieldList.push_back( meanField );
102  }
103  QString medianFieldName;
104  if ( mStatistics & QgsZonalStatistics::Median )
105  {
106  medianFieldName = getUniqueFieldName( mAttributePrefix + "median", newFieldList );
107  QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
108  newFieldList.push_back( medianField );
109  }
110  QString stdevFieldName;
111  if ( mStatistics & QgsZonalStatistics::StDev )
112  {
113  stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev", newFieldList );
114  QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
115  newFieldList.push_back( stdField );
116  }
117  QString minFieldName;
118  if ( mStatistics & QgsZonalStatistics::Min )
119  {
120  minFieldName = getUniqueFieldName( mAttributePrefix + "min", newFieldList );
121  QgsField minField( minFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
122  newFieldList.push_back( minField );
123  }
124  QString maxFieldName;
125  if ( mStatistics & QgsZonalStatistics::Max )
126  {
127  maxFieldName = getUniqueFieldName( mAttributePrefix + "max", newFieldList );
128  QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
129  newFieldList.push_back( maxField );
130  }
131  QString rangeFieldName;
132  if ( mStatistics & QgsZonalStatistics::Range )
133  {
134  rangeFieldName = getUniqueFieldName( mAttributePrefix + "range", newFieldList );
135  QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
136  newFieldList.push_back( rangeField );
137  }
138  QString minorityFieldName;
139  if ( mStatistics & QgsZonalStatistics::Minority )
140  {
141  minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority", newFieldList );
142  QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
143  newFieldList.push_back( minorityField );
144  }
145  QString majorityFieldName;
146  if ( mStatistics & QgsZonalStatistics::Majority )
147  {
148  majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority", newFieldList );
149  QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
150  newFieldList.push_back( majField );
151  }
152  QString varietyFieldName;
153  if ( mStatistics & QgsZonalStatistics::Variety )
154  {
155  varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety", newFieldList );
156  QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) );
157  newFieldList.push_back( varietyField );
158  }
159  QString varianceFieldName;
160  if ( mStatistics & QgsZonalStatistics::Variance )
161  {
162  varianceFieldName = getUniqueFieldName( mAttributePrefix + "variance", newFieldList );
163  QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
164  newFieldList.push_back( varianceField );
165  }
166  vectorProvider->addAttributes( newFieldList );
167 
168  //index of the new fields
169  int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1;
170  int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1;
171  int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1;
172  int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1;
173  int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1;
174  int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1;
175  int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1;
176  int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1;
177  int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1;
178  int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1;
179  int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1;
180  int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->fieldNameIndex( varianceFieldName ) : -1;
181 
182  if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
183  || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
184  || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 )
185  || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 )
186  || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 )
187  || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 )
188  || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 )
189  || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 )
190  || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
191  || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
192  || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
193  || ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 )
194  )
195  {
196  //failed to create a required field
197  return 8;
198  }
199 
200  //progress dialog
201  long featureCount = vectorProvider->featureCount();
202 
203  //iterate over each polygon
204  QgsFeatureRequest request;
206  QgsFeatureIterator fi = vectorProvider->getFeatures( request );
207  QgsFeature f;
208 
209  bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) ||
210  ( mStatistics & QgsZonalStatistics::StDev ) ||
211  ( mStatistics & QgsZonalStatistics::Variance );
212  bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) ||
213  ( mStatistics & QgsZonalStatistics::Majority );
214 
215  FeatureStats featureStats( statsStoreValues, statsStoreValueCount );
216  int featureCounter = 0;
217 
218  QgsChangedAttributesMap changeMap;
219  while ( fi.nextFeature( f ) )
220  {
221  if ( feedback && feedback->isCanceled() )
222  {
223  break;
224  }
225 
226  if ( feedback )
227  {
228  feedback->setProgress( 100.0 * static_cast< double >( featureCounter ) / featureCount );
229  }
230 
231  if ( !f.hasGeometry() )
232  {
233  ++featureCounter;
234  continue;
235  }
236  QgsGeometry featureGeometry = f.geometry();
237 
238  QgsRectangle featureRect = featureGeometry.boundingBox().intersect( &rasterBBox );
239  if ( featureRect.isEmpty() )
240  {
241  ++featureCounter;
242  continue;
243  }
244 
245  int offsetX, offsetY, nCellsX, nCellsY;
246  if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 )
247  {
248  ++featureCounter;
249  continue;
250  }
251 
252  //avoid access to cells outside of the raster (may occur because of rounding)
253  if ( ( offsetX + nCellsX ) > nCellsXProvider )
254  {
255  nCellsX = nCellsXProvider - offsetX;
256  }
257  if ( ( offsetY + nCellsY ) > nCellsYProvider )
258  {
259  nCellsY = nCellsYProvider - offsetY;
260  }
261 
262  statisticsFromMiddlePointTest( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
263  rasterBBox, featureStats );
264 
265  if ( featureStats.count <= 1 )
266  {
267  //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case
268  statisticsFromPreciseIntersection( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
269  rasterBBox, featureStats );
270  }
271 
272  //write the statistics value to the vector data provider
273  QgsAttributeMap changeAttributeMap;
274  if ( mStatistics & QgsZonalStatistics::Count )
275  changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) );
276  if ( mStatistics & QgsZonalStatistics::Sum )
277  changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) );
278  if ( featureStats.count > 0 )
279  {
280  double mean = featureStats.sum / featureStats.count;
281  if ( mStatistics & QgsZonalStatistics::Mean )
282  changeAttributeMap.insert( meanIndex, QVariant( mean ) );
283  if ( mStatistics & QgsZonalStatistics::Median )
284  {
285  std::sort( featureStats.values.begin(), featureStats.values.end() );
286  int size = featureStats.values.count();
287  bool even = ( size % 2 ) < 1;
288  double medianValue;
289  if ( even )
290  {
291  medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2;
292  }
293  else //odd
294  {
295  medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 );
296  }
297  changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
298  }
299  if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance )
300  {
301  double sumSquared = 0;
302  for ( int i = 0; i < featureStats.values.count(); ++i )
303  {
304  double diff = featureStats.values.at( i ) - mean;
305  sumSquared += diff * diff;
306  }
307  double variance = sumSquared / featureStats.values.count();
308  if ( mStatistics & QgsZonalStatistics::StDev )
309  {
310  double stdev = std::pow( variance, 0.5 );
311  changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
312  }
313  if ( mStatistics & QgsZonalStatistics::Variance )
314  changeAttributeMap.insert( varianceIndex, QVariant( variance ) );
315  }
316  if ( mStatistics & QgsZonalStatistics::Min )
317  changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
318  if ( mStatistics & QgsZonalStatistics::Max )
319  changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) );
320  if ( mStatistics & QgsZonalStatistics::Range )
321  changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) );
322  if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority )
323  {
324  QList<int> vals = featureStats.valueCount.values();
325  std::sort( vals.begin(), vals.end() );
326  if ( mStatistics & QgsZonalStatistics::Minority )
327  {
328  float minorityKey = featureStats.valueCount.key( vals.first() );
329  changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) );
330  }
331  if ( mStatistics & QgsZonalStatistics::Majority )
332  {
333  float majKey = featureStats.valueCount.key( vals.last() );
334  changeAttributeMap.insert( majorityIndex, QVariant( majKey ) );
335  }
336  }
337  if ( mStatistics & QgsZonalStatistics::Variety )
338  changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) );
339  }
340 
341  changeMap.insert( f.id(), changeAttributeMap );
342  ++featureCounter;
343  }
344 
345  vectorProvider->changeAttributeValues( changeMap );
346 
347  if ( feedback )
348  {
349  feedback->setProgress( 100 );
350  }
351 
352  mPolygonLayer->updateFields();
353 
354  if ( feedback && feedback->isCanceled() )
355  {
356  return 9;
357  }
358 
359  return 0;
360 }
361 
362 int QgsZonalStatistics::cellInfoForBBox( const QgsRectangle &rasterBBox, const QgsRectangle &featureBBox, double cellSizeX, double cellSizeY,
363  int &offsetX, int &offsetY, int &nCellsX, int &nCellsY ) const
364 {
365  //get intersecting bbox
366  QgsRectangle intersectBox = rasterBBox.intersect( &featureBBox );
367  if ( intersectBox.isEmpty() )
368  {
369  nCellsX = 0;
370  nCellsY = 0;
371  offsetX = 0;
372  offsetY = 0;
373  return 0;
374  }
375 
376  //get offset in pixels in x- and y- direction
377  offsetX = ( int )( ( intersectBox.xMinimum() - rasterBBox.xMinimum() ) / cellSizeX );
378  offsetY = ( int )( ( rasterBBox.yMaximum() - intersectBox.yMaximum() ) / cellSizeY );
379 
380  int maxColumn = ( int )( ( intersectBox.xMaximum() - rasterBBox.xMinimum() ) / cellSizeX ) + 1;
381  int maxRow = ( int )( ( rasterBBox.yMaximum() - intersectBox.yMinimum() ) / cellSizeY ) + 1;
382 
383  nCellsX = maxColumn - offsetX;
384  nCellsY = maxRow - offsetY;
385 
386  return 0;
387 }
388 
389 void QgsZonalStatistics::statisticsFromMiddlePointTest( const QgsGeometry &poly, int pixelOffsetX,
390  int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
391 {
392  double cellCenterX, cellCenterY;
393 
394  cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
395  stats.reset();
396 
397  GEOSGeometry *polyGeos = poly.exportToGeos();
398  if ( !polyGeos )
399  {
400  return;
401  }
402 
403  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
404  const GEOSPreparedGeometry *polyGeosPrepared = GEOSPrepare_r( geosctxt, polyGeos );
405  if ( !polyGeosPrepared )
406  {
407  GEOSGeom_destroy_r( geosctxt, polyGeos );
408  return;
409  }
410 
411  GEOSCoordSequence *cellCenterCoords = nullptr;
412  GEOSGeometry *currentCellCenter = nullptr;
413 
414  QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox );
415  QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox );
416 
417  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  GEOSGeom_destroy_r( geosctxt, currentCellCenter );
426  cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
427  GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX );
428  GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY );
429  currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords );
430  if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) )
431  {
432  stats.addValue( block->value( i, j ) );
433  }
434  }
435  cellCenterX += cellSizeX;
436  }
437  cellCenterY -= cellSizeY;
438  }
439 
440  GEOSGeom_destroy_r( geosctxt, currentCellCenter );
441  GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared );
442  GEOSGeom_destroy_r( geosctxt, polyGeos );
443  delete block;
444 }
445 
446 void QgsZonalStatistics::statisticsFromPreciseIntersection( const QgsGeometry &poly, int pixelOffsetX,
447  int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
448 {
449  stats.reset();
450 
451  double currentY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
452  QgsGeometry pixelRectGeometry;
453 
454  double hCellSizeX = cellSizeX / 2.0;
455  double hCellSizeY = cellSizeY / 2.0;
456  double pixelArea = cellSizeX * cellSizeY;
457  double weight = 0;
458 
459  QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox );
460  QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox );
461 
462  QgsRasterBlock *block = mRasterProvider->block( mRasterBand, intersectBBox, nCellsX, nCellsY );
463  for ( int i = 0; i < nCellsY; ++i )
464  {
465  double currentX = rasterBBox.xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX;
466  for ( int j = 0; j < nCellsX; ++j )
467  {
468  if ( !validPixel( block->value( i, j ) ) )
469  {
470  continue;
471  }
472 
473  pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
474  if ( !pixelRectGeometry.isNull() )
475  {
476  //intersection
477  QgsGeometry intersectGeometry = pixelRectGeometry.intersection( poly );
478  if ( !intersectGeometry.isNull() )
479  {
480  double intersectionArea = intersectGeometry.area();
481  if ( intersectionArea >= 0.0 )
482  {
483  weight = intersectionArea / pixelArea;
484  stats.addValue( block->value( i, j ), weight );
485  }
486  }
487  pixelRectGeometry = QgsGeometry();
488  }
489  currentX += cellSizeX;
490  }
491  currentY -= cellSizeY;
492  }
493  delete block;
494 }
495 
496 bool QgsZonalStatistics::validPixel( float value ) const
497 {
498  return !( value == mInputNodataValue || std::isnan( value ) );
499 }
500 
501 QString QgsZonalStatistics::getUniqueFieldName( const QString &fieldName, const QList<QgsField> &newFields )
502 {
503  QgsVectorDataProvider *dp = mPolygonLayer->dataProvider();
504 
505  if ( !dp->storageType().contains( QLatin1String( "ESRI Shapefile" ) ) )
506  {
507  return fieldName;
508  }
509 
510  QList<QgsField> allFields = dp->fields().toList();
511  allFields.append( newFields );
512  QString shortName = fieldName.mid( 0, 10 );
513 
514  bool found = false;
515  for ( int idx = 0; idx < allFields.count(); ++idx )
516  {
517  if ( shortName == allFields.at( idx ).name() )
518  {
519  found = true;
520  break;
521  }
522  }
523 
524  if ( !found )
525  {
526  return shortName;
527  }
528 
529  int n = 1;
530  shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
531  found = true;
532  while ( found )
533  {
534  found = false;
535  for ( int idx = 0; idx < allFields.count(); ++idx )
536  {
537  if ( shortName == allFields.at( idx ).name() )
538  {
539  n += 1;
540  if ( n < 9 )
541  {
542  shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
543  }
544  else
545  {
546  shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n );
547  }
548  found = true;
549  }
550  }
551  }
552  return shortName;
553 }
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() )...
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:94
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.
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:119
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:104
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:109
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:114
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.