Skip to content

Commit 88a49e7

Browse files
committed
Fix zonal stats doesn't work with raster/vector in different CRS
Fixes #19027
1 parent e94b1ac commit 88a49e7

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/analysis/vector/qgszonalstatistics.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "qgsrasterblock.h"
2727
#include "qgslogger.h"
2828
#include "qgsgeos.h"
29+
#include "qgsproject.h"
2930

3031
#include <QFile>
3132

@@ -204,6 +205,7 @@ int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
204205
//iterate over each polygon
205206
QgsFeatureRequest request;
206207
request.setSubsetOfAttributes( QgsAttributeList() );
208+
request.setDestinationCrs( mRasterLayer->crs(), QgsProject::instance()->transformContext() );
207209
QgsFeatureIterator fi = vectorProvider->getFeatures( request );
208210
QgsFeature f;
209211

tests/src/analysis/testqgszonalstatistics.cpp

+64
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgsrasterlayer.h"
2323
#include "qgszonalstatistics.h"
2424
#include "qgsproject.h"
25+
#include "qgsvectorlayerutils.h"
2526

2627
/**
2728
* \ingroup UnitTests
@@ -38,6 +39,7 @@ class TestQgsZonalStatistics : public QObject
3839
void cleanup() {}
3940

4041
void testStatistics();
42+
void testReprojection();
4143

4244
private:
4345
QgsVectorLayer *mVectorLayer = nullptr;
@@ -182,5 +184,67 @@ void TestQgsZonalStatistics::testStatistics()
182184
QCOMPARE( f.attribute( "myqgis2__4" ).toDouble(), 0.13888888888889 );
183185
}
184186

187+
void TestQgsZonalStatistics::testReprojection()
188+
{
189+
QString myDataPath( TEST_DATA_DIR ); //defined in CmakeLists.txt
190+
QString myTestDataPath = myDataPath + "/zonalstatistics/";
191+
192+
// create a reprojected version of the layer
193+
std::unique_ptr< QgsVectorLayer > vectorLayer( new QgsVectorLayer( myTestDataPath + "polys.shp", QStringLiteral( "poly" ), QStringLiteral( "ogr" ) ) );
194+
std::unique_ptr< QgsVectorLayer > reprojected( vectorLayer->materialize( QgsFeatureRequest().setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3785" ) ), QgsProject::instance()->transformContext() ) ) );
195+
196+
QCOMPARE( reprojected->featureCount(), vectorLayer->featureCount() );
197+
QgsZonalStatistics zs( reprojected.get(), mRasterLayer, QString(), 1, QgsZonalStatistics::All );
198+
zs.calculateStatistics( nullptr );
199+
200+
QgsFeature f;
201+
QgsFeatureRequest request;
202+
QgsFeatureIterator it = reprojected->getFeatures( request );
203+
bool fetched = it.nextFeature( f );
204+
QVERIFY( fetched );
205+
QCOMPARE( f.attribute( "count" ).toDouble(), 12.0 );
206+
QCOMPARE( f.attribute( "sum" ).toDouble(), 8.0 );
207+
QCOMPARE( f.attribute( "mean" ).toDouble(), 0.666666666666667 );
208+
QCOMPARE( f.attribute( "median" ).toDouble(), 1.0 );
209+
QCOMPARE( f.attribute( "stdev" ).toDouble(), 0.47140452079103201 );
210+
QCOMPARE( f.attribute( "min" ).toDouble(), 0.0 );
211+
QCOMPARE( f.attribute( "max" ).toDouble(), 1.0 );
212+
QCOMPARE( f.attribute( "range" ).toDouble(), 1.0 );
213+
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
214+
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
215+
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
216+
QCOMPARE( f.attribute( "variance" ).toDouble(), 0.222222222222222 );
217+
218+
fetched = it.nextFeature( f );
219+
QVERIFY( fetched );
220+
QCOMPARE( f.attribute( "count" ).toDouble(), 9.0 );
221+
QCOMPARE( f.attribute( "sum" ).toDouble(), 5.0 );
222+
QCOMPARE( f.attribute( "mean" ).toDouble(), 0.555555555555556 );
223+
QCOMPARE( f.attribute( "median" ).toDouble(), 1.0 );
224+
QCOMPARE( f.attribute( "stdev" ).toDouble(), 0.49690399499995302 );
225+
QCOMPARE( f.attribute( "min" ).toDouble(), 0.0 );
226+
QCOMPARE( f.attribute( "max" ).toDouble(), 1.0 );
227+
QCOMPARE( f.attribute( "range" ).toDouble(), 1.0 );
228+
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
229+
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
230+
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
231+
QCOMPARE( f.attribute( "variance" ).toDouble(), 0.24691358024691 );
232+
233+
fetched = it.nextFeature( f );
234+
QVERIFY( fetched );
235+
QCOMPARE( f.attribute( "count" ).toDouble(), 6.0 );
236+
QCOMPARE( f.attribute( "sum" ).toDouble(), 5.0 );
237+
QCOMPARE( f.attribute( "mean" ).toDouble(), 0.833333333333333 );
238+
QCOMPARE( f.attribute( "median" ).toDouble(), 1.0 );
239+
QCOMPARE( f.attribute( "stdev" ).toDouble(), 0.372677996249965 );
240+
QCOMPARE( f.attribute( "min" ).toDouble(), 0.0 );
241+
QCOMPARE( f.attribute( "max" ).toDouble(), 1.0 );
242+
QCOMPARE( f.attribute( "range" ).toDouble(), 1.0 );
243+
QCOMPARE( f.attribute( "minority" ).toDouble(), 0.0 );
244+
QCOMPARE( f.attribute( "majority" ).toDouble(), 1.0 );
245+
QCOMPARE( f.attribute( "variety" ).toDouble(), 2.0 );
246+
QCOMPARE( f.attribute( "variance" ).toDouble(), 0.13888888888889 );
247+
}
248+
185249
QGSTEST_MAIN( TestQgsZonalStatistics )
186250
#include "testqgszonalstatistics.moc"

0 commit comments

Comments
 (0)