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 );
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 ); } );
272 changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) );
274 changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) );
275 if ( featureStats.count > 0 )
277 double mean = featureStats.sum / featureStats.count;
279 changeAttributeMap.insert( meanIndex, QVariant( mean ) );
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 ) );
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();
307 double stdev = std::pow( variance, 0.5 );
308 changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
311 changeAttributeMap.insert( varianceIndex, QVariant( variance ) );
314 changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
316 changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) );
318 changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) );
321 QList<int> vals = featureStats.valueCount.values();
322 std::sort( vals.begin(), vals.end() );
325 double minorityKey = featureStats.valueCount.key( vals.first() );
326 changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) );
330 double majKey = featureStats.valueCount.key( vals.last() );
331 changeAttributeMap.insert( majorityIndex, QVariant( majKey ) );
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" );