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