QGIS API Documentation  2.17.0-Master (dfeb663)
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 "qgsgeometry.h"
20 #include "qgsvectordataprovider.h"
21 #include "qgsvectorlayer.h"
22 #include "qmath.h"
23 #include "gdal.h"
24 #include "cpl_string.h"
25 #include <QProgressDialog>
26 #include <QFile>
27 
28 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
29 #define TO8F(x) (x).toUtf8().constData()
30 #else
31 #define TO8F(x) QFile::encodeName( x ).constData()
32 #endif
33 
34 QgsZonalStatistics::QgsZonalStatistics( QgsVectorLayer* polygonLayer, const QString& rasterFile, const QString& attributePrefix, int rasterBand, const Statistics& stats )
35  : mRasterFilePath( rasterFile )
36  , mRasterBand( rasterBand )
37  , mPolygonLayer( polygonLayer )
38  , mAttributePrefix( attributePrefix )
39  , mInputNodataValue( -1 )
40  , mStatistics( stats )
41 {
42 
43 }
44 
46  : mRasterBand( 0 )
47  , mPolygonLayer( nullptr )
48  , mInputNodataValue( -1 )
49  , mStatistics( QgsZonalStatistics::All )
50 {
51 
52 }
53 
55 {
56  if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon )
57  {
58  return 1;
59  }
60 
61  QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider();
62  if ( !vectorProvider )
63  {
64  return 2;
65  }
66 
67  //open the raster layer and the raster band
68  GDALAllRegister();
69  GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly );
70  if ( !inputDataset )
71  {
72  return 3;
73  }
74 
75  if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) )
76  {
77  GDALClose( inputDataset );
78  return 4;
79  }
80 
81  GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand );
82  if ( !rasterBand )
83  {
84  GDALClose( inputDataset );
85  return 5;
86  }
87  mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr );
88 
89  //get geometry info about raster layer
90  int nCellsXGDAL = GDALGetRasterXSize( inputDataset );
91  int nCellsYGDAL = GDALGetRasterYSize( inputDataset );
92  double geoTransform[6];
93  if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None )
94  {
95  GDALClose( inputDataset );
96  return 6;
97  }
98  double cellsizeX = geoTransform[1];
99  if ( cellsizeX < 0 )
100  {
101  cellsizeX = -cellsizeX;
102  }
103  double cellsizeY = geoTransform[5];
104  if ( cellsizeY < 0 )
105  {
106  cellsizeY = -cellsizeY;
107  }
108  QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ),
109  geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] );
110 
111  //add the new fields to the provider
112  QList<QgsField> newFieldList;
113  QString countFieldName;
114  if ( mStatistics & QgsZonalStatistics::Count )
115  {
116  countFieldName = getUniqueFieldName( mAttributePrefix + "count" );
117  QgsField countField( countFieldName, QVariant::Double, "double precision" );
118  newFieldList.push_back( countField );
119  }
120  QString sumFieldName;
121  if ( mStatistics & QgsZonalStatistics::Sum )
122  {
123  sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" );
124  QgsField sumField( sumFieldName, QVariant::Double, "double precision" );
125  newFieldList.push_back( sumField );
126  }
127  QString meanFieldName;
128  if ( mStatistics & QgsZonalStatistics::Mean )
129  {
130  meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" );
131  QgsField meanField( meanFieldName, QVariant::Double, "double precision" );
132  newFieldList.push_back( meanField );
133  }
134  QString medianFieldName;
135  if ( mStatistics & QgsZonalStatistics::Median )
136  {
137  medianFieldName = getUniqueFieldName( mAttributePrefix + "median" );
138  QgsField medianField( medianFieldName, QVariant::Double, "double precision" );
139  newFieldList.push_back( medianField );
140  }
141  QString stdevFieldName;
142  if ( mStatistics & QgsZonalStatistics::StDev )
143  {
144  stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev" );
145  QgsField stdField( stdevFieldName, QVariant::Double, "double precision" );
146  newFieldList.push_back( stdField );
147  }
148  QString minFieldName;
149  if ( mStatistics & QgsZonalStatistics::Min )
150  {
151  minFieldName = getUniqueFieldName( mAttributePrefix + "min" );
152  QgsField minField( minFieldName, QVariant::Double, "double precision" );
153  newFieldList.push_back( minField );
154  }
155  QString maxFieldName;
156  if ( mStatistics & QgsZonalStatistics::Max )
157  {
158  maxFieldName = getUniqueFieldName( mAttributePrefix + "max" );
159  QgsField maxField( maxFieldName, QVariant::Double, "double precision" );
160  newFieldList.push_back( maxField );
161  }
162  QString rangeFieldName;
163  if ( mStatistics & QgsZonalStatistics::Range )
164  {
165  rangeFieldName = getUniqueFieldName( mAttributePrefix + "range" );
166  QgsField rangeField( rangeFieldName, QVariant::Double, "double precision" );
167  newFieldList.push_back( rangeField );
168  }
169  QString minorityFieldName;
170  if ( mStatistics & QgsZonalStatistics::Minority )
171  {
172  minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority" );
173  QgsField minorityField( minorityFieldName, QVariant::Double, "double precision" );
174  newFieldList.push_back( minorityField );
175  }
176  QString majorityFieldName;
177  if ( mStatistics & QgsZonalStatistics::Majority )
178  {
179  majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority" );
180  QgsField majField( majorityFieldName, QVariant::Double, "double precision" );
181  newFieldList.push_back( majField );
182  }
183  QString varietyFieldName;
184  if ( mStatistics & QgsZonalStatistics::Variety )
185  {
186  varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety" );
187  QgsField varietyField( varietyFieldName, QVariant::Int, "int" );
188  newFieldList.push_back( varietyField );
189  }
190  vectorProvider->addAttributes( newFieldList );
191 
192  //index of the new fields
193  int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1;
194  int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1;
195  int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1;
196  int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1;
197  int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1;
198  int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1;
199  int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1;
200  int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1;
201  int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1;
202  int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1;
203  int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1;
204 
205  if (( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
206  || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
207  || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 )
208  || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 )
209  || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 )
210  || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 )
211  || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 )
212  || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 )
213  || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
214  || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
215  || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
216  )
217  {
218  //failed to create a required field
219  return 8;
220  }
221 
222  //progress dialog
223  long featureCount = vectorProvider->featureCount();
224  if ( p )
225  {
226  p->setMaximum( featureCount );
227  }
228 
229 
230  //iterate over each polygon
231  QgsFeatureRequest request;
233  QgsFeatureIterator fi = vectorProvider->getFeatures( request );
234  QgsFeature f;
235 
236  bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) ||
237  ( mStatistics & QgsZonalStatistics::StDev );
238  bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) ||
239  ( mStatistics & QgsZonalStatistics::Majority );
240 
241  FeatureStats featureStats( statsStoreValues, statsStoreValueCount );
242  int featureCounter = 0;
243 
244  QgsChangedAttributesMap changeMap;
245  while ( fi.nextFeature( f ) )
246  {
247  if ( p )
248  {
249  p->setValue( featureCounter );
250  }
251 
252  if ( p && p->wasCanceled() )
253  {
254  break;
255  }
256 
257  if ( !f.constGeometry() )
258  {
259  ++featureCounter;
260  continue;
261  }
262  const QgsGeometry* featureGeometry = f.constGeometry();
263 
264  QgsRectangle featureRect = featureGeometry->boundingBox().intersect( &rasterBBox );
265  if ( featureRect.isEmpty() )
266  {
267  ++featureCounter;
268  continue;
269  }
270 
271  int offsetX, offsetY, nCellsX, nCellsY;
272  if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 )
273  {
274  ++featureCounter;
275  continue;
276  }
277 
278  //avoid access to cells outside of the raster (may occur because of rounding)
279  if (( offsetX + nCellsX ) > nCellsXGDAL )
280  {
281  nCellsX = nCellsXGDAL - offsetX;
282  }
283  if (( offsetY + nCellsY ) > nCellsYGDAL )
284  {
285  nCellsY = nCellsYGDAL - offsetY;
286  }
287 
288  statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
289  rasterBBox, featureStats );
290 
291  if ( featureStats.count <= 1 )
292  {
293  //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case
294  statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
295  rasterBBox, featureStats );
296  }
297 
298  //write the statistics value to the vector data provider
299  QgsAttributeMap changeAttributeMap;
300  if ( mStatistics & QgsZonalStatistics::Count )
301  changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) );
302  if ( mStatistics & QgsZonalStatistics::Sum )
303  changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) );
304  if ( featureStats.count > 0 )
305  {
306  double mean = featureStats.sum / featureStats.count;
307  if ( mStatistics & QgsZonalStatistics::Mean )
308  changeAttributeMap.insert( meanIndex, QVariant( mean ) );
309  if ( mStatistics & QgsZonalStatistics::Median )
310  {
311  qSort( featureStats.values.begin(), featureStats.values.end() );
312  int size = featureStats.values.count();
313  bool even = ( size % 2 ) < 1;
314  double medianValue;
315  if ( even )
316  {
317  medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2;
318  }
319  else //odd
320  {
321  medianValue = featureStats.values.at(( size + 1 ) / 2 - 1 );
322  }
323  changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
324  }
325  if ( mStatistics & QgsZonalStatistics::StDev )
326  {
327  double sumSquared = 0;
328  for ( int i = 0; i < featureStats.values.count(); ++i )
329  {
330  double diff = featureStats.values.at( i ) - mean;
331  sumSquared += diff * diff;
332  }
333  double stdev = qPow( sumSquared / featureStats.values.count(), 0.5 );
334  changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
335  }
336  if ( mStatistics & QgsZonalStatistics::Min )
337  changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
338  if ( mStatistics & QgsZonalStatistics::Max )
339  changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) );
340  if ( mStatistics & QgsZonalStatistics::Range )
341  changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) );
342  if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority )
343  {
344  QList<int> vals = featureStats.valueCount.values();
345  qSort( vals.begin(), vals.end() );
346  if ( mStatistics & QgsZonalStatistics::Minority )
347  {
348  float minorityKey = featureStats.valueCount.key( vals.first() );
349  changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) );
350  }
351  if ( mStatistics & QgsZonalStatistics::Majority )
352  {
353  float majKey = featureStats.valueCount.key( vals.last() );
354  changeAttributeMap.insert( majorityIndex, QVariant( majKey ) );
355  }
356  }
357  if ( mStatistics & QgsZonalStatistics::Variety )
358  changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) );
359  }
360 
361  changeMap.insert( f.id(), changeAttributeMap );
362  ++featureCounter;
363  }
364 
365  vectorProvider->changeAttributeValues( changeMap );
366 
367  if ( p )
368  {
369  p->setValue( featureCount );
370  }
371 
372  GDALClose( inputDataset );
373  mPolygonLayer->updateFields();
374 
375  if ( p && p->wasCanceled() )
376  {
377  return 9;
378  }
379 
380  return 0;
381 }
382 
383 int QgsZonalStatistics::cellInfoForBBox( const QgsRectangle& rasterBBox, const QgsRectangle& featureBBox, double cellSizeX, double cellSizeY,
384  int& offsetX, int& offsetY, int& nCellsX, int& nCellsY ) const
385 {
386  //get intersecting bbox
387  QgsRectangle intersectBox = rasterBBox.intersect( &featureBBox );
388  if ( intersectBox.isEmpty() )
389  {
390  nCellsX = 0;
391  nCellsY = 0;
392  offsetX = 0;
393  offsetY = 0;
394  return 0;
395  }
396 
397  //get offset in pixels in x- and y- direction
398  offsetX = ( int )(( intersectBox.xMinimum() - rasterBBox.xMinimum() ) / cellSizeX );
399  offsetY = ( int )(( rasterBBox.yMaximum() - intersectBox.yMaximum() ) / cellSizeY );
400 
401  int maxColumn = ( int )(( intersectBox.xMaximum() - rasterBBox.xMinimum() ) / cellSizeX ) + 1;
402  int maxRow = ( int )(( rasterBBox.yMaximum() - intersectBox.yMinimum() ) / cellSizeY ) + 1;
403 
404  nCellsX = maxColumn - offsetX;
405  nCellsY = maxRow - offsetY;
406 
407  return 0;
408 }
409 
410 void QgsZonalStatistics::statisticsFromMiddlePointTest( void* band, const QgsGeometry* poly, int pixelOffsetX,
411  int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, FeatureStats &stats )
412 {
413  double cellCenterX, cellCenterY;
414 
415  float* scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX );
416  cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
417  stats.reset();
418 
419  const GEOSGeometry* polyGeos = poly->asGeos();
420  if ( !polyGeos )
421  {
422  return;
423  }
424 
425  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
426  const GEOSPreparedGeometry* polyGeosPrepared = GEOSPrepare_r( geosctxt, poly->asGeos() );
427  if ( !polyGeosPrepared )
428  {
429  return;
430  }
431 
432  GEOSCoordSequence* cellCenterCoords = nullptr;
433  GEOSGeometry* currentCellCenter = nullptr;
434 
435  for ( int i = 0; i < nCellsY; ++i )
436  {
437  if ( GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 )
438  != CPLE_None )
439  {
440  continue;
441  }
442  cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2;
443  for ( int j = 0; j < nCellsX; ++j )
444  {
445  if ( validPixel( scanLine[j] ) )
446  {
447  GEOSGeom_destroy_r( geosctxt, currentCellCenter );
448  cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
449  GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX );
450  GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY );
451  currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords );
452  if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) )
453  {
454  stats.addValue( scanLine[j] );
455  }
456  }
457  cellCenterX += cellSizeX;
458  }
459  cellCenterY -= cellSizeY;
460  }
461  GEOSGeom_destroy_r( geosctxt, currentCellCenter );
462  CPLFree( scanLine );
463  GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared );
464 }
465 
466 void QgsZonalStatistics::statisticsFromPreciseIntersection( void* band, const QgsGeometry* poly, int pixelOffsetX,
467  int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, FeatureStats &stats )
468 {
469  stats.reset();
470 
471  double currentY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
472  float* pixelData = ( float * ) CPLMalloc( sizeof( float ) );
473  QgsGeometry* pixelRectGeometry = nullptr;
474 
475  double hCellSizeX = cellSizeX / 2.0;
476  double hCellSizeY = cellSizeY / 2.0;
477  double pixelArea = cellSizeX * cellSizeY;
478  double weight = 0;
479 
480  for ( int row = 0; row < nCellsY; ++row )
481  {
482  double currentX = rasterBBox.xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX;
483  for ( int col = 0; col < nCellsX; ++col )
484  {
485  if ( GDALRasterIO( band, GF_Read, pixelOffsetX + col, pixelOffsetY + row, nCellsX, 1, pixelData, 1, 1, GDT_Float32, 0, 0 ) != CE_None )
486  {
487  QgsDebugMsg( "Raster IO Error" );
488  }
489 
490  if ( !validPixel( *pixelData ) )
491  continue;
492 
493  pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
494  if ( pixelRectGeometry )
495  {
496  //intersection
497  QgsGeometry *intersectGeometry = pixelRectGeometry->intersection( poly );
498  if ( intersectGeometry )
499  {
500  double intersectionArea = intersectGeometry->area();
501  if ( intersectionArea >= 0.0 )
502  {
503  weight = intersectionArea / pixelArea;
504  stats.addValue( *pixelData, weight );
505  }
506  delete intersectGeometry;
507  }
508  delete pixelRectGeometry;
509  pixelRectGeometry = nullptr;
510  }
511  currentX += cellSizeX;
512  }
513  currentY -= cellSizeY;
514  }
515  CPLFree( pixelData );
516 }
517 
518 bool QgsZonalStatistics::validPixel( float value ) const
519 {
520  if ( value == mInputNodataValue || qIsNaN( value ) )
521  {
522  return false;
523  }
524  return true;
525 }
526 
527 QString QgsZonalStatistics::getUniqueFieldName( const QString& fieldName )
528 {
529  QgsVectorDataProvider* dp = mPolygonLayer->dataProvider();
530 
531  if ( !dp->storageType().contains( "ESRI Shapefile" ) )
532  {
533  return fieldName;
534  }
535 
536  const QgsFields& providerFields = dp->fields();
537  QString shortName = fieldName.mid( 0, 10 );
538 
539  bool found = false;
540  for ( int idx = 0; idx < providerFields.count(); ++idx )
541  {
542  if ( shortName == providerFields[idx].name() )
543  {
544  found = true;
545  break;
546  }
547  }
548 
549  if ( !found )
550  {
551  return shortName;
552  }
553 
554  int n = 1;
555  shortName = QString( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
556  found = true;
557  while ( found )
558  {
559  found = false;
560  for ( int idx = 0; idx < providerFields.count(); ++idx )
561  {
562  if ( shortName == providerFields[idx].name() )
563  {
564  n += 1;
565  if ( n < 9 )
566  {
567  shortName = QString( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
568  }
569  else
570  {
571  shortName = QString( "%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n );
572  }
573  found = true;
574  }
575  }
576  }
577  return shortName;
578 }
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
Wrapper for iterator of features from vector data provider or vector layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes.
void setMaximum(int maximum)
void push_back(const T &value)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
Definition: qgsfield.h:252
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
QgsRectangle intersect(const QgsRectangle *rect) const
return the intersection with the given rectangle
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
int count() const
Return number of items.
Definition: qgsfield.cpp:402
Median of pixel values.
Minority of pixel values.
Variety (count of distinct) pixel values.
void setValue(int progress)
bool isEmpty() const
test if rectangle is empty.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
Sum of pixel values.
virtual long featureCount() const =0
Number of features in the layer.
Majority of pixel values.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())=0
Query the provider for features specified in request.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
T & first()
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
void * GDALDatasetH
Max of pixel values.
iterator end()
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
bool contains(QChar ch, Qt::CaseSensitivity cs) const
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:202
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:187
#define TO8F(x)
Mean of pixel values.
Range of pixel values (max - min)
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
int calculateStatistics(QProgressDialog *p)
Starts the calculation.
QString mid(int position, int n) const
static GEOSContextHandle_t getGEOSHandler()
Return GEOS context handle.
const GEOSGeometry * asGeos(double precision=0) const
Returns a geos geometry.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
T & last()
QgsGeometry * intersection(const QgsGeometry *geometry) const
Returns a geometry representing the points shared by this geometry and other.
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:192
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:197
iterator insert(const Key &key, const T &value)
Min of pixel values.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QgsZonalStatistics(QgsVectorLayer *polygonLayer, const QString &rasterFile, const QString &attributePrefix="", int rasterBand=1, const Statistics &stats=Statistics(Count|Sum|Mean))
double area() const
Returns the area of the geometry using GEOS.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
Represents a vector layer which manages a vector based data sets.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
iterator begin()
Standard deviation of pixel values.