26 QString QgsCellStatisticsAlgorithmBase::group()
 const 
   28   return QObject::tr( 
"Raster analysis" );
 
   31 QString QgsCellStatisticsAlgorithmBase::groupId()
 const 
   33   return QStringLiteral( 
"rasteranalysis" );
 
   36 void QgsCellStatisticsAlgorithmBase::initAlgorithm( 
const QVariantMap & )
 
   41   addSpecificAlgorithmParams();
 
   47   std::unique_ptr< QgsProcessingParameterNumber > output_nodata_parameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( 
"OUTPUT_NODATA_VALUE" ), QObject::tr( 
"Output NoData value" ), 
QgsProcessingParameterNumber::Double, -9999, 
false );
 
   49   addParameter( output_nodata_parameter.release() );
 
   52                 QObject::tr( 
"Output layer" ) ) );
 
   63   QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, QStringLiteral( 
"REFERENCE_LAYER" ), context );
 
   64   if ( !referenceLayer )
 
   67   mIgnoreNoData = parameterAsBool( parameters, QStringLiteral( 
"IGNORE_NODATA" ), context );
 
   68   mNoDataValue = parameterAsDouble( parameters, QStringLiteral( 
"OUTPUT_NODATA_VALUE" ), context );
 
   69   mCrs = referenceLayer->
crs();
 
   72   mLayerWidth = referenceLayer->
width();
 
   73   mLayerHeight = referenceLayer->
height();
 
   74   mExtent = referenceLayer->
extent();
 
   76   const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral( 
"INPUT" ), context );
 
   77   QList< QgsRasterLayer * > rasterLayers;
 
   78   rasterLayers.reserve( layers.count() );
 
   87       QgsRasterAnalysisUtils::RasterLogicInput input;
 
   91       input.interface = input.sourceDataProvider.get();
 
   93       if ( layer->
crs() != mCrs )
 
   95         input.projector = std::make_unique< QgsRasterProjector >();
 
   96         input.projector->setInput( input.sourceDataProvider.get() );
 
   98         input.interface = input.projector.get();
 
  100       mInputs.emplace_back( std::move( input ) );
 
  107   for ( 
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
 
  109     for ( 
int band : i.bands )
 
  112       if ( 
static_cast<int>( mDataType ) < 
static_cast<int>( inputDataType ) )
 
  113         mDataType = inputDataType; 
 
  117   prepareSpecificAlgorithmParameters( parameters, context, feedback );
 
  125   const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( 
"OUTPUT" ), context );
 
  126   QFileInfo fi( outputFile );
 
  129   std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
 
  130   writer->setOutputProviderKey( QStringLiteral( 
"gdal" ) );
 
  131   writer->setOutputFormat( outputFormat );
 
  132   mOutputRasterDataProvider = writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs );
 
  133   if ( !mOutputRasterDataProvider )
 
  135   if ( !mOutputRasterDataProvider->isValid() )
 
  138   mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
 
  142   processRasterStack( feedback );
 
  145   outputs.insert( QStringLiteral( 
"EXTENT" ), mExtent.toString() );
 
  146   outputs.insert( QStringLiteral( 
"CRS_AUTHID" ), mCrs.authid() );
 
  147   outputs.insert( QStringLiteral( 
"WIDTH_IN_PIXELS" ), mLayerWidth );
 
  148   outputs.insert( QStringLiteral( 
"HEIGHT_IN_PIXELS" ), mLayerHeight );
 
  149   outputs.insert( QStringLiteral( 
"TOTAL_PIXEL_COUNT" ), layerSize );
 
  150   outputs.insert( QStringLiteral( 
"OUTPUT" ), outputFile );
 
  159 QString QgsCellStatisticsAlgorithm::displayName()
 const 
  161   return QObject::tr( 
"Cell statistics" );
 
  164 QString QgsCellStatisticsAlgorithm::name()
 const 
  166   return QStringLiteral( 
"cellstatistics" );
 
  169 QStringList QgsCellStatisticsAlgorithm::tags()
 const 
  171   return QObject::tr( 
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split( 
',' );
 
  174 QString QgsCellStatisticsAlgorithm::shortHelpString()
 const 
  176   return QObject::tr( 
"The Cell statistics algorithm computes a value for each cell of the " 
  177                       "output raster. At each cell location, " 
  178                       "the output value is defined as a function of all overlaid cell values of the " 
  180                       "The output raster's extent and resolution is defined by a reference " 
  181                       "raster. The following functions can be applied on the input " 
  182                       "raster cells per output raster cell location:\n" 
  188                       "   <li>Standard deviation</li>" 
  192                       "   <li>Minority (least frequent value)</li>" 
  193                       "   <li>Majority (most frequent value)</li>" 
  194                       "   <li>Range (max-min)</li>" 
  195                       "   <li>Variety (count of unique values)</li>" 
  197                       "Input raster layers that do not match the cell size of the reference raster layer will be " 
  198                       "resampled using nearest neighbor resampling. The output raster data type will be set to " 
  199                       "the most complex data type present in the input datasets except when using the functions " 
  200                       "Mean, Standard deviation and Variance (data type is always Float32/Float64 depending on input float type) or Count and Variety (data type is always Int32).\n" 
  201                       "<i>Calculation details - general:</i> NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set.\n" 
  202                       "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n" 
  203                       "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the " 
  204                       "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n" 
  205                       "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all " 
  206                       "input cell values are equal." );
 
  209 QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
 const 
  211   return new QgsCellStatisticsAlgorithm();
 
  214 void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
 
  216   QStringList statistics = QStringList();
 
  217   statistics << QObject::tr( 
"Sum" )
 
  218              << QObject::tr( 
"Count" )
 
  219              << QObject::tr( 
"Mean" )
 
  220              << QObject::tr( 
"Median" )
 
  221              << QObject::tr( 
"Standard deviation" )
 
  222              << QObject::tr( 
"Variance" )
 
  223              << QObject::tr( 
"Minimum" )
 
  224              << QObject::tr( 
"Maximum" )
 
  225              << QObject::tr( 
"Minority" )
 
  226              << QObject::tr( 
"Majority" )
 
  227              << QObject::tr( 
"Range" )
 
  228              << QObject::tr( 
"Variety" );
 
  230   addParameter( 
new QgsProcessingParameterEnum( QStringLiteral( 
"STATISTIC" ), QObject::tr( 
"Statistic" ),  statistics, 
false, 0, 
false ) );
 
  237   mMethod = 
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, QStringLiteral( 
"STATISTIC" ), context ) );
 
  241     mMethod == QgsRasterAnalysisUtils::Mean ||
 
  242     mMethod == QgsRasterAnalysisUtils::StandardDeviation ||
 
  243     mMethod == QgsRasterAnalysisUtils::Variance ||
 
  244     ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) )
 
  247     if ( 
static_cast<int>( mDataType ) < 6 )
 
  250   else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety ) 
 
  252     if ( 
static_cast<int>( mDataType ) > 5 ) 
 
  262   int nbBlocksWidth = 
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
 
  263   int nbBlocksHeight = 
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
 
  264   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  265   mOutputRasterDataProvider->setEditable( 
true );
 
  267   outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
 
  274   std::unique_ptr< QgsRasterBlock > outputBlock;
 
  275   while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
 
  277     std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
 
  278     for ( 
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
 
  282       for ( 
int band : i.bands )
 
  286         std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
 
  287         inputBlocks.emplace_back( std::move( b ) );
 
  291     feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  292     for ( 
int row = 0; row < iterRows; row++ )
 
  297       for ( 
int col = 0; col < iterCols; col++ )
 
  300         bool noDataInStack = 
false;
 
  301         std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
 
  302         int cellValueStackSize = cellValues.size();
 
  304         if ( noDataInStack && !mIgnoreNoData )
 
  308           if ( mMethod == QgsRasterAnalysisUtils::Count )
 
  309             outputBlock->setValue( row, col,  cellValueStackSize );
 
  312             outputBlock->setValue( row, col, mNoDataValue );
 
  315         else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
 
  319             case QgsRasterAnalysisUtils::Sum:
 
  320               result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
 
  322             case QgsRasterAnalysisUtils::Count:
 
  323               result = cellValueStackSize;
 
  325             case QgsRasterAnalysisUtils::Mean:
 
  326               result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
 
  328             case QgsRasterAnalysisUtils::Median:
 
  329               result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
 
  331             case QgsRasterAnalysisUtils::StandardDeviation:
 
  332               result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
 
  334             case QgsRasterAnalysisUtils::Variance:
 
  335               result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
 
  337             case QgsRasterAnalysisUtils::Minimum:
 
  338               result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
 
  340             case QgsRasterAnalysisUtils::Maximum:
 
  341               result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
 
  343             case QgsRasterAnalysisUtils::Minority:
 
  344               result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
 
  346             case QgsRasterAnalysisUtils::Majority:
 
  347               result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
 
  349             case QgsRasterAnalysisUtils::Range:
 
  350               result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
 
  352             case QgsRasterAnalysisUtils::Variety:
 
  353               result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
 
  356           outputBlock->setValue( row, col, result );
 
  361           outputBlock->setValue( row, col, mNoDataValue );
 
  365     mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
 
  367   mOutputRasterDataProvider->setEditable( 
false );
 
  373 QString QgsCellStatisticsPercentileAlgorithm::displayName()
 const 
  375   return QObject::tr( 
"Cell stack percentile" );
 
  378 QString QgsCellStatisticsPercentileAlgorithm::name()
 const 
  380   return QStringLiteral( 
"cellstackpercentile" );
 
  383 QStringList QgsCellStatisticsPercentileAlgorithm::tags()
 const 
  385   return QObject::tr( 
"cell,pixel,statistic,percentile,quantile,quartile" ).split( 
',' );
 
  388 QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
 const 
  390   return QObject::tr( 
"The Cell stack percentile algorithm returns the cell-wise percentile value of a stack of rasters " 
  391                       "and writes the results to an output raster. The percentile to return is determined by the percentile input value (ranges between 0 and 1). " 
  392                       "At each cell location, the specified percentile is obtained using the respective value from " 
  393                       "the stack of all overlaid and sorted cell values of the input rasters.\n\n" 
  394                       "There are three methods for percentile calculation:" 
  396                       "   <li>Nearest rank</li>" 
  397                       "   <li>Inclusive linear interpolation (PERCENTILE.INC)</li>" 
  398                       "   <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>" 
  400                       "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the " 
  401                       "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation " 
  402                       "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n" 
  403                       "The output raster's extent and resolution is defined by a reference " 
  404                       "raster. If the input raster layers that do not match the cell size of the reference raster layer will be " 
  405                       "resampled using nearest neighbor resampling. NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set. " 
  406                       "The output raster data type will be set to the most complex data type present in the input datasets. " );
 
  409 QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
 const 
  411   return new QgsCellStatisticsPercentileAlgorithm();
 
  414 void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
 
  416   addParameter( 
new QgsProcessingParameterEnum( QStringLiteral( 
"METHOD" ), QObject::tr( 
"Method" ), QStringList() << QObject::tr( 
"Nearest rank" ) << QObject::tr( 
"Inclusive linear interpolation (PERCENTILE.INC)" ) << QObject::tr( 
"Exclusive linear interpolation (PERCENTILE.EXC)" ), 
false, 0, 
false ) );
 
  423   mMethod = 
static_cast< QgsRasterAnalysisUtils::CellValuePercentileMethods 
>( parameterAsEnum( parameters, QStringLiteral( 
"METHOD" ), context ) );
 
  424   mPercentile = parameterAsDouble( parameters, QStringLiteral( 
"PERCENTILE" ), context );
 
  428   if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile && 
static_cast< int >( mDataType ) < 6 )
 
  439   int nbBlocksWidth = 
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
 
  440   int nbBlocksHeight = 
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
 
  441   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  442   mOutputRasterDataProvider->setEditable( 
true );
 
  444   outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
 
  451   std::unique_ptr< QgsRasterBlock > outputBlock;
 
  452   while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
 
  454     std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
 
  455     for ( 
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
 
  459       for ( 
int band : i.bands )
 
  463         std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
 
  464         inputBlocks.emplace_back( std::move( b ) );
 
  468     feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  469     for ( 
int row = 0; row < iterRows; row++ )
 
  474       for ( 
int col = 0; col < iterCols; col++ )
 
  477         bool noDataInStack = 
false;
 
  478         std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
 
  479         int cellValueStackSize = cellValues.size();
 
  481         if ( noDataInStack && !mIgnoreNoData )
 
  483           outputBlock->setValue( row, col, mNoDataValue );
 
  485         else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
 
  489             case QgsRasterAnalysisUtils::NearestRankPercentile:
 
  490               result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
 
  492             case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
 
  493               result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
 
  495             case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
 
  496               result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
 
  499           outputBlock->setValue( row, col, result );
 
  504           outputBlock->setValue( row, col, mNoDataValue );
 
  508     mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
 
  510   mOutputRasterDataProvider->setEditable( 
false );
 
  516 QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
 const 
  518   return QObject::tr( 
"Cell stack percent rank from value" );
 
  521 QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
 const 
  523   return QStringLiteral( 
"cellstackpercentrankfromvalue" );
 
  526 QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
 const 
  528   return QObject::tr( 
"cell,pixel,statistic,percentrank,rank,percent,value" ).split( 
',' );
 
  531 QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
 const 
  533   return QObject::tr( 
"The Cell stack percentrank from value algorithm calculates the cell-wise percentrank value of a stack of rasters based on a single input value " 
  534                       "and writes them to an output raster.\n\n" 
  535                       "At each cell location, the specified value is ranked among the respective values in the stack of all overlaid and sorted cell values from the input rasters. " 
  536                       "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n" 
  537                       "There are two methods for percentile calculation:" 
  539                       "   <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>" 
  540                       "   <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>" 
  542                       "The linear interpolation method return the unique percent rank for different values. Both interpolation " 
  543                       "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n" 
  544                       "The output raster's extent and resolution is defined by a reference " 
  545                       "raster. If the input raster layers that do not match the cell size of the reference raster layer will be " 
  546                       "resampled using nearest neighbor resampling. NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set. " 
  547                       "The output raster data type will always be Float32." );
 
  550 QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
 const 
  552   return new QgsCellStatisticsPercentRankFromValueAlgorithm();
 
  555 void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
 
  557   addParameter( 
new QgsProcessingParameterEnum( QStringLiteral( 
"METHOD" ), QObject::tr( 
"Method" ), QStringList() << QObject::tr( 
"Inclusive linear interpolation (PERCENTRANK.INC)" ) << QObject::tr( 
"Exclusive linear interpolation (PERCENTRANK.EXC)" ), 
false, 0, 
false ) );
 
  564   mMethod = 
static_cast< QgsRasterAnalysisUtils::CellValuePercentRankMethods 
>( parameterAsEnum( parameters, QStringLiteral( 
"METHOD" ), context ) );
 
  565   mValue = parameterAsDouble( parameters, QStringLiteral( 
"VALUE" ), context );
 
  572 void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack( 
QgsProcessingFeedback *feedback )
 
  577   int nbBlocksWidth = 
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
 
  578   int nbBlocksHeight = 
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
 
  579   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  580   mOutputRasterDataProvider->setEditable( 
true );
 
  582   outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
 
  589   std::unique_ptr< QgsRasterBlock > outputBlock;
 
  590   while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
 
  592     std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
 
  593     for ( 
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
 
  597       for ( 
int band : i.bands )
 
  601         std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
 
  602         inputBlocks.emplace_back( std::move( b ) );
 
  606     feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  607     for ( 
int row = 0; row < iterRows; row++ )
 
  612       for ( 
int col = 0; col < iterCols; col++ )
 
  615         bool noDataInStack = 
false;
 
  616         std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
 
  617         int cellValueStackSize = cellValues.size();
 
  619         if ( noDataInStack && !mIgnoreNoData )
 
  621           outputBlock->setValue( row, col, mNoDataValue );
 
  623         else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
 
  627             case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
 
  628               result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
 
  630             case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
 
  631               result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
 
  634           outputBlock->setValue( row, col, result );
 
  639           outputBlock->setValue( row, col, mNoDataValue );
 
  643     mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
 
  645   mOutputRasterDataProvider->setEditable( 
false );
 
  652 QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
 const 
  654   return QObject::tr( 
"Cell stack percentrank from raster layer" );
 
  657 QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
 const 
  659   return QStringLiteral( 
"cellstackpercentrankfromrasterlayer" );
 
  662 QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
 const 
  664   return QObject::tr( 
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split( 
',' );
 
  667 QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
 const 
  669   return QObject::tr( 
"The Cell stack percentrank from raster layer algorithm calculates the cell-wise percentrank value of a stack of rasters based on an input value raster " 
  670                       "and writes them to an output raster.\n\n" 
  671                       "At each cell location, the current value of the value raster is used ranked among the respective values in the stack of all overlaid and sorted cell values of the input rasters. " 
  672                       "For values outside of the the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n" 
  673                       "There are two methods for percentile calculation:" 
  675                       "   <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>" 
  676                       "   <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>" 
  678                       "The linear interpolation method return the unique percent rank for different values. Both interpolation " 
  679                       "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n" 
  680                       "The output raster's extent and resolution is defined by a reference " 
  681                       "raster. If the input raster layers that do not match the cell size of the reference raster layer will be " 
  682                       "resampled using nearest neighbor resampling.  NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set. " 
  683                       "The output raster data type will always be Float32." );
 
  686 QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
 const 
  688   return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
 
  691 void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
 
  694   addParameter( 
new QgsProcessingParameterBand( QStringLiteral( 
"VALUE_RASTER_BAND" ), QObject::tr( 
"Value raster band" ), 1, QStringLiteral( 
"VALUE_LAYER" ) ) );
 
  695   addParameter( 
new QgsProcessingParameterEnum( QStringLiteral( 
"METHOD" ), QObject::tr( 
"Method" ), QStringList() << QObject::tr( 
"Inclusive linear interpolation (PERCENTRANK.INC)" ) << QObject::tr( 
"Exclusive linear interpolation (PERCENTRANK.EXC)" ), 
false, 0, 
false ) );
 
  701   mMethod = 
static_cast< QgsRasterAnalysisUtils::CellValuePercentRankMethods 
>( parameterAsEnum( parameters, QStringLiteral( 
"METHOD" ), context ) );
 
  703   QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral( 
"INPUT_VALUE_RASTER" ), context );
 
  704   if ( !inputValueRaster )
 
  709   mValueRasterBand = parameterAsInt( parameters, QStringLiteral( 
"VALUE_RASTER_BAND" ), context );
 
  716 void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack( 
QgsProcessingFeedback *feedback )
 
  720   int nbBlocksWidth = 
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
 
  721   int nbBlocksHeight = 
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
 
  722   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  723   mOutputRasterDataProvider->setEditable( 
true );
 
  725   outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
 
  732   std::unique_ptr< QgsRasterBlock > outputBlock;
 
  733   while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
 
  735     std::unique_ptr< QgsRasterBlock > valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
 
  737     std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
 
  738     for ( 
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
 
  742       for ( 
int band : i.bands )
 
  746         std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
 
  747         inputBlocks.emplace_back( std::move( b ) );
 
  751     feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  752     for ( 
int row = 0; row < iterRows; row++ )
 
  757       for ( 
int col = 0; col < iterCols; col++ )
 
  759         bool percentRankValueIsNoData = 
false;
 
  760         double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
 
  763         bool noDataInStack = 
false;
 
  764         std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
 
  765         int cellValueStackSize = cellValues.size();
 
  767         if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
 
  769           outputBlock->setValue( row, col, mNoDataValue );
 
  771         else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
 
  775             case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
 
  776               result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
 
  778             case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
 
  779               result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
 
  782           outputBlock->setValue( row, col, result );
 
  787           outputBlock->setValue( row, col, mNoDataValue );
 
  791     mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
 
  793   mOutputRasterDataProvider->setEditable( 
false );
 
DataType
Raster data types.
@ Float32
Thirty two bit floating point (float)
@ Byte
Eight bit unsigned integer (quint8)
@ Int32
Thirty two bit signed integer (qint32)
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
A numeric output for processing algorithms.
A string output for processing algorithms.
A raster band parameter for Processing algorithms.
A boolean parameter for processing algorithms.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A parameter for processing algorithms which accepts multiple map layers.
A numeric parameter for processing algorithms.
@ Double
Double/float values.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A raster layer parameter for processing algorithms.
@ TypeRaster
Raster layers.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
Iterator for sequentially processing raster cells.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
Represents a raster layer.
int height() const
Returns the height of the (unclipped) raster.
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis.
int width() const
Returns the width of the (unclipped) raster.
A rectangle specified with double values.
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...