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 QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
146 const QString optionsString = parameterAsString( parameters, u
"CREATE_OPTIONS"_s, context );
147 if ( !optionsString.isEmpty() )
148 creationOptions = optionsString;
150 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
151 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
153 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
154 writer->setOutputProviderKey( u
"gdal"_s );
155 if ( !creationOptions.isEmpty() )
157 writer->setCreationOptions( creationOptions.split(
'|' ) );
159 writer->setOutputFormat( outputFormat );
160 mOutputRasterDataProvider.reset( writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
161 if ( !mOutputRasterDataProvider )
163 if ( !mOutputRasterDataProvider->isValid() )
166 mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
169 const bool hasReportsDuringClose = mOutputRasterDataProvider->hasReportsDuringClose();
170 mMaxProgressDuringBlockWriting = hasReportsDuringClose ? 50.0 : 100.0;
173 processRasterStack( feedback );
175 if ( feedback && hasReportsDuringClose )
178 if ( !mOutputRasterDataProvider->closeWithProgress( scaledFeedback.get() ) )
186 mOutputRasterDataProvider.reset();
189 outputs.insert( u
"EXTENT"_s, mExtent.toString() );
190 outputs.insert( u
"CRS_AUTHID"_s, mCrs.authid() );
191 outputs.insert( u
"WIDTH_IN_PIXELS"_s, mLayerWidth );
192 outputs.insert( u
"HEIGHT_IN_PIXELS"_s, mLayerHeight );
193 outputs.insert( u
"TOTAL_PIXEL_COUNT"_s, layerSize );
194 outputs.insert( u
"OUTPUT"_s, outputFile );
203QString QgsCellStatisticsAlgorithm::displayName()
const
205 return QObject::tr(
"Cell statistics" );
208QString QgsCellStatisticsAlgorithm::name()
const
210 return u
"cellstatistics"_s;
213QStringList QgsCellStatisticsAlgorithm::tags()
const
215 return QObject::tr(
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split(
',' );
218QString QgsCellStatisticsAlgorithm::shortHelpString()
const
221 "The Cell statistics algorithm computes a value for each cell of the "
222 "output raster. At each cell location, "
223 "the output value is defined as a function of all overlaid cell values of the "
225 "The output raster's extent and resolution is defined by a reference "
226 "raster. The following functions can be applied on the input "
227 "raster cells per output raster cell location:\n"
233 " <li>Standard deviation</li>"
237 " <li>Minority (least frequent value)</li>"
238 " <li>Majority (most frequent value)</li>"
239 " <li>Range (max-min)</li>"
240 " <li>Variety (count of unique values)</li>"
242 "Input raster layers that do not match the cell size of the reference raster layer will be "
243 "resampled using nearest neighbor resampling. The output raster data type will be set to "
244 "the most complex data type present in the input datasets except when using the functions "
245 "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"
246 "<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"
247 "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n"
248 "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the "
249 "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n"
250 "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all "
251 "input cell values are equal."
255QString QgsCellStatisticsAlgorithm::shortDescription()
const
257 return QObject::tr(
"Generates a raster whose cell values are computed from overlaid cell values of the input rasters." );
260QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
const
262 return new QgsCellStatisticsAlgorithm();
265void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
267 QStringList statistics = QStringList();
269 << QObject::tr(
"Sum" )
270 << QObject::tr(
"Count" )
271 << QObject::tr(
"Mean" )
272 << QObject::tr(
"Median" )
273 << QObject::tr(
"Standard deviation" )
274 << QObject::tr(
"Variance" )
275 << QObject::tr(
"Minimum" )
276 << QObject::tr(
"Maximum" )
277 << QObject::tr(
"Minority" )
278 << QObject::tr(
"Majority" )
279 << QObject::tr(
"Range" )
280 << QObject::tr(
"Variety" );
289 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, u
"STATISTIC"_s, context ) );
292 if ( mMethod == QgsRasterAnalysisUtils::Mean
293 || mMethod == QgsRasterAnalysisUtils::StandardDeviation
294 || mMethod == QgsRasterAnalysisUtils::Variance
295 || ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) ) )
297 if (
static_cast<int>( mDataType ) < 6 )
300 else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety )
302 if (
static_cast<int>( mDataType ) > 5 )
310 QGS_MARK_ALGORITHM_SOURCE
312 mOutputRasterDataProvider->setEditable(
true );
314 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
321 std::unique_ptr<QgsRasterBlock> outputBlock;
322 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
324 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
325 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
329 for (
int band : i.bands )
333 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
334 inputBlocks.emplace_back( std::move( b ) );
338 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
339 for (
int row = 0; row < iterRows; row++ )
344 for (
int col = 0; col < iterCols; col++ )
347 bool noDataInStack =
false;
348 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
349 int cellValueStackSize = cellValues.size();
351 if ( noDataInStack && !mIgnoreNoData )
355 if ( mMethod == QgsRasterAnalysisUtils::Count )
356 outputBlock->setValue( row, col, cellValueStackSize );
359 outputBlock->setValue( row, col, mNoDataValue );
362 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
366 case QgsRasterAnalysisUtils::Sum:
367 result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
369 case QgsRasterAnalysisUtils::Count:
370 result = cellValueStackSize;
372 case QgsRasterAnalysisUtils::Mean:
373 result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
375 case QgsRasterAnalysisUtils::Median:
376 result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
378 case QgsRasterAnalysisUtils::StandardDeviation:
379 result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
381 case QgsRasterAnalysisUtils::Variance:
382 result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
384 case QgsRasterAnalysisUtils::Minimum:
385 result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
387 case QgsRasterAnalysisUtils::Maximum:
388 result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
390 case QgsRasterAnalysisUtils::Minority:
391 result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
393 case QgsRasterAnalysisUtils::Majority:
394 result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
396 case QgsRasterAnalysisUtils::Range:
397 result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
399 case QgsRasterAnalysisUtils::Variety:
400 result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
403 outputBlock->setValue( row, col, result );
408 outputBlock->setValue( row, col, mNoDataValue );
412 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
414 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
417 mOutputRasterDataProvider->setEditable(
false );
423QString QgsCellStatisticsPercentileAlgorithm::displayName()
const
425 return QObject::tr(
"Cell stack percentile" );
428QString QgsCellStatisticsPercentileAlgorithm::name()
const
430 return u
"cellstackpercentile"_s;
433QStringList QgsCellStatisticsPercentileAlgorithm::tags()
const
435 return QObject::tr(
"cell,pixel,statistic,percentile,quantile,quartile" ).split(
',' );
438QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
const
441 "This algorithm generates a raster containing the cell-wise percentile value of a stack of input rasters. "
442 "The percentile to return is determined by the percentile input value (ranges between 0 and 1). "
443 "At each cell location, the specified percentile is obtained using the respective value from "
444 "the stack of all overlaid and sorted cell values of the input rasters.\n\n"
445 "There are three methods for percentile calculation:"
447 " <li>Nearest rank</li>"
448 " <li>Inclusive linear interpolation (PERCENTILE.INC)</li>"
449 " <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>"
451 "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the "
452 "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation "
453 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
454 "The output raster's extent and resolution is defined by a reference "
455 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
456 "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. "
457 "The output raster data type will be set to the most complex data type present in the input datasets. "
461QString QgsCellStatisticsPercentileAlgorithm::shortDescription()
const
463 return QObject::tr(
"Generates a raster containing the cell-wise percentile value of a stack of input rasters." );
466QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
const
468 return new QgsCellStatisticsPercentileAlgorithm();
471void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
475 QObject::tr(
"Method" ),
476 QStringList() << QObject::tr(
"Nearest rank" ) << QObject::tr(
"Inclusive linear interpolation (PERCENTILE.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTILE.EXC)" ),
487 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentileMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
488 mPercentile = parameterAsDouble( parameters, u
"PERCENTILE"_s, context );
492 if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile &&
static_cast<int>( mDataType ) < 6 )
500 QGS_MARK_ALGORITHM_SOURCE
502 mOutputRasterDataProvider->setEditable(
true );
504 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
511 std::unique_ptr<QgsRasterBlock> outputBlock;
512 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
514 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
515 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
519 for (
int band : i.bands )
523 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
524 inputBlocks.emplace_back( std::move( b ) );
528 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
529 for (
int row = 0; row < iterRows; row++ )
534 for (
int col = 0; col < iterCols; col++ )
537 bool noDataInStack =
false;
538 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
539 int cellValueStackSize = cellValues.size();
541 if ( noDataInStack && !mIgnoreNoData )
543 outputBlock->setValue( row, col, mNoDataValue );
545 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
549 case QgsRasterAnalysisUtils::NearestRankPercentile:
550 result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
552 case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
553 result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
555 case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
556 result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
559 outputBlock->setValue( row, col, result );
564 outputBlock->setValue( row, col, mNoDataValue );
568 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
570 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
573 mOutputRasterDataProvider->setEditable(
false );
579QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
const
581 return QObject::tr(
"Cell stack percent rank from value" );
584QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
const
586 return u
"cellstackpercentrankfromvalue"_s;
589QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
const
591 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value" ).split(
',' );
594QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
const
597 "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"
598 "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. "
599 "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
600 "There are two methods for percentile calculation:"
602 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
603 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
605 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
606 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
607 "The output raster's extent and resolution is defined by a reference "
608 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
609 "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. "
610 "The output raster data type will always be Float32."
614QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortDescription()
const
616 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." );
619QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
const
621 return new QgsCellStatisticsPercentRankFromValueAlgorithm();
624void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
627 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 )
635 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
636 mValue = parameterAsDouble( parameters, u
"VALUE"_s, context );
643void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
645 QGS_MARK_ALGORITHM_SOURCE
647 mOutputRasterDataProvider->setEditable(
true );
649 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
656 std::unique_ptr<QgsRasterBlock> outputBlock;
657 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
659 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
660 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
664 for (
int band : i.bands )
668 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
669 inputBlocks.emplace_back( std::move( b ) );
673 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
674 for (
int row = 0; row < iterRows; row++ )
679 for (
int col = 0; col < iterCols; col++ )
682 bool noDataInStack =
false;
683 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
684 int cellValueStackSize = cellValues.size();
686 if ( noDataInStack && !mIgnoreNoData )
688 outputBlock->setValue( row, col, mNoDataValue );
690 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
694 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
695 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
697 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
698 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
701 outputBlock->setValue( row, col, result );
706 outputBlock->setValue( row, col, mNoDataValue );
710 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
712 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
715 mOutputRasterDataProvider->setEditable(
false );
722QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
const
724 return QObject::tr(
"Cell stack percentrank from raster layer" );
727QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
const
729 return u
"cellstackpercentrankfromrasterlayer"_s;
732QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
const
734 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split(
',' );
737QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
const
740 "This algorithm generates a raster containing the cell-wise percent rank value of a stack of input rasters "
741 "based on an input value raster.\n\n"
742 "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. "
743 "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"
744 "There are two methods for percentile calculation:"
746 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
747 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
749 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
750 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
751 "The output raster's extent and resolution is defined by a reference "
752 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
753 "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. "
754 "The output raster data type will always be Float32."
758QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortDescription()
const
760 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." );
763QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
const
765 return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
768void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
771 addParameter(
new QgsProcessingParameterBand( u
"VALUE_RASTER_BAND"_s, QObject::tr(
"Value raster band" ), 1, u
"VALUE_LAYER"_s ) );
773 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 )
780 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, u
"METHOD"_s, context ) );
782 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, u
"INPUT_VALUE_RASTER"_s, context );
783 if ( !inputValueRaster )
788 mValueRasterBand = parameterAsInt( parameters, u
"VALUE_RASTER_BAND"_s, context );
795void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
797 QGS_MARK_ALGORITHM_SOURCE
799 mOutputRasterDataProvider->setEditable(
true );
801 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
808 std::unique_ptr<QgsRasterBlock> outputBlock;
809 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
811 std::unique_ptr<QgsRasterBlock> valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
813 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
814 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
818 for (
int band : i.bands )
822 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
823 inputBlocks.emplace_back( std::move( b ) );
827 feedback->
setProgress( mMaxProgressDuringBlockWriting * outputIter.progress( 1 ) );
828 for (
int row = 0; row < iterRows; row++ )
833 for (
int col = 0; col < iterCols; col++ )
835 bool percentRankValueIsNoData =
false;
836 double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
839 bool noDataInStack =
false;
840 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
841 int cellValueStackSize = cellValues.size();
843 if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
845 outputBlock->setValue( row, col, mNoDataValue );
847 else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
851 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
852 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
854 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
855 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
858 outputBlock->setValue( row, col, result );
863 outputBlock->setValue( row, col, mNoDataValue );
867 if ( !mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
869 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( mOutputRasterDataProvider->error().summary() ) );
872 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...