26using namespace Qt::StringLiterals;
31QString QgsCellStatisticsAlgorithmBase::group()
const
33 return QObject::tr(
"Raster analysis" );
36QString QgsCellStatisticsAlgorithmBase::groupId()
const
38 return u
"rasteranalysis"_s;
41void QgsCellStatisticsAlgorithmBase::initAlgorithm(
const QVariantMap & )
45 addSpecificAlgorithmParams();
53 addParameter( output_nodata_parameter.release() );
57 auto createOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATE_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
58 createOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
60 addParameter( createOptsParam.release() );
62 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATION_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
63 creationOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
65 addParameter( creationOptsParam.release() );
78 QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, u
"REFERENCE_LAYER"_s, context );
79 if ( !referenceLayer )
82 mIgnoreNoData = parameterAsBool( parameters, u
"IGNORE_NODATA"_s, context );
83 mNoDataValue = parameterAsDouble( parameters, u
"OUTPUT_NODATA_VALUE"_s, context );
84 mCrs = referenceLayer->
crs();
87 mLayerWidth = referenceLayer->
width();
88 mLayerHeight = referenceLayer->
height();
89 mExtent = referenceLayer->
extent();
91 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, u
"INPUT"_s, context );
92 QList<QgsRasterLayer *> rasterLayers;
93 rasterLayers.reserve( layers.count() );
102 QgsRasterAnalysisUtils::RasterLogicInput input;
106 input.interface = input.sourceDataProvider.get();
108 if ( layer->
crs() != mCrs )
110 input.projector = std::make_unique<QgsRasterProjector>();
111 input.projector->setInput( input.sourceDataProvider.get() );
113 input.interface = input.projector.get();
115 mInputs.emplace_back( std::move( input ) );
122 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
124 for (
int band : i.bands )
127 if (
static_cast<int>( mDataType ) <
static_cast<int>( inputDataType ) )
128 mDataType = inputDataType;
132 prepareSpecificAlgorithmParameters( parameters, context, feedback );
140 QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
142 const QString optionsString = parameterAsString( parameters, u
"CREATE_OPTIONS"_s, context );
143 if ( !optionsString.isEmpty() )
144 creationOptions = optionsString;
146 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
147 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
149 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
150 writer->setOutputProviderKey( u
"gdal"_s );
151 if ( !creationOptions.isEmpty() )
153 writer->setCreationOptions( creationOptions.split(
'|' ) );
155 writer->setOutputFormat( outputFormat );
156 mOutputRasterDataProvider.reset( writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
157 if ( !mOutputRasterDataProvider )
159 if ( !mOutputRasterDataProvider->isValid() )
162 mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
165 const bool hasReportsDuringClose = mOutputRasterDataProvider->hasReportsDuringClose();
166 mMaxProgressDuringBlockWriting = hasReportsDuringClose ? 50.0 : 100.0;
169 processRasterStack( feedback );
171 if ( feedback && hasReportsDuringClose )
174 if ( !mOutputRasterDataProvider->closeWithProgress( scaledFeedback.get() ) )
182 mOutputRasterDataProvider.reset();
185 outputs.insert( u
"EXTENT"_s, mExtent.toString() );
186 outputs.insert( u
"CRS_AUTHID"_s, mCrs.authid() );
187 outputs.insert( u
"WIDTH_IN_PIXELS"_s, mLayerWidth );
188 outputs.insert( u
"HEIGHT_IN_PIXELS"_s, mLayerHeight );
189 outputs.insert( u
"TOTAL_PIXEL_COUNT"_s, layerSize );
190 outputs.insert( u
"OUTPUT"_s, outputFile );
199QString QgsCellStatisticsAlgorithm::displayName()
const
201 return QObject::tr(
"Cell statistics" );
204QString QgsCellStatisticsAlgorithm::name()
const
206 return u
"cellstatistics"_s;
209QStringList QgsCellStatisticsAlgorithm::tags()
const
211 return QObject::tr(
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split(
',' );
214QString QgsCellStatisticsAlgorithm::shortHelpString()
const
216 return QObject::tr(
"The Cell statistics algorithm computes a value for each cell of the "
217 "output raster. At each cell location, "
218 "the output value is defined as a function of all overlaid cell values of the "
220 "The output raster's extent and resolution is defined by a reference "
221 "raster. The following functions can be applied on the input "
222 "raster cells per output raster cell location:\n"
228 " <li>Standard deviation</li>"
232 " <li>Minority (least frequent value)</li>"
233 " <li>Majority (most frequent value)</li>"
234 " <li>Range (max-min)</li>"
235 " <li>Variety (count of unique values)</li>"
237 "Input raster layers that do not match the cell size of the reference raster layer will be "
238 "resampled using nearest neighbor resampling. The output raster data type will be set to "
239 "the most complex data type present in the input datasets except when using the functions "
240 "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"
241 "<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"
242 "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n"
243 "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the "
244 "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n"
245 "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all "
246 "input cell values are equal." );
249QString QgsCellStatisticsAlgorithm::shortDescription()
const
251 return QObject::tr(
"Generates a raster whose cell values are computed from overlaid cell values of the input rasters." );
254QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
const
256 return new QgsCellStatisticsAlgorithm();
259void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
261 QStringList statistics = QStringList();
262 statistics << QObject::tr(
"Sum" )
263 << QObject::tr(
"Count" )
264 << QObject::tr(
"Mean" )
265 << QObject::tr(
"Median" )
266 << QObject::tr(
"Standard deviation" )
267 << QObject::tr(
"Variance" )
268 << QObject::tr(
"Minimum" )
269 << QObject::tr(
"Maximum" )
270 << QObject::tr(
"Minority" )
271 << QObject::tr(
"Majority" )
272 << QObject::tr(
"Range" )
273 << QObject::tr(
"Variety" );
282 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, u
"STATISTIC"_s, context ) );
286 mMethod == QgsRasterAnalysisUtils::Mean || mMethod == QgsRasterAnalysisUtils::StandardDeviation || mMethod == QgsRasterAnalysisUtils::Variance || ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) )
289 if (
static_cast<int>( mDataType ) < 6 )
292 else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety )
294 if (
static_cast<int>( mDataType ) > 5 )
302 mOutputRasterDataProvider->setEditable(
true );
304 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
311 std::unique_ptr<QgsRasterBlock> outputBlock;
312 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
314 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
315 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
319 for (
int band : i.bands )
323 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
324 inputBlocks.emplace_back( std::move( b ) );
328 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
329 for (
int row = 0; row < iterRows; row++ )
334 for (
int col = 0; col < iterCols; col++ )
337 bool noDataInStack =
false;
338 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
339 int cellValueStackSize = cellValues.size();
341 if ( noDataInStack && !mIgnoreNoData )
345 if ( mMethod == QgsRasterAnalysisUtils::Count )
346 outputBlock->setValue( row, col, cellValueStackSize );
349 outputBlock->setValue( row, col, mNoDataValue );
352 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
356 case QgsRasterAnalysisUtils::Sum:
357 result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
359 case QgsRasterAnalysisUtils::Count:
360 result = cellValueStackSize;
362 case QgsRasterAnalysisUtils::Mean:
363 result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
365 case QgsRasterAnalysisUtils::Median:
366 result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
368 case QgsRasterAnalysisUtils::StandardDeviation:
369 result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
371 case QgsRasterAnalysisUtils::Variance:
372 result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
374 case QgsRasterAnalysisUtils::Minimum:
375 result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
377 case QgsRasterAnalysisUtils::Maximum:
378 result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
380 case QgsRasterAnalysisUtils::Minority:
381 result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
383 case QgsRasterAnalysisUtils::Majority:
384 result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
386 case QgsRasterAnalysisUtils::Range:
387 result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
389 case QgsRasterAnalysisUtils::Variety:
390 result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
393 outputBlock->setValue( row, col, result );
398 outputBlock->setValue( row, col, mNoDataValue );
402 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
404 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
407 mOutputRasterDataProvider->setEditable(
false );
413QString QgsCellStatisticsPercentileAlgorithm::displayName()
const
415 return QObject::tr(
"Cell stack percentile" );
418QString QgsCellStatisticsPercentileAlgorithm::name()
const
420 return u
"cellstackpercentile"_s;
423QStringList QgsCellStatisticsPercentileAlgorithm::tags()
const
425 return QObject::tr(
"cell,pixel,statistic,percentile,quantile,quartile" ).split(
',' );
428QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
const
430 return QObject::tr(
"This algorithm generates a raster containing the cell-wise percentile value of a stack of input rasters. "
431 "The percentile to return is determined by the percentile input value (ranges between 0 and 1). "
432 "At each cell location, the specified percentile is obtained using the respective value from "
433 "the stack of all overlaid and sorted cell values of the input rasters.\n\n"
434 "There are three methods for percentile calculation:"
436 " <li>Nearest rank</li>"
437 " <li>Inclusive linear interpolation (PERCENTILE.INC)</li>"
438 " <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>"
440 "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the "
441 "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation "
442 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
443 "The output raster's extent and resolution is defined by a reference "
444 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
445 "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. "
446 "The output raster data type will be set to the most complex data type present in the input datasets. " );
449QString QgsCellStatisticsPercentileAlgorithm::shortDescription()
const
451 return QObject::tr(
"Generates a raster containing the cell-wise percentile value of a stack of input rasters." );
454QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
const
456 return new QgsCellStatisticsPercentileAlgorithm();
459void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
461 addParameter(
new QgsProcessingParameterEnum( u
"METHOD"_s, 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 ) );
468 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentileMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
469 mPercentile = parameterAsDouble( parameters, u
"PERCENTILE"_s, context );
473 if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile &&
static_cast<int>( mDataType ) < 6 )
481 mOutputRasterDataProvider->setEditable(
true );
483 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
490 std::unique_ptr<QgsRasterBlock> outputBlock;
491 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
493 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
494 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
498 for (
int band : i.bands )
502 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
503 inputBlocks.emplace_back( std::move( b ) );
507 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
508 for (
int row = 0; row < iterRows; row++ )
513 for (
int col = 0; col < iterCols; col++ )
516 bool noDataInStack =
false;
517 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
518 int cellValueStackSize = cellValues.size();
520 if ( noDataInStack && !mIgnoreNoData )
522 outputBlock->setValue( row, col, mNoDataValue );
524 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
528 case QgsRasterAnalysisUtils::NearestRankPercentile:
529 result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
531 case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
532 result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
534 case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
535 result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
538 outputBlock->setValue( row, col, result );
543 outputBlock->setValue( row, col, mNoDataValue );
547 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
549 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
552 mOutputRasterDataProvider->setEditable(
false );
558QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
const
560 return QObject::tr(
"Cell stack percent rank from value" );
563QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
const
565 return u
"cellstackpercentrankfromvalue"_s;
568QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
const
570 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value" ).split(
',' );
573QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
const
575 return QObject::tr(
"This algorithm generates a raster containing the cell-wise percent rank value of a stack of input rasters based on a single input value.\n\n"
576 "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. "
577 "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
578 "There are two methods for percentile calculation:"
580 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
581 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
583 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
584 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
585 "The output raster's extent and resolution is defined by a reference "
586 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
587 "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. "
588 "The output raster data type will always be Float32." );
591QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortDescription()
const
593 return QObject::tr(
"Generates a raster containing the cell-wise percent rank value of a stack of input rasters based on a single input value." );
596QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
const
598 return new QgsCellStatisticsPercentRankFromValueAlgorithm();
601void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
603 addParameter(
new QgsProcessingParameterEnum( u
"METHOD"_s, QObject::tr(
"Method" ), QStringList() << QObject::tr(
"Inclusive linear interpolation (PERCENTRANK.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTRANK.EXC)" ),
false, 0,
false ) );
610 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
611 mValue = parameterAsDouble( parameters, u
"VALUE"_s, context );
618void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
620 mOutputRasterDataProvider->setEditable(
true );
622 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
629 std::unique_ptr<QgsRasterBlock> outputBlock;
630 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
632 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
633 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
637 for (
int band : i.bands )
641 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
642 inputBlocks.emplace_back( std::move( b ) );
646 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
647 for (
int row = 0; row < iterRows; row++ )
652 for (
int col = 0; col < iterCols; col++ )
655 bool noDataInStack =
false;
656 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
657 int cellValueStackSize = cellValues.size();
659 if ( noDataInStack && !mIgnoreNoData )
661 outputBlock->setValue( row, col, mNoDataValue );
663 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
667 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
668 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
670 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
671 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
674 outputBlock->setValue( row, col, result );
679 outputBlock->setValue( row, col, mNoDataValue );
683 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
685 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
688 mOutputRasterDataProvider->setEditable(
false );
695QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
const
697 return QObject::tr(
"Cell stack percentrank from raster layer" );
700QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
const
702 return u
"cellstackpercentrankfromrasterlayer"_s;
705QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
const
707 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split(
',' );
710QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
const
712 return QObject::tr(
"This algorithm generates a raster containing the cell-wise percent rank value of a stack of input rasters "
713 "based on an input value raster.\n\n"
714 "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. "
715 "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"
716 "There are two methods for percentile calculation:"
718 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
719 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
721 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
722 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
723 "The output raster's extent and resolution is defined by a reference "
724 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
725 "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. "
726 "The output raster data type will always be Float32." );
729QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortDescription()
const
731 return QObject::tr(
"Generates a raster containing the cell-wise percent rank value of a stack of input rasters based on an input value raster." );
734QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
const
736 return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
739void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
742 addParameter(
new QgsProcessingParameterBand( u
"VALUE_RASTER_BAND"_s, QObject::tr(
"Value raster band" ), 1, u
"VALUE_LAYER"_s ) );
743 addParameter(
new QgsProcessingParameterEnum( u
"METHOD"_s, QObject::tr(
"Method" ), QStringList() << QObject::tr(
"Inclusive linear interpolation (PERCENTRANK.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTRANK.EXC)" ),
false, 0,
false ) );
749 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
751 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, u
"INPUT_VALUE_RASTER"_s, context );
752 if ( !inputValueRaster )
757 mValueRasterBand = parameterAsInt( parameters, u
"VALUE_RASTER_BAND"_s, context );
764void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
766 mOutputRasterDataProvider->setEditable(
true );
768 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
775 std::unique_ptr<QgsRasterBlock> outputBlock;
776 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
778 std::unique_ptr<QgsRasterBlock> valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
780 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
781 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
785 for (
int band : i.bands )
789 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
790 inputBlocks.emplace_back( std::move( b ) );
794 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
795 for (
int row = 0; row < iterRows; row++ )
800 for (
int col = 0; col < iterCols; col++ )
802 bool percentRankValueIsNoData =
false;
803 double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
806 bool noDataInStack =
false;
807 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
808 int cellValueStackSize = cellValues.size();
810 if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
812 outputBlock->setValue( row, col, mNoDataValue );
814 else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
818 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
819 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
821 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
822 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
825 outputBlock->setValue( row, col, result );
830 outputBlock->setValue( row, col, mNoDataValue );
834 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
836 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
839 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).
@ Hidden
Parameter is hidden and should not be shown to users.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ Double
Double/float values.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
static std::unique_ptr< QgsFeedback > createScaledFeedback(QgsFeedback *parentFeedback, double startPercentage, double endPercentage)
Returns a feedback object whose [0, 100] progression range will be mapped to parentFeedback [startPer...
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.
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.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A raster layer parameter for processing algorithms.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
Iterator for sequentially processing raster cells.
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...