32 :
QgsZonalStatistics( polygonLayer, rasterLayer ? rasterLayer->dataProvider() : nullptr, rasterLayer ? rasterLayer->crs() :
QgsCoordinateReferenceSystem(), rasterLayer ? rasterLayer->rasterUnitsPerPixelX() : 0, rasterLayer ? rasterLayer->rasterUnitsPerPixelY() : 0, attributePrefix, rasterBand, stats )
37 : mRasterInterface( rasterInterface )
38 , mRasterCrs( rasterCrs )
39 , mCellSizeX( std::fabs( rasterUnitsPerPixelX ) )
40 , mCellSizeY( std::fabs( rasterUnitsPerPixelY ) )
41 , mRasterBand( rasterBand )
42 , mPolygonLayer( polygonLayer )
43 , mAttributePrefix( attributePrefix )
44 , mStatistics( stats )
50 if ( !mRasterInterface )
55 if ( mRasterInterface->bandCount() < mRasterBand )
66 if ( !vectorProvider )
71 QMap<Qgis::ZonalStatistic, int> statFieldIndexes;
74 int oldFieldCount = vectorProvider->
fields().
count();
75 QList<QgsField> newFieldList;
92 if ( mStatistics & stat )
95 QgsField field( fieldName, QMetaType::Type::Double, QStringLiteral(
"double precision" ) );
96 newFieldList.push_back( field );
97 statFieldIndexes.insert( stat, oldFieldCount + newFieldList.count() - 1 );
112 int featureCounter = 0;
125 feedback->
setProgress( 100.0 *
static_cast<double>( featureCounter ) / featureCount );
130 QMap<Qgis::ZonalStatistic, QVariant> results =
calculateStatistics( mRasterInterface, featureGeometry, mCellSizeX, mCellSizeY, mRasterBand, mStatistics );
132 if ( results.empty() )
136 for (
const auto &result : results.toStdMap() )
138 changeAttributeMap.insert( statFieldIndexes.value( result.first ), result.second );
141 changeMap.insert( feature.
id(), changeAttributeMap );
145 mPolygonLayer->updateFields();
158QString QgsZonalStatistics::getUniqueFieldName(
const QString &fieldName,
const QList<QgsField> &newFields )
162 if ( !dp->
storageType().contains( QLatin1String(
"ESRI Shapefile" ) ) )
168 allFields.append( newFields );
169 QString
shortName = fieldName.mid( 0, 10 );
172 for (
const QgsField &field : std::as_const( allFields ) )
187 shortName = QStringLiteral(
"%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
192 for (
const QgsField &field : std::as_const( allFields ) )
199 shortName = QStringLiteral(
"%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
203 shortName = QStringLiteral(
"%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n );
217 return QObject::tr(
"Count" );
219 return QObject::tr(
"Sum" );
221 return QObject::tr(
"Mean" );
223 return QObject::tr(
"Median" );
225 return QObject::tr(
"St dev" );
227 return QObject::tr(
"Minimum" );
229 return QObject::tr(
"Maximum" );
231 return QObject::tr(
"Minimum point" );
233 return QObject::tr(
"Maximum point" );
235 return QObject::tr(
"Range" );
237 return QObject::tr(
"Minority" );
239 return QObject::tr(
"Majority" );
241 return QObject::tr(
"Variety" );
243 return QObject::tr(
"Variance" );
256 return QStringLiteral(
"count" );
258 return QStringLiteral(
"sum" );
260 return QStringLiteral(
"mean" );
262 return QStringLiteral(
"median" );
264 return QStringLiteral(
"stdev" );
266 return QStringLiteral(
"min" );
268 return QStringLiteral(
"max" );
270 return QStringLiteral(
"minpoint" );
272 return QStringLiteral(
"maxpoint" );
274 return QStringLiteral(
"range" );
276 return QStringLiteral(
"minority" );
278 return QStringLiteral(
"majority" );
280 return QStringLiteral(
"variety" );
282 return QStringLiteral(
"variance" );
294 QMap<int, QVariant> pyResult;
295 for (
auto it = result.constBegin(); it != result.constEnd(); ++it )
297 pyResult.insert(
static_cast<int>( it.key() ), it.value() );
305 QMap<Qgis::ZonalStatistic, QVariant> results;
320 FeatureStats featureStats( statsStoreValues, statsStoreValueCount );
322 int nCellsXProvider = rasterInterface->
xSize();
323 int nCellsYProvider = rasterInterface->
ySize();
325 int nCellsX, nCellsY;
327 QgsRasterAnalysisUtils::cellInfoForBBox( rasterBBox, featureRect, cellSizeX, cellSizeY, nCellsX, nCellsY, nCellsXProvider, nCellsYProvider, rasterBlockExtent );
329 featureStats.reset();
330 QgsRasterAnalysisUtils::statisticsFromMiddlePointTest( rasterInterface, rasterBand, geometry, nCellsX, nCellsY, cellSizeX, cellSizeY, rasterBlockExtent, [&featureStats](
double value,
const QgsPointXY &point ) { featureStats.addValue( value, point ); } );
332 if ( featureStats.count <= 1 )
335 featureStats.reset();
336 QgsRasterAnalysisUtils::statisticsFromPreciseIntersection( rasterInterface, rasterBand, geometry, nCellsX, nCellsY, cellSizeX, cellSizeY, rasterBlockExtent, [&featureStats](
double value,
double weight,
const QgsPointXY &point ) { featureStats.addValue( value, point, weight ); } );
345 if ( featureStats.count > 0 )
347 double mean = featureStats.sum / featureStats.count;
352 std::sort( featureStats.values.begin(), featureStats.values.end() );
353 int size = featureStats.values.count();
354 bool even = ( size % 2 ) < 1;
358 medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2;
362 medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 );
368 double sumSquared = 0;
369 for (
int i = 0; i < featureStats.values.count(); ++i )
371 double diff = featureStats.values.at( i ) - mean;
372 sumSquared += diff * diff;
374 double variance = sumSquared / featureStats.values.count();
377 double stdev = std::pow( variance, 0.5 );
395 QList<int> vals = featureStats.valueCount.values();
396 std::sort( vals.begin(), vals.end() );
399 double minorityKey = featureStats.valueCount.key( vals.first() );
404 double majKey = featureStats.valueCount.key( vals.last() );
ZonalStatistic
Statistics to be calculated during a zonal statistics operation.
@ StDev
Standard deviation of pixel values.
@ Mean
Mean of pixel values.
@ Median
Median of pixel values.
@ Max
Max of pixel values.
@ Variance
Variance of pixel values.
@ MinimumPoint
Pixel centroid for minimum pixel value.
@ Min
Min of pixel values.
@ Default
Default statistics.
@ Range
Range of pixel values (max - min).
@ Sum
Sum of pixel values.
@ Minority
Minority of pixel values.
@ All
All statistics. For QGIS 3.x this includes ONLY numeric statistics, but for 4.0 this will be extended...
@ Majority
Majority of pixel values.
@ Variety
Variety (count of distinct) pixel values.
@ MaximumPoint
Pixel centroid for maximum pixel value.
ZonalStatisticResult
Zonal statistics result codes.
@ Canceled
Algorithm was canceled.
@ LayerTypeWrong
Layer is not a polygon layer.
@ RasterBandInvalid
The raster band does not exist on the raster layer.
@ RasterInvalid
Raster layer is invalid.
@ LayerInvalid
Layer is invalid.
QFlags< ZonalStatistic > ZonalStatistics
Statistics to be calculated during a zonal statistics operation.
Represents a coordinate reference system (CRS).
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
A geometry is the spatial representation of a feature.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual int xSize() const
Gets raster size.
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
Represents a raster layer.
A rectangle specified with double values.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Base class for vector data providers.
long long featureCount() const override=0
Number of features in the layer.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override=0
Query the provider for features specified in request.
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes to the provider.
Represents a vector layer which manages a vector based dataset.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
QgsZonalStatistics(QgsVectorLayer *polygonLayer, QgsRasterLayer *rasterLayer, const QString &attributePrefix=QString(), int rasterBand=1, Qgis::ZonalStatistics stats=Qgis::ZonalStatistic::Default)
Convenience constructor for QgsZonalStatistics, using an input raster layer.
Qgis::ZonalStatisticResult calculateStatistics(QgsFeedback *feedback)
Runs the calculation.
static QString displayName(Qgis::ZonalStatistic statistic)
Returns the friendly display name for a statistic.
static QString shortName(Qgis::ZonalStatistic statistic)
Returns a short, friendly display name for a statistic, suitable for use in a field name.
QMap< int, QVariant > QgsAttributeMap
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap