@@ -389,9 +389,6 @@ void QgsZonalStatistics::cellInfoForBBox( const QgsRectangle &rasterBBox, const
389
389
390
390
void QgsZonalStatistics::statisticsFromMiddlePointTest ( const QgsGeometry &poly, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
391
391
{
392
- double cellCenterX, cellCenterY;
393
-
394
- cellCenterY = rasterBBox.yMaximum () - cellSizeY / 2 ;
395
392
stats.reset ();
396
393
397
394
std::unique_ptr< QgsGeometryEngine > polyEngine ( QgsGeometry::createGeometryEngine ( poly.constGet ( ) ) );
@@ -401,32 +398,48 @@ void QgsZonalStatistics::statisticsFromMiddlePointTest( const QgsGeometry &poly,
401
398
}
402
399
polyEngine->prepareGeometry ();
403
400
404
- std::unique_ptr< QgsRasterBlock > block ( mRasterInterface ->block ( mRasterBand , rasterBBox, nCellsX, nCellsY ) );
405
- for ( int i = 0 ; i < nCellsY; ++i )
401
+ const int maxWidth = 4000 ;
402
+ const int maxHeight = 4000 ;
403
+
404
+ QgsRasterIterator iter ( mRasterInterface );
405
+ iter.setMaximumTileWidth ( maxWidth );
406
+ iter.setMaximumTileHeight ( maxHeight );
407
+ iter.startRasterRead ( mRasterBand , nCellsX, nCellsY, rasterBBox );
408
+
409
+ QgsRasterBlock *block = nullptr ;
410
+ int iterLeft = 0 ;
411
+ int iterTop = 0 ;
412
+ int iterCols = 0 ;
413
+ int iterRows = 0 ;
414
+ while ( iter.readNextRasterPart ( mRasterBand , iterCols, iterRows, &block, iterLeft, iterTop ) )
406
415
{
407
- cellCenterX = rasterBBox.xMinimum () + cellSizeX / 2 ;
408
- for ( int j = 0 ; j < nCellsX ; ++j )
416
+ double cellCenterY = rasterBBox.yMinimum () + ( iterTop + iterRows - 0.5 ) * cellSizeY ;
417
+ for ( int row = 0 ; row < iterRows ; ++row )
409
418
{
410
- double pixelValue = block-> value ( i, j ) ;
411
- if ( validPixel ( pixelValue ) && !block-> isNoData ( i, j ) )
419
+ double cellCenterX = rasterBBox. xMinimum () + ( iterLeft + 0.5 ) * cellSizeX ;
420
+ for ( int col = 0 ; col < iterCols; ++col )
412
421
{
413
- QgsPoint cellCenter ( cellCenterX, cellCenterY );
414
- if ( polyEngine-> contains ( &cellCenter ) )
422
+ double pixelValue = block-> value ( row, col );
423
+ if ( validPixel ( pixelValue ) && !block-> isNoData ( row, col ) )
415
424
{
416
- stats.addValue ( pixelValue );
425
+ QgsPoint cellCenter ( cellCenterX, cellCenterY );
426
+ if ( polyEngine->contains ( &cellCenter ) )
427
+ {
428
+ stats.addValue ( pixelValue );
429
+ }
417
430
}
431
+ cellCenterX += cellSizeX;
418
432
}
419
- cellCenterX += cellSizeX ;
433
+ cellCenterY -= cellSizeY ;
420
434
}
421
- cellCenterY -= cellSizeY ;
435
+ delete block ;
422
436
}
423
437
}
424
438
425
439
void QgsZonalStatistics::statisticsFromPreciseIntersection ( const QgsGeometry &poly, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
426
440
{
427
441
stats.reset ();
428
442
429
- double currentY = rasterBBox.yMaximum () - cellSizeY / 2 ;
430
443
QgsGeometry pixelRectGeometry;
431
444
432
445
double hCellSizeX = cellSizeX / 2.0 ;
@@ -441,36 +454,52 @@ void QgsZonalStatistics::statisticsFromPreciseIntersection( const QgsGeometry &p
441
454
}
442
455
polyEngine->prepareGeometry ();
443
456
444
- std::unique_ptr< QgsRasterBlock > block ( mRasterInterface ->block ( mRasterBand , rasterBBox, nCellsX, nCellsY ) );
445
- for ( int i = 0 ; i < nCellsY; ++i )
457
+ const int maxWidth = 4000 ;
458
+ const int maxHeight = 4000 ;
459
+
460
+ QgsRasterIterator iter ( mRasterInterface );
461
+ iter.setMaximumTileWidth ( maxWidth );
462
+ iter.setMaximumTileHeight ( maxHeight );
463
+ iter.startRasterRead ( mRasterBand , nCellsX, nCellsY, rasterBBox );
464
+
465
+ QgsRasterBlock *block = nullptr ;
466
+ int iterLeft = 0 ;
467
+ int iterTop = 0 ;
468
+ int iterCols = 0 ;
469
+ int iterRows = 0 ;
470
+ while ( iter.readNextRasterPart ( mRasterBand , iterCols, iterRows, &block, iterLeft, iterTop ) )
446
471
{
447
- double currentX = rasterBBox.xMinimum () + cellSizeX / 2.0 ;
448
- for ( int j = 0 ; j < nCellsX ; ++j )
472
+ double currentY = rasterBBox.yMinimum () + ( iterTop + iterRows - 0.5 ) * cellSizeY ;
473
+ for ( int row = 0 ; row < iterRows ; ++row )
449
474
{
450
- double pixelValue = block-> value ( i, j ) ;
451
- if ( validPixel ( pixelValue ) && !block-> isNoData ( i, j ) )
475
+ double currentX = rasterBBox. xMinimum () + ( iterLeft + 0.5 ) * cellSizeX ;
476
+ for ( int col = 0 ; col < iterCols; ++col )
452
477
{
453
- pixelRectGeometry = QgsGeometry::fromRect ( QgsRectangle ( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
454
- // GEOS intersects tests on prepared geometry is MAGNITUDES faster than calculating the intersection itself,
455
- // so we first test to see if there IS an intersection before doing the actual calculation
456
- if ( !pixelRectGeometry.isNull () && polyEngine->intersects ( pixelRectGeometry.constGet () ) )
478
+ double pixelValue = block->value ( row, col );
479
+ if ( validPixel ( pixelValue ) && !block->isNoData ( row, col ) )
457
480
{
458
- // intersection
459
- QgsGeometry intersectGeometry = pixelRectGeometry.intersection ( poly );
460
- if ( !intersectGeometry.isEmpty () )
481
+ pixelRectGeometry = QgsGeometry::fromRect ( QgsRectangle ( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
482
+ // GEOS intersects tests on prepared geometry is MAGNITUDES faster than calculating the intersection itself,
483
+ // so we first test to see if there IS an intersection before doing the actual calculation
484
+ if ( !pixelRectGeometry.isNull () && polyEngine->intersects ( pixelRectGeometry.constGet () ) )
461
485
{
462
- double intersectionArea = intersectGeometry.area ();
463
- if ( intersectionArea > 0.0 )
486
+ // intersection
487
+ QgsGeometry intersectGeometry = pixelRectGeometry.intersection ( poly );
488
+ if ( !intersectGeometry.isEmpty () )
464
489
{
465
- weight = intersectionArea / pixelArea;
466
- stats.addValue ( pixelValue, weight );
490
+ double intersectionArea = intersectGeometry.area ();
491
+ if ( intersectionArea > 0.0 )
492
+ {
493
+ weight = intersectionArea / pixelArea;
494
+ stats.addValue ( pixelValue, weight );
495
+ }
467
496
}
468
497
}
469
498
}
499
+ currentX += cellSizeX;
470
500
}
471
- currentX += cellSizeX ;
501
+ currentY -= cellSizeY ;
472
502
}
473
- currentY -= cellSizeY;
474
503
}
475
504
}
476
505
0 commit comments