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