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 31, 2021
1 parent 9049a2b commit c060b3bd256db96a59be44d75c92b1cc9002ec99
@@ -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 c060b3b

Please sign in to comment.