Skip to content
Permalink
Browse files
Fix SIP issue with return results from calculateStatistics
Fixes #43245

SIP failed to convert the QMap<QgsZonalStatistics::Statistic, QVariant>
so we give it an QMap<int, QVariant>.
  • Loading branch information
elpaso authored and nyalldawson committed May 21, 2021
1 parent bce96e5 commit d06f1e6467018c3290592884be0b1d8f76043867
@@ -130,7 +130,9 @@ Returns a short, friendly display name for a ``statistic``, suitable for use in
.. versionadded:: 3.12
%End

static QMap<QgsZonalStatistics::Statistic, QVariant> calculateStatistics( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics );


static QMap<int, QVariant> 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``.
@@ -287,6 +287,19 @@ QString QgsZonalStatistics::shortName( QgsZonalStatistics::Statistic statistic )
return QString();
}

///@cond PRIVATE
QMap<int, QVariant> 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<int, QVariant> pyResult;
for ( auto it = result.constBegin(); it != result.constEnd(); ++it )
{
pyResult.insert( it.key(), it.value() );
}
return pyResult;
}
/// @endcond

QMap<QgsZonalStatistics::Statistic, QVariant> QgsZonalStatistics::calculateStatistics( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics )
{
QMap<QgsZonalStatistics::Statistic, QVariant> results;
@@ -327,7 +340,7 @@ QMap<QgsZonalStatistics::Statistic, QVariant> QgsZonalStatistics::calculateStati
}

// calculate the statistics
QgsAttributeMap changeAttributeMap;

if ( statistics & QgsZonalStatistics::Count )
results.insert( QgsZonalStatistics::Count, QVariant( featureStats.count ) );
if ( statistics & QgsZonalStatistics::Sum )
@@ -155,7 +155,23 @@ class ANALYSIS_EXPORT QgsZonalStatistics
*
* \since QGIS 3.16
*/
#ifndef SIP_RUN
static QMap<QgsZonalStatistics::Statistic, QVariant> 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<int, QVariant> calculateStatisticsInt( QgsRasterInterface *rasterInterface, const QgsGeometry &geometry, double cellSizeX, double cellSizeY, int rasterBand, QgsZonalStatistics::Statistics statistics ) SIP_PYNAME( calculateStatistics );
/// @endcond

private:
QgsZonalStatistics() = default;
@@ -11,16 +11,19 @@
__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
from utilities import unitTestDataPath

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()

0 comments on commit d06f1e6

Please sign in to comment.