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;
93 QgsField countField( countFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
94 newFieldList.push_back( countField );
100 QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
101 newFieldList.push_back( sumField );
103 QString meanFieldName;
107 QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
108 newFieldList.push_back( meanField );
110 QString medianFieldName;
114 QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
115 newFieldList.push_back( medianField );
117 QString stdevFieldName;
121 QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
122 newFieldList.push_back( stdField );
124 QString minFieldName;
128 QgsField minField( minFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
129 newFieldList.push_back( minField );
131 QString maxFieldName;
135 QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
136 newFieldList.push_back( maxField );
138 QString rangeFieldName;
142 QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
143 newFieldList.push_back( rangeField );
145 QString minorityFieldName;
149 QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
150 newFieldList.push_back( minorityField );
152 QString majorityFieldName;
156 QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral(
"double precision" ) );
157 newFieldList.push_back( majField );
159 QString varietyFieldName;
163 QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral(
"int" ) );
164 newFieldList.push_back( varietyField );
166 QString varianceFieldName;
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 );
418 return QObject::tr(
"Count" );
420 return QObject::tr(
"Sum" );
422 return QObject::tr(
"Mean" );
424 return QObject::tr(
"Median" );
426 return QObject::tr(
"St dev)" );
428 return QObject::tr(
"Minimum" );
430 return QObject::tr(
"Maximum" );
432 return QObject::tr(
"Range" );
434 return QObject::tr(
"Minority" );
436 return QObject::tr(
"Majority" );
438 return QObject::tr(
"Variety" );
440 return QObject::tr(
"Variance" );
452 return QStringLiteral(
"count" );
454 return QStringLiteral(
"sum" );
456 return QStringLiteral(
"mean" );
458 return QStringLiteral(
"median" );
460 return QStringLiteral(
"stdev" );
462 return QStringLiteral(
"min" );
464 return QStringLiteral(
"max" );
466 return QStringLiteral(
"range" );
468 return QStringLiteral(
"minority" );
470 return QStringLiteral(
"majority" );
472 return QStringLiteral(
"variety" );
474 return QStringLiteral(
"variance" );
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.
static QString shortName(QgsZonalStatistics::Statistic statistic)
Returns a short, friendly display name for a statistic, suitable for use in a field name...
Statistic
Enumeration of flags that specify statistics to be calculated.
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes to the provider.
virtual QgsRectangle extent() const
Gets the extent of the interface.
Represents a raster layer.
void setProgress(double progress)
Sets the current progress for the feedback object.
virtual int ySize() const
Q_INVOKABLE 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 cancellation of something running in a worker thread...
Variance of pixel values.
static QString displayName(QgsZonalStatistics::Statistic statistic)
Returns the friendly display name for a statistic.
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 nullptr.
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.