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 Jun 14, 2021
1 parent 8f74542 commit da9b0fa317ae78a9258ad9b5ce55017aae60730c
@@ -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 da9b0fa

Please sign in to comment.