27 void QgsRasterAnalysisUtils::cellInfoForBBox( 
const QgsRectangle &rasterBBox, 
const QgsRectangle &featureBBox, 
double cellSizeX, 
double cellSizeY,
 
   28     int &nCellsX, 
int &nCellsY, 
int rasterWidth, 
int rasterHeight, 
QgsRectangle &rasterBlockExtent )
 
   41   int offsetX = 
static_cast< int >( std::floor( ( intersectBox.
xMinimum() - rasterBBox.
xMinimum() ) / cellSizeX ) );
 
   42   int offsetY = 
static_cast< int >( std::floor( ( rasterBBox.
yMaximum() - intersectBox.
yMaximum() ) / cellSizeY ) );
 
   44   int maxColumn = 
static_cast< int >( std::floor( ( intersectBox.
xMaximum() - rasterBBox.
xMinimum() ) / cellSizeX ) ) + 1;
 
   45   int maxRow = 
static_cast< int >( std::floor( ( rasterBBox.
yMaximum() - intersectBox.
yMinimum() ) / cellSizeY ) ) + 1;
 
   47   nCellsX = maxColumn - offsetX;
 
   48   nCellsY = maxRow - offsetY;
 
   51   nCellsX = std::min( offsetX + nCellsX, rasterWidth ) - offsetX;
 
   52   nCellsY = std::min( offsetY + nCellsY, rasterHeight ) - offsetY;
 
   55                                     rasterBBox.
yMaximum() - offsetY * cellSizeY,
 
   56                                     rasterBBox.
xMinimum() + ( nCellsX + offsetX ) * cellSizeX,
 
   57                                     rasterBBox.
yMaximum() - ( nCellsY + offsetY ) * cellSizeY );
 
   60 void QgsRasterAnalysisUtils::statisticsFromMiddlePointTest( 
QgsRasterInterface *rasterInterface, 
int rasterBand, 
const QgsGeometry &poly, 
int nCellsX, 
int nCellsY, 
double cellSizeX, 
double cellSizeY, 
const QgsRectangle &rasterBBox,  
const std::function<
void( 
double )> &addValue, 
bool skipNodata )
 
   67   polyEngine->prepareGeometry();
 
   70   iter.startRasterRead( rasterBand, nCellsX, nCellsY, rasterBBox );
 
   72   std::unique_ptr< QgsRasterBlock > block;
 
   78   bool isNoData = 
false;
 
   79   while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
 
   81     double cellCenterY = blockExtent.
yMaximum() - 0.5 * cellSizeY;
 
   83     for ( 
int row = 0; row < iterRows; ++row )
 
   85       double cellCenterX = blockExtent.
xMinimum() + 0.5 * cellSizeX;
 
   86       for ( 
int col = 0; col < iterCols; ++col )
 
   88         const double pixelValue = block->valueAndNoData( row, col, isNoData );
 
   89         if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
 
   91           QgsPoint cellCenter( cellCenterX, cellCenterY );
 
   92           if ( polyEngine->contains( &cellCenter ) )
 
   94             addValue( pixelValue );
 
   97         cellCenterX += cellSizeX;
 
   99       cellCenterY -= cellSizeY;
 
  104 void QgsRasterAnalysisUtils::statisticsFromPreciseIntersection( 
QgsRasterInterface *rasterInterface, 
int rasterBand, 
const QgsGeometry &poly, 
int nCellsX, 
int nCellsY, 
double cellSizeX, 
double cellSizeY, 
const QgsRectangle &rasterBBox,  
const std::function<
void( 
double, 
double )> &addValue, 
bool skipNodata )
 
  108   double hCellSizeX = cellSizeX / 2.0;
 
  109   double hCellSizeY = cellSizeY / 2.0;
 
  110   double pixelArea = cellSizeX * cellSizeY;
 
  118   polyEngine->prepareGeometry();
 
  121   iter.startRasterRead( rasterBand, nCellsX, nCellsY, rasterBBox );
 
  123   std::unique_ptr< QgsRasterBlock > block;
 
  129   bool isNoData = 
false;
 
  130   while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
 
  132     double currentY = blockExtent.
yMaximum() - 0.5 * cellSizeY;
 
  133     for ( 
int row = 0; row < iterRows; ++row )
 
  135       double currentX = blockExtent.
xMinimum() + 0.5 * cellSizeX;
 
  136       for ( 
int col = 0; col < iterCols; ++col )
 
  138         const double pixelValue = block->valueAndNoData( row, col, isNoData );
 
  139         if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
 
  144           if ( !pixelRectGeometry.
isNull() && polyEngine->intersects( pixelRectGeometry.
constGet() ) )
 
  148             if ( !intersectGeometry.
isEmpty() )
 
  150               double intersectionArea = intersectGeometry.
area();
 
  151               if ( intersectionArea > 0.0 )
 
  153                 weight = intersectionArea / pixelArea;
 
  154                 addValue( pixelValue, weight );
 
  159         currentX += cellSizeX;
 
  161       currentY -= cellSizeY;
 
  166 bool QgsRasterAnalysisUtils::validPixel( 
double value )
 
  168   return !std::isnan( value );
 
  171 void QgsRasterAnalysisUtils::mapToPixel( 
const double x, 
const double y, 
const QgsRectangle bounds, 
const double unitsPerPixelX, 
const double unitsPerPixelY, 
int &px, 
int &py )
 
  173   px = trunc( ( x - bounds.
xMinimum() ) / unitsPerPixelX );
 
  174   py = trunc( ( y - bounds.
yMaximum() ) / -unitsPerPixelY );
 
  177 void QgsRasterAnalysisUtils::pixelToMap( 
const int px, 
const int py, 
const QgsRectangle bounds, 
const double unitsPerPixelX, 
const double unitsPerPixelY, 
double &x, 
double &y )
 
  179   x = bounds.
xMinimum() + ( px + 0.5 ) * unitsPerPixelX;
 
  180   y = bounds.
yMaximum() - ( py + 0.5 ) * unitsPerPixelY;
 
  183 static QVector< QPair< QString, Qgis::DataType > > sDataTypes;
 
  185 void populateDataTypes()
 
  187   if ( sDataTypes.empty() )
 
  189     sDataTypes.append( qMakePair( QStringLiteral( 
"Byte" ), 
Qgis::Byte ) );
 
  190     sDataTypes.append( qMakePair( QStringLiteral( 
"Int16" ), 
Qgis::Int16 ) );
 
  191     sDataTypes.append( qMakePair( QStringLiteral( 
"UInt16" ), 
Qgis::UInt16 ) );
 
  192     sDataTypes.append( qMakePair( QStringLiteral( 
"Int32" ), 
Qgis::Int32 ) );
 
  193     sDataTypes.append( qMakePair( QStringLiteral( 
"UInt32" ), 
Qgis::UInt32 ) );
 
  194     sDataTypes.append( qMakePair( QStringLiteral( 
"Float32" ), 
Qgis::Float32 ) );
 
  195     sDataTypes.append( qMakePair( QStringLiteral( 
"Float64" ), 
Qgis::Float64 ) );
 
  196     sDataTypes.append( qMakePair( QStringLiteral( 
"CInt16" ), 
Qgis::CInt16 ) );
 
  197     sDataTypes.append( qMakePair( QStringLiteral( 
"CInt32" ), 
Qgis::CInt32 ) );
 
  198     sDataTypes.append( qMakePair( QStringLiteral( 
"CFloat32" ), 
Qgis::CFloat32 ) );
 
  199     sDataTypes.append( qMakePair( QStringLiteral( 
"CFloat64" ), 
Qgis::CFloat64 ) );
 
  203 std::unique_ptr<QgsProcessingParameterDefinition> QgsRasterAnalysisUtils::createRasterTypeParameter( 
const QString &name, 
const QString &description, 
Qgis::DataType defaultType )
 
  208   int defaultChoice = 0;
 
  210   for ( 
auto it = sDataTypes.constBegin(); it != sDataTypes.constEnd(); ++it )
 
  212     names.append( it->first );
 
  213     if ( it->second == defaultType )
 
  218   return qgis::make_unique< QgsProcessingParameterEnum >( name, description, names, 
false, defaultChoice );
 
  221 Qgis::DataType QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( 
int choice )
 
  223   if ( choice < 0 || choice >= sDataTypes.count() )
 
  226   return sDataTypes.value( choice ).second;
 
  229 void QgsRasterAnalysisUtils::applyRasterLogicOperator( 
const std::vector< QgsRasterAnalysisUtils::RasterLogicInput > &inputs, 
QgsRasterDataProvider *destinationRaster, 
double outputNoDataValue, 
const bool treatNoDataAsFalse,
 
  231     std::function<
void( 
const std::vector< std::unique_ptr< QgsRasterBlock > > &, 
bool &, 
bool &, 
int, 
int, 
bool )> &applyLogicFunc,
 
  236   int nbBlocksWidth = 
static_cast< int>( std::ceil( 1.0 * width / maxWidth ) );
 
  237   int nbBlocksHeight = 
static_cast< int >( std::ceil( 1.0 * height / maxHeight ) );
 
  238   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  242   outputIter.startRasterRead( 1, width, height, extent );
 
  249   std::unique_ptr< QgsRasterBlock > outputBlock;
 
  250   while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
 
  252     std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
 
  253     for ( 
const QgsRasterAnalysisUtils::RasterLogicInput &i : inputs )
 
  255       for ( 
int band : i.bands )
 
  257         std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
 
  258         inputBlocks.emplace_back( std::move( b ) );
 
  262     feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  263     for ( 
int row = 0; row < iterRows; row++ )
 
  268       for ( 
int column = 0; column < iterCols; column++ )
 
  271         bool resIsNoData = 
false;
 
  272         applyLogicFunc( inputBlocks, res, resIsNoData, row, column, treatNoDataAsFalse );
 
  280         outputBlock->setValue( row, column, resIsNoData ? outputNoDataValue : ( res ? 1 : 0 ) );
 
  283     destinationRaster->
writeBlock( outputBlock.get(), 1, iterLeft, iterTop );