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