35                         rasterLayer ? rasterLayer->dataProvider() : nullptr,
    37                         rasterLayer ? rasterLayer->rasterUnitsPerPixelX() : 0,
    38                         rasterLayer ? rasterLayer->rasterUnitsPerPixelY() : 0,
    46                                         const QgsCoordinateReferenceSystem &rasterCrs, 
double rasterUnitsPerPixelX, 
double rasterUnitsPerPixelY, 
const QString &attributePrefix, 
int rasterBand, QgsZonalStatistics::Statistics stats )
    47   : mRasterInterface( rasterInterface )
    48   , mRasterCrs( rasterCrs )
    49   , mCellSizeX( std::fabs( rasterUnitsPerPixelX ) )
    50   , mCellSizeY( std::fabs( rasterUnitsPerPixelY ) )
    51   , mRasterBand( rasterBand )
    52   , mPolygonLayer( polygonLayer )
    53   , mAttributePrefix( attributePrefix )
    54   , mStatistics( stats )
    66   if ( !vectorProvider )
    71   if ( !mRasterInterface )
    76   if ( mRasterInterface->
bandCount() < mRasterBand )
    82   int nCellsXProvider = mRasterInterface->
xSize();
    83   int nCellsYProvider = mRasterInterface->
ySize();
    88   QList<QgsField> newFieldList;
    89   QString countFieldName;
    92     countFieldName = getUniqueFieldName( mAttributePrefix + 
"count", newFieldList );
    93     QgsField countField( countFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
    94     newFieldList.push_back( countField );
    99     sumFieldName = getUniqueFieldName( mAttributePrefix + 
"sum", newFieldList );
   100     QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   101     newFieldList.push_back( sumField );
   103   QString meanFieldName;
   106     meanFieldName = getUniqueFieldName( mAttributePrefix + 
"mean", newFieldList );
   107     QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   108     newFieldList.push_back( meanField );
   110   QString medianFieldName;
   113     medianFieldName = getUniqueFieldName( mAttributePrefix + 
"median", newFieldList );
   114     QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   115     newFieldList.push_back( medianField );
   117   QString stdevFieldName;
   120     stdevFieldName = getUniqueFieldName( mAttributePrefix + 
"stdev", newFieldList );
   121     QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   122     newFieldList.push_back( stdField );
   124   QString minFieldName;
   127     minFieldName = getUniqueFieldName( mAttributePrefix + 
"min", newFieldList );
   128     QgsField minField( minFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   129     newFieldList.push_back( minField );
   131   QString maxFieldName;
   134     maxFieldName = getUniqueFieldName( mAttributePrefix + 
"max", newFieldList );
   135     QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   136     newFieldList.push_back( maxField );
   138   QString rangeFieldName;
   141     rangeFieldName = getUniqueFieldName( mAttributePrefix + 
"range", newFieldList );
   142     QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   143     newFieldList.push_back( rangeField );
   145   QString minorityFieldName;
   148     minorityFieldName = getUniqueFieldName( mAttributePrefix + 
"minority", newFieldList );
   149     QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   150     newFieldList.push_back( minorityField );
   152   QString majorityFieldName;
   155     majorityFieldName = getUniqueFieldName( mAttributePrefix + 
"majority", newFieldList );
   156     QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   157     newFieldList.push_back( majField );
   159   QString varietyFieldName;
   162     varietyFieldName = getUniqueFieldName( mAttributePrefix + 
"variety", newFieldList );
   163     QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( 
"int" ) );
   164     newFieldList.push_back( varietyField );
   166   QString varianceFieldName;
   169     varianceFieldName = getUniqueFieldName( mAttributePrefix + 
"variance", newFieldList );
   170     QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( 
"double precision" ) );
   171     newFieldList.push_back( varianceField );
   176   int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->
fieldNameIndex( countFieldName ) : -1;
   177   int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->
fieldNameIndex( sumFieldName ) : -1;
   178   int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->
fieldNameIndex( meanFieldName ) : -1;
   179   int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->
fieldNameIndex( medianFieldName ) : -1;
   180   int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->
fieldNameIndex( stdevFieldName ) : -1;
   181   int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->
fieldNameIndex( minFieldName ) : -1;
   182   int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->
fieldNameIndex( maxFieldName ) : -1;
   183   int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->
fieldNameIndex( rangeFieldName ) : -1;
   184   int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->
fieldNameIndex( minorityFieldName ) : -1;
   185   int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->
fieldNameIndex( majorityFieldName ) : -1;
   186   int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->
fieldNameIndex( varietyFieldName ) : -1;
   187   int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->
fieldNameIndex( varianceFieldName ) : -1;
   189   if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
   190        || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
   191        || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 )
   192        || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 )
   193        || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 )
   194        || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 )
   195        || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 )
   196        || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 )
   197        || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
   198        || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
   199        || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
   200        || ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 )
   218                           ( mStatistics & QgsZonalStatistics::StDev ) ||
   221                               ( mStatistics & QgsZonalStatistics::Majority );
   223   FeatureStats featureStats( statsStoreValues, statsStoreValueCount );
   224   int featureCounter = 0;
   236       feedback->
setProgress( 100.0 * static_cast< double >( featureCounter ) / featureCount );
   253     int nCellsX, nCellsY;
   255     QgsRasterAnalysisUtils::cellInfoForBBox( rasterBBox, featureRect, mCellSizeX, mCellSizeY, nCellsX, nCellsY, nCellsXProvider, nCellsYProvider, rasterBlockExtent );
   257     featureStats.reset();
   258     QgsRasterAnalysisUtils::statisticsFromMiddlePointTest( mRasterInterface, mRasterBand, featureGeometry, nCellsX, nCellsY, mCellSizeX, mCellSizeY,
   259     rasterBlockExtent, [ &featureStats ]( 
double value ) { featureStats.addValue( value ); } );
   261     if ( featureStats.count <= 1 )
   264       featureStats.reset();
   265       QgsRasterAnalysisUtils::statisticsFromPreciseIntersection( mRasterInterface, mRasterBand, featureGeometry, nCellsX, nCellsY, mCellSizeX, mCellSizeY,
   266       rasterBlockExtent, [ &featureStats ]( 
double value, 
double weight ) { featureStats.addValue( value, weight ); } );
   271     if ( mStatistics & QgsZonalStatistics::Count )
   272       changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) );
   273     if ( mStatistics & QgsZonalStatistics::Sum )
   274       changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) );
   275     if ( featureStats.count > 0 )
   277       double mean = featureStats.sum / featureStats.count;
   278       if ( mStatistics & QgsZonalStatistics::Mean )
   279         changeAttributeMap.insert( meanIndex, QVariant( mean ) );
   280       if ( mStatistics & QgsZonalStatistics::Median )
   282         std::sort( featureStats.values.begin(), featureStats.values.end() );
   283         int size = featureStats.values.count();
   284         bool even = ( size % 2 ) < 1;
   288           medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2;
   292           medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 );
   294         changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
   296       if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance )
   298         double sumSquared = 0;
   299         for ( 
int i = 0; i < featureStats.values.count(); ++i )
   301           double diff = featureStats.values.at( i ) - mean;
   302           sumSquared += diff * diff;
   304         double variance = sumSquared / featureStats.values.count();
   305         if ( mStatistics & QgsZonalStatistics::StDev )
   307           double stdev = std::pow( variance, 0.5 );
   308           changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
   310         if ( mStatistics & QgsZonalStatistics::Variance )
   311           changeAttributeMap.insert( varianceIndex, QVariant( variance ) );
   313       if ( mStatistics & QgsZonalStatistics::Min )
   314         changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
   315       if ( mStatistics & QgsZonalStatistics::Max )
   316         changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) );
   317       if ( mStatistics & QgsZonalStatistics::Range )
   318         changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) );
   319       if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority )
   321         QList<int> vals = featureStats.valueCount.values();
   322         std::sort( vals.begin(), vals.end() );
   323         if ( mStatistics & QgsZonalStatistics::Minority )
   325           double minorityKey = featureStats.valueCount.key( vals.first() );
   326           changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) );
   328         if ( mStatistics & QgsZonalStatistics::Majority )
   330           double majKey = featureStats.valueCount.key( vals.last() );
   331           changeAttributeMap.insert( majorityIndex, QVariant( majKey ) );
   334       if ( mStatistics & QgsZonalStatistics::Variety )
   335         changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) );
   338     changeMap.insert( f.
id(), changeAttributeMap );
   359 QString QgsZonalStatistics::getUniqueFieldName( 
const QString &fieldName, 
const QList<QgsField> &newFields )
   363   if ( !dp->
storageType().contains( QLatin1String( 
"ESRI Shapefile" ) ) )
   369   allFields.append( newFields );
   370   QString shortName = fieldName.mid( 0, 10 );
   373   for ( 
int idx = 0; idx < allFields.count(); ++idx )
   375     if ( shortName == allFields.at( idx ).name() )
   388   shortName = QStringLiteral( 
"%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
   393     for ( 
int idx = 0; idx < allFields.count(); ++idx )
   395       if ( shortName == allFields.at( idx ).name() )
   400           shortName = QStringLiteral( 
"%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
   404           shortName = QStringLiteral( 
"%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n );
 
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider...
 
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries. 
 
virtual int bandCount() const =0
Gets number of bands. 
 
Wrapper for iterator of features from vector data provider or vector layer. 
 
A rectangle specified with double values. 
 
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes to the provider. 
 
virtual QgsRectangle extent() const
Gets the extent of the interface. 
 
This class provides qgis with the ability to render raster datasets onto the mapcanvas. 
 
void setProgress(double progress)
Sets the current progress for the feedback object. 
 
virtual int ySize() const
 
QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon. 
 
A geometry is the spatial representation of a feature. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
const QgsCoordinateReferenceSystem & crs
 
bool hasGeometry() const
Returns true if the feature has an associated geometry. 
 
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...
 
Variance of pixel values. 
 
bool isEmpty() const
Returns true if the rectangle is empty. 
 
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched. 
 
QgsFields fields() const override=0
Returns the fields associated with this data provider. 
 
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features. 
 
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle. 
 
QMap< int, QVariant > QgsAttributeMap
 
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. 
 
int calculateStatistics(QgsFeedback *feedback)
Starts the calculation. 
 
Base class for processing filters like renderers, reprojector, resampler etc. 
 
Range of pixel values (max - min) 
 
bool isCanceled() const
Tells whether the operation has been canceled already. 
 
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override=0
Query the provider for features specified in request. 
 
long featureCount() const override=0
Number of features in the layer. 
 
QgsZonalStatistics(QgsVectorLayer *polygonLayer, QgsRasterLayer *rasterLayer, const QString &attributePrefix=QString(), int rasterBand=1, QgsZonalStatistics::Statistics stats=QgsZonalStatistics::Statistics(QgsZonalStatistics::Count|QgsZonalStatistics::Sum|QgsZonalStatistics::Mean))
Convenience constructor for QgsZonalStatistics, using an input raster layer. 
 
static QgsProject * instance()
Returns the QgsProject singleton instance. 
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry. 
 
This class represents a coordinate reference system (CRS). 
 
QList< QgsField > toList() const
Utility function to return a list of QgsField instances. 
 
A class that calculates raster statistics (count, sum, mean) for a polygon or multipolygon layer and ...
 
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name. 
 
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be null. 
 
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
Gets raster size. 
 
Standard deviation of pixel values.