mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
[zonal statistics] add variance statistic
This commit is contained in:
parent
8379f9bb98
commit
58f6f93cb6
@ -36,6 +36,7 @@ class QgsZonalStatistics
|
|||||||
Minority,
|
Minority,
|
||||||
Majority,
|
Majority,
|
||||||
Variety,
|
Variety,
|
||||||
|
Variance,
|
||||||
All
|
All
|
||||||
};
|
};
|
||||||
typedef QFlags<QgsZonalStatistics::Statistic> Statistics;
|
typedef QFlags<QgsZonalStatistics::Statistic> Statistics;
|
||||||
|
@ -158,6 +158,13 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
|
|||||||
QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) );
|
QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) );
|
||||||
newFieldList.push_back( varietyField );
|
newFieldList.push_back( varietyField );
|
||||||
}
|
}
|
||||||
|
QString varianceFieldName;
|
||||||
|
if ( mStatistics & QgsZonalStatistics::Variance )
|
||||||
|
{
|
||||||
|
varianceFieldName = getUniqueFieldName( mAttributePrefix + "variance", newFieldList );
|
||||||
|
QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
|
||||||
|
newFieldList.push_back( varianceField );
|
||||||
|
}
|
||||||
vectorProvider->addAttributes( newFieldList );
|
vectorProvider->addAttributes( newFieldList );
|
||||||
|
|
||||||
//index of the new fields
|
//index of the new fields
|
||||||
@ -172,6 +179,7 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
|
|||||||
int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1;
|
int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1;
|
||||||
int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1;
|
int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1;
|
||||||
int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1;
|
int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1;
|
||||||
|
int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->fieldNameIndex( varianceFieldName ) : -1;
|
||||||
|
|
||||||
if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
|
if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
|
||||||
|| ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
|
|| ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
|
||||||
@ -184,6 +192,7 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
|
|||||||
|| ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
|
|| ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
|
||||||
|| ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
|
|| ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
|
||||||
|| ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
|
|| ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
|
||||||
|
|| ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 )
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//failed to create a required field
|
//failed to create a required field
|
||||||
@ -200,7 +209,8 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
|
|||||||
QgsFeature f;
|
QgsFeature f;
|
||||||
|
|
||||||
bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) ||
|
bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) ||
|
||||||
( mStatistics & QgsZonalStatistics::StDev );
|
( mStatistics & QgsZonalStatistics::StDev ) ||
|
||||||
|
( mStatistics & QgsZonalStatistics::Variance );
|
||||||
bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) ||
|
bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) ||
|
||||||
( mStatistics & QgsZonalStatistics::Majority );
|
( mStatistics & QgsZonalStatistics::Majority );
|
||||||
|
|
||||||
@ -288,7 +298,7 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
|
|||||||
}
|
}
|
||||||
changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
|
changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
|
||||||
}
|
}
|
||||||
if ( mStatistics & QgsZonalStatistics::StDev )
|
if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance )
|
||||||
{
|
{
|
||||||
double sumSquared = 0;
|
double sumSquared = 0;
|
||||||
for ( int i = 0; i < featureStats.values.count(); ++i )
|
for ( int i = 0; i < featureStats.values.count(); ++i )
|
||||||
@ -296,8 +306,14 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
|
|||||||
double diff = featureStats.values.at( i ) - mean;
|
double diff = featureStats.values.at( i ) - mean;
|
||||||
sumSquared += diff * diff;
|
sumSquared += diff * diff;
|
||||||
}
|
}
|
||||||
double stdev = qPow( sumSquared / featureStats.values.count(), 0.5 );
|
double variance = sumSquared / featureStats.values.count();
|
||||||
changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
|
if ( mStatistics & QgsZonalStatistics::StDev )
|
||||||
|
{
|
||||||
|
double stdev = qPow( variance, 0.5 );
|
||||||
|
changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
|
||||||
|
}
|
||||||
|
if ( mStatistics & QgsZonalStatistics::Variance )
|
||||||
|
changeAttributeMap.insert( varianceIndex, QVariant( variance ) );
|
||||||
}
|
}
|
||||||
if ( mStatistics & QgsZonalStatistics::Min )
|
if ( mStatistics & QgsZonalStatistics::Min )
|
||||||
changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
|
changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
|
||||||
|
@ -55,7 +55,8 @@ class ANALYSIS_EXPORT QgsZonalStatistics
|
|||||||
Minority = 256, //!< Minority of pixel values
|
Minority = 256, //!< Minority of pixel values
|
||||||
Majority = 512, //!< Majority of pixel values
|
Majority = 512, //!< Majority of pixel values
|
||||||
Variety = 1024, //!< Variety (count of distinct) pixel values
|
Variety = 1024, //!< Variety (count of distinct) pixel values
|
||||||
All = Count | Sum | Mean | Median | StDev | Max | Min | Range | Minority | Majority | Variety
|
Variance = 2048, //!< Variance of pixel values
|
||||||
|
All = Count | Sum | Mean | Median | StDev | Max | Min | Range | Minority | Majority | Variety | Variance
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS( Statistics, Statistic )
|
Q_DECLARE_FLAGS( Statistics, Statistic )
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ void TestQgsZonalStatistics::testStatistics()
|
|||||||
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
|
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
|
||||||
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
|
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
|
||||||
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
|
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
|
||||||
|
QCOMPARE( f.attribute( "variance" ).toDouble(), 0.222222222222222 );
|
||||||
|
|
||||||
request.setFilterFid( 1 );
|
request.setFilterFid( 1 );
|
||||||
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
||||||
@ -109,6 +110,7 @@ void TestQgsZonalStatistics::testStatistics()
|
|||||||
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
|
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
|
||||||
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
|
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
|
||||||
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
|
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
|
||||||
|
QCOMPARE( f.attribute( "variance" ).toDouble(), 0.24691358024691 );
|
||||||
|
|
||||||
request.setFilterFid( 2 );
|
request.setFilterFid( 2 );
|
||||||
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
||||||
@ -124,6 +126,7 @@ void TestQgsZonalStatistics::testStatistics()
|
|||||||
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
|
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
|
||||||
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
|
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
|
||||||
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
|
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
|
||||||
|
QCOMPARE( f.attribute( "variance" ).toDouble(), 0.13888888888889 );
|
||||||
|
|
||||||
// same with long prefix to ensure that field name truncation handled correctly
|
// same with long prefix to ensure that field name truncation handled correctly
|
||||||
QgsZonalStatistics zsl( mVectorLayer, mRasterLayer, QStringLiteral( "myqgis2_" ), 1, QgsZonalStatistics::All );
|
QgsZonalStatistics zsl( mVectorLayer, mRasterLayer, QStringLiteral( "myqgis2_" ), 1, QgsZonalStatistics::All );
|
||||||
@ -143,6 +146,7 @@ void TestQgsZonalStatistics::testStatistics()
|
|||||||
QCOMPARE( f.attribute( "myqgis2__2" ).toDouble(), 0.0 );
|
QCOMPARE( f.attribute( "myqgis2__2" ).toDouble(), 0.0 );
|
||||||
QCOMPARE( f.attribute( "myqgis2__3" ).toDouble(), 1.0 );
|
QCOMPARE( f.attribute( "myqgis2__3" ).toDouble(), 1.0 );
|
||||||
QCOMPARE( f.attribute( "myqgis2_va" ).toDouble(), 2.0 );
|
QCOMPARE( f.attribute( "myqgis2_va" ).toDouble(), 2.0 );
|
||||||
|
QCOMPARE( f.attribute( "myqgis2__4" ).toDouble(), 0.222222222222222 );
|
||||||
|
|
||||||
request.setFilterFid( 1 );
|
request.setFilterFid( 1 );
|
||||||
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
||||||
@ -158,6 +162,7 @@ void TestQgsZonalStatistics::testStatistics()
|
|||||||
QCOMPARE( f.attribute( "myqgis2__2" ).toDouble(), 0.0 );
|
QCOMPARE( f.attribute( "myqgis2__2" ).toDouble(), 0.0 );
|
||||||
QCOMPARE( f.attribute( "myqgis2__3" ).toDouble(), 1.0 );
|
QCOMPARE( f.attribute( "myqgis2__3" ).toDouble(), 1.0 );
|
||||||
QCOMPARE( f.attribute( "myqgis2_va" ).toDouble(), 2.0 );
|
QCOMPARE( f.attribute( "myqgis2_va" ).toDouble(), 2.0 );
|
||||||
|
QCOMPARE( f.attribute( "myqgis2__4" ).toDouble(), 0.24691358024691 );
|
||||||
|
|
||||||
request.setFilterFid( 2 );
|
request.setFilterFid( 2 );
|
||||||
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
fetched = mVectorLayer->getFeatures( request ).nextFeature( f );
|
||||||
@ -173,6 +178,7 @@ void TestQgsZonalStatistics::testStatistics()
|
|||||||
QCOMPARE( f.attribute( "myqgis2__2" ).toDouble(), 0.0 );
|
QCOMPARE( f.attribute( "myqgis2__2" ).toDouble(), 0.0 );
|
||||||
QCOMPARE( f.attribute( "myqgis2__3" ).toDouble(), 1.0 );
|
QCOMPARE( f.attribute( "myqgis2__3" ).toDouble(), 1.0 );
|
||||||
QCOMPARE( f.attribute( "myqgis2_va" ).toDouble(), 2.0 );
|
QCOMPARE( f.attribute( "myqgis2_va" ).toDouble(), 2.0 );
|
||||||
|
QCOMPARE( f.attribute( "myqgis2__4" ).toDouble(), 0.13888888888889 );
|
||||||
}
|
}
|
||||||
|
|
||||||
QGSTEST_MAIN( TestQgsZonalStatistics )
|
QGSTEST_MAIN( TestQgsZonalStatistics )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user