diff --git a/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in b/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in index a5bb2ca20c83..3c32378856d1 100644 --- a/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in +++ b/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in @@ -130,7 +130,9 @@ Returns a short, friendly display name for a ``statistic``, suitable for use in .. versionadded:: 3.12 %End - static QMap calculateStatistics( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ); + + + static QMap calculateStatisticsInt( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ) /PyName=calculateStatistics/; %Docstring Calculates the specified ``statistics`` for the pixels of ``rasterBand`` in ``rasterInterface`` (a raster layer :py:func:`~QgsZonalStatistics.dataProvider` ) within polygon ``geometry``. diff --git a/src/analysis/vector/qgszonalstatistics.cpp b/src/analysis/vector/qgszonalstatistics.cpp index 74ed6e76284d..733aea3dcd70 100644 --- a/src/analysis/vector/qgszonalstatistics.cpp +++ b/src/analysis/vector/qgszonalstatistics.cpp @@ -287,6 +287,19 @@ QString QgsZonalStatistics::shortName( QgsZonalStatistics::Statistic statistic ) return QString(); } +///@cond PRIVATE +QMap QgsZonalStatistics::calculateStatisticsInt( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ) +{ + const auto result { QgsZonalStatistics::calculateStatistics( rasterInterface, geometry, cellSizeX, cellSizeY, rasterBand, statistics ) }; + QMap pyResult; + for ( auto it = result.constBegin(); it != result.constEnd(); ++it ) + { + pyResult.insert( it.key(), it.value() ); + } + return pyResult; +} +/// @endcond + QMap QgsZonalStatistics::calculateStatistics( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ) { QMap results; @@ -327,7 +340,7 @@ QMap QgsZonalStatistics::calculateStati } // calculate the statistics - QgsAttributeMap changeAttributeMap; + if ( statistics & QgsZonalStatistics::Count ) results.insert( QgsZonalStatistics::Count, QVariant( featureStats.count ) ); if ( statistics & QgsZonalStatistics::Sum ) diff --git a/src/analysis/vector/qgszonalstatistics.h b/src/analysis/vector/qgszonalstatistics.h index 66df8ad1b1ba..306865b98950 100644 --- a/src/analysis/vector/qgszonalstatistics.h +++ b/src/analysis/vector/qgszonalstatistics.h @@ -155,7 +155,23 @@ class ANALYSIS_EXPORT QgsZonalStatistics * * \since QGIS 3.16 */ +#ifndef SIP_RUN static QMap calculateStatistics( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ); +#endif + +///@cond PRIVATE + // Required to fix https://github.com/qgis/QGIS/issues/43245 (SIP is failing to convert the enum to values) + + /** + * Calculates the specified \a statistics for the pixels of \a rasterBand + * in \a rasterInterface (a raster layer dataProvider() ) within polygon \a geometry. + * + * Returns a map of statistic to result value. + * + * \since QGIS 3.16 + */ + static QMap calculateStatisticsInt( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ) SIP_PYNAME( calculateStatistics ); +/// @endcond private: QgsZonalStatistics() = default; diff --git a/tests/src/python/test_qgszonalstatistics.py b/tests/src/python/test_qgszonalstatistics.py index 2f59bc9eecb3..fe25265ae735 100644 --- a/tests/src/python/test_qgszonalstatistics.py +++ b/tests/src/python/test_qgszonalstatistics.py @@ -11,9 +11,10 @@ __copyright__ = 'Copyright 2013, The QGIS Project' import qgis # NOQA - -from qgis.PyQt.QtCore import QDir, QFile -from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsFeature, QgsFeatureRequest +import os +import shutil +from qgis.PyQt.QtCore import QDir, QFile, QTemporaryDir +from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsFeature, QgsFeatureRequest, QgsGeometry from qgis.analysis import QgsZonalStatistics from qgis.testing import start_app, unittest @@ -21,6 +22,8 @@ start_app() +TEST_DATA_DIR = unitTestDataPath() + class TestQgsZonalStatistics(unittest.TestCase): @@ -117,6 +120,29 @@ def testStatistics(self): myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage + def test_enum_conversion(self): + """Test regression GH #43245""" + + tmp = QTemporaryDir() + origin = os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif') + dest = os.path.join(tmp.path(), 'band1_byte_ct_epsg4326.tif') + shutil.copyfile(origin, dest) + + layer = QgsRasterLayer(dest, 'rast', 'gdal') + + stats = QgsZonalStatistics.calculateStatistics( + layer.dataProvider(), + QgsGeometry.fromWkt(layer.extent().asWktPolygon()), + layer.rasterUnitsPerPixelX(), + layer.rasterUnitsPerPixelY(), + 1, + QgsZonalStatistics.Statistic.Max | QgsZonalStatistics.Statistic.Median + ) + + self.assertEqual(sorted(list(stats.keys())), [QgsZonalStatistics.Statistic.Median, QgsZonalStatistics.Statistic.Max]) + self.assertEqual(stats[QgsZonalStatistics.Statistic.Median], 142.0) + self.assertEqual(stats[QgsZonalStatistics.Statistic.Max], 254.0) + if __name__ == '__main__': unittest.main()