26using namespace Qt::StringLiterals;
29#define EXCLUDE_CPPCHECK
30#ifdef EXCLUDE_CPPCHECK
35QString QgsCellStatisticsAlgorithmBase::group()
const
37 return QObject::tr(
"Raster analysis" );
40QString QgsCellStatisticsAlgorithmBase::groupId()
const
42 return u
"rasteranalysis"_s;
45void QgsCellStatisticsAlgorithmBase::initAlgorithm(
const QVariantMap & )
49 addSpecificAlgorithmParams();
57 addParameter( output_nodata_parameter.release() );
61 auto createOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATE_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
62 createOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
64 addParameter( createOptsParam.release() );
66 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATION_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
67 creationOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
69 addParameter( creationOptsParam.release() );
82 QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, u
"REFERENCE_LAYER"_s, context );
83 if ( !referenceLayer )
86 mIgnoreNoData = parameterAsBool( parameters, u
"IGNORE_NODATA"_s, context );
87 mNoDataValue = parameterAsDouble( parameters, u
"OUTPUT_NODATA_VALUE"_s, context );
88 mCrs = referenceLayer->
crs();
91 mLayerWidth = referenceLayer->
width();
92 mLayerHeight = referenceLayer->
height();
93 mExtent = referenceLayer->
extent();
95 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, u
"INPUT"_s, context );
96 QList<QgsRasterLayer *> rasterLayers;
97 rasterLayers.reserve( layers.count() );
106 QgsRasterAnalysisUtils::RasterLogicInput input;
110 input.interface = input.sourceDataProvider.get();
112 if ( layer->
crs() != mCrs )
114 input.projector = std::make_unique<QgsRasterProjector>();
115 input.projector->setInput( input.sourceDataProvider.get() );
117 input.interface = input.projector.get();
119 mInputs.emplace_back( std::move( input ) );
126 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
128 for (
int band : i.bands )
131 if (
static_cast<int>( mDataType ) <
static_cast<int>( inputDataType ) )
132 mDataType = inputDataType;
136 prepareSpecificAlgorithmParameters( parameters, context, feedback );
144 QGS_MARK_ALGORITHM_SOURCE
146 QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
148 const QString optionsString = parameterAsString( parameters, u
"CREATE_OPTIONS"_s, context );
149 if ( !optionsString.isEmpty() )
150 creationOptions = optionsString;
152 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
153 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
155 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
156 writer->setOutputProviderKey( u
"gdal"_s );
157 if ( !creationOptions.isEmpty() )
159 writer->setCreationOptions( creationOptions.split(
'|' ) );
161 writer->setOutputFormat( outputFormat );
162 mOutputRasterDataProvider.reset( writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
163 if ( !mOutputRasterDataProvider )
165 if ( !mOutputRasterDataProvider->isValid() )
168 mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
171 const bool hasReportsDuringClose = mOutputRasterDataProvider->hasReportsDuringClose();
172 mMaxProgressDuringBlockWriting = hasReportsDuringClose ? 50.0 : 100.0;
175 processRasterStack( feedback );
177 if ( feedback && hasReportsDuringClose )
180 if ( !mOutputRasterDataProvider->closeWithProgress( scaledFeedback.get() ) )
188 mOutputRasterDataProvider.reset();
191 outputs.insert( u
"EXTENT"_s, mExtent.toString() );
192 outputs.insert( u
"CRS_AUTHID"_s, mCrs.authid() );
193 outputs.insert( u
"WIDTH_IN_PIXELS"_s, mLayerWidth );
194 outputs.insert( u
"HEIGHT_IN_PIXELS"_s, mLayerHeight );
195 outputs.insert( u
"TOTAL_PIXEL_COUNT"_s, layerSize );
196 outputs.insert( u
"OUTPUT"_s, outputFile );
205QString QgsCellStatisticsAlgorithm::displayName()
const
207 return QObject::tr(
"Cell statistics" );
210QString QgsCellStatisticsAlgorithm::name()
const
212 return u
"cellstatistics"_s;
215QStringList QgsCellStatisticsAlgorithm::tags()
const
217 return QObject::tr(
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split(
',' );
220QString QgsCellStatisticsAlgorithm::shortHelpString()
const
223 "The Cell statistics algorithm computes a value for each cell of the "
224 "output raster. At each cell location, "
225 "the output value is defined as a function of all overlaid cell values of the "
227 "The output raster's extent and resolution is defined by a reference "
228 "raster. The following functions can be applied on the input "
229 "raster cells per output raster cell location:\n"
235 " <li>Standard deviation</li>"
239 " <li>Minority (least frequent value)</li>"
240 " <li>Majority (most frequent value)</li>"
241 " <li>Range (max-min)</li>"
242 " <li>Variety (count of unique values)</li>"
244 "Input raster layers that do not match the cell size of the reference raster layer will be "
245 "resampled using nearest neighbor resampling. The output raster data type will be set to "
246 "the most complex data type present in the input datasets except when using the functions "
247 "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"
248 "<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"
249 "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n"
250 "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the "
251 "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n"
252 "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all "
253 "input cell values are equal."
257QString QgsCellStatisticsAlgorithm::shortDescription()
const
259 return QObject::tr(
"Generates a raster whose cell values are computed from overlaid cell values of the input rasters." );
262QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
const
264 return new QgsCellStatisticsAlgorithm();
267void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
269 QStringList statistics = QStringList();
271 << QObject::tr(
"Sum" )
272 << QObject::tr(
"Count" )
273 << QObject::tr(
"Mean" )
274 << QObject::tr(
"Median" )
275 << QObject::tr(
"Standard deviation" )
276 << QObject::tr(
"Variance" )
277 << QObject::tr(
"Minimum" )
278 << QObject::tr(
"Maximum" )
279 << QObject::tr(
"Minority" )
280 << QObject::tr(
"Majority" )
281 << QObject::tr(
"Range" )
282 << QObject::tr(
"Variety" );
291 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, u
"STATISTIC"_s, context ) );
294 if ( mMethod == QgsRasterAnalysisUtils::Mean
295 || mMethod == QgsRasterAnalysisUtils::StandardDeviation
296 || mMethod == QgsRasterAnalysisUtils::Variance
297 || ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) ) )
299 if (
static_cast<int>( mDataType ) < 6 )
302 else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety )
304 if (
static_cast<int>( mDataType ) > 5 )
312 QGS_MARK_ALGORITHM_SOURCE
314 mOutputRasterDataProvider->setEditable(
true );
316 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
323 std::unique_ptr<QgsRasterBlock> outputBlock;
324 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
326 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
327 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
331 for (
int band : i.bands )
335 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
336 inputBlocks.emplace_back( std::move( b ) );
340 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
341 for (
int row = 0; row < iterRows; row++ )
346 for (
int col = 0; col < iterCols; col++ )
349 bool noDataInStack =
false;
350 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
351 int cellValueStackSize = cellValues.size();
353 if ( noDataInStack && !mIgnoreNoData )
357 if ( mMethod == QgsRasterAnalysisUtils::Count )
358 outputBlock->setValue( row, col, cellValueStackSize );
361 outputBlock->setValue( row, col, mNoDataValue );
364 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
368 case QgsRasterAnalysisUtils::Sum:
369 result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
371 case QgsRasterAnalysisUtils::Count:
372 result = cellValueStackSize;
374 case QgsRasterAnalysisUtils::Mean:
375 result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
377 case QgsRasterAnalysisUtils::Median:
378 result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
380 case QgsRasterAnalysisUtils::StandardDeviation:
381 result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
383 case QgsRasterAnalysisUtils::Variance:
384 result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
386 case QgsRasterAnalysisUtils::Minimum:
387 result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
389 case QgsRasterAnalysisUtils::Maximum:
390 result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
392 case QgsRasterAnalysisUtils::Minority:
393 result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
395 case QgsRasterAnalysisUtils::Majority:
396 result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
398 case QgsRasterAnalysisUtils::Range:
399 result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
401 case QgsRasterAnalysisUtils::Variety:
402 result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
405 outputBlock->setValue( row, col, result );
410 outputBlock->setValue( row, col, mNoDataValue );
414 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
416 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
419 mOutputRasterDataProvider->setEditable(
false );
425QString QgsCellStatisticsPercentileAlgorithm::displayName()
const
427 return QObject::tr(
"Cell stack percentile" );
430QString QgsCellStatisticsPercentileAlgorithm::name()
const
432 return u
"cellstackpercentile"_s;
435QStringList QgsCellStatisticsPercentileAlgorithm::tags()
const
437 return QObject::tr(
"cell,pixel,statistic,percentile,quantile,quartile" ).split(
',' );
440QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
const
443 "This algorithm generates a raster containing the cell-wise percentile value of a stack of input rasters. "
444 "The percentile to return is determined by the percentile input value (ranges between 0 and 1). "
445 "At each cell location, the specified percentile is obtained using the respective value from "
446 "the stack of all overlaid and sorted cell values of the input rasters.\n\n"
447 "There are three methods for percentile calculation:"
449 " <li>Nearest rank</li>"
450 " <li>Inclusive linear interpolation (PERCENTILE.INC)</li>"
451 " <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>"
453 "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the "
454 "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation "
455 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
456 "The output raster's extent and resolution is defined by a reference "
457 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
458 "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. "
459 "The output raster data type will be set to the most complex data type present in the input datasets. "
463QString QgsCellStatisticsPercentileAlgorithm::shortDescription()
const
465 return QObject::tr(
"Generates a raster containing the cell-wise percentile value of a stack of input rasters." );
468QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
const
470 return new QgsCellStatisticsPercentileAlgorithm();
473void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
477 QObject::tr(
"Method" ),
478 QStringList() << QObject::tr(
"Nearest rank" ) << QObject::tr(
"Inclusive linear interpolation (PERCENTILE.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTILE.EXC)" ),
489 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentileMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
490 mPercentile = parameterAsDouble( parameters, u
"PERCENTILE"_s, context );
494 if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile &&
static_cast<int>( mDataType ) < 6 )
502 QGS_MARK_ALGORITHM_SOURCE
504 mOutputRasterDataProvider->setEditable(
true );
506 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
513 std::unique_ptr<QgsRasterBlock> outputBlock;
514 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
516 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
517 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
521 for (
int band : i.bands )
525 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
526 inputBlocks.emplace_back( std::move( b ) );
530 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
531 for (
int row = 0; row < iterRows; row++ )
536 for (
int col = 0; col < iterCols; col++ )
539 bool noDataInStack =
false;
540 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
541 int cellValueStackSize = cellValues.size();
543 if ( noDataInStack && !mIgnoreNoData )
545 outputBlock->setValue( row, col, mNoDataValue );
547 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
551 case QgsRasterAnalysisUtils::NearestRankPercentile:
552 result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
554 case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
555 result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
557 case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
558 result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
561 outputBlock->setValue( row, col, result );
566 outputBlock->setValue( row, col, mNoDataValue );
570 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
572 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
575 mOutputRasterDataProvider->setEditable(
false );
581QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
const
583 return QObject::tr(
"Cell stack percent rank from value" );
586QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
const
588 return u
"cellstackpercentrankfromvalue"_s;
591QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
const
593 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value" ).split(
',' );
596QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
const
599 "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"
600 "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. "
601 "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
602 "There are two methods for percentile calculation:"
604 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
605 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
607 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
608 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
609 "The output raster's extent and resolution is defined by a reference "
610 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
611 "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. "
612 "The output raster data type will always be Float32."
616QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortDescription()
const
618 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." );
621QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
const
623 return new QgsCellStatisticsPercentRankFromValueAlgorithm();
626void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
629 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 )
637 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
638 mValue = parameterAsDouble( parameters, u
"VALUE"_s, context );
645void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
647 QGS_MARK_ALGORITHM_SOURCE
649 mOutputRasterDataProvider->setEditable(
true );
651 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
658 std::unique_ptr<QgsRasterBlock> outputBlock;
659 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
661 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
662 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
666 for (
int band : i.bands )
670 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
671 inputBlocks.emplace_back( std::move( b ) );
675 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
676 for (
int row = 0; row < iterRows; row++ )
681 for (
int col = 0; col < iterCols; col++ )
684 bool noDataInStack =
false;
685 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
686 int cellValueStackSize = cellValues.size();
688 if ( noDataInStack && !mIgnoreNoData )
690 outputBlock->setValue( row, col, mNoDataValue );
692 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
696 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
697 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
699 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
700 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
703 outputBlock->setValue( row, col, result );
708 outputBlock->setValue( row, col, mNoDataValue );
712 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
714 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
717 mOutputRasterDataProvider->setEditable(
false );
724QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
const
726 return QObject::tr(
"Cell stack percentrank from raster layer" );
729QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
const
731 return u
"cellstackpercentrankfromrasterlayer"_s;
734QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
const
736 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split(
',' );
739QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
const
742 "This algorithm generates a raster containing the cell-wise percent rank value of a stack of input rasters "
743 "based on an input value raster.\n\n"
744 "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. "
745 "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"
746 "There are two methods for percentile calculation:"
748 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
749 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
751 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
752 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
753 "The output raster's extent and resolution is defined by a reference "
754 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
755 "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. "
756 "The output raster data type will always be Float32."
760QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortDescription()
const
762 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." );
765QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
const
767 return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
770void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
773 addParameter(
new QgsProcessingParameterBand( u
"VALUE_RASTER_BAND"_s, QObject::tr(
"Value raster band" ), 1, u
"VALUE_LAYER"_s ) );
775 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 )
782 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
784 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, u
"INPUT_VALUE_RASTER"_s, context );
785 if ( !inputValueRaster )
790 mValueRasterBand = parameterAsInt( parameters, u
"VALUE_RASTER_BAND"_s, context );
797void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
799 QGS_MARK_ALGORITHM_SOURCE
801 mOutputRasterDataProvider->setEditable(
true );
803 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
810 std::unique_ptr<QgsRasterBlock> outputBlock;
811 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
813 std::unique_ptr<QgsRasterBlock> valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
815 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
816 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
820 for (
int band : i.bands )
824 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
825 inputBlocks.emplace_back( std::move( b ) );
829 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
830 for (
int row = 0; row < iterRows; row++ )
835 for (
int col = 0; col < iterCols; col++ )
837 bool percentRankValueIsNoData =
false;
838 double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
841 bool noDataInStack =
false;
842 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
843 int cellValueStackSize = cellValues.size();
845 if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
847 outputBlock->setValue( row, col, mNoDataValue );
849 else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
853 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
854 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
856 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
857 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
860 outputBlock->setValue( row, col, result );
865 outputBlock->setValue( row, col, mNoDataValue );
869 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
871 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
874 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 Q_INVOKABLE 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...