26QString QgsCellStatisticsAlgorithmBase::group()
const
28 return QObject::tr(
"Raster analysis" );
31QString QgsCellStatisticsAlgorithmBase::groupId()
const
33 return QStringLiteral(
"rasteranalysis" );
36void QgsCellStatisticsAlgorithmBase::initAlgorithm(
const QVariantMap & )
40 addSpecificAlgorithmParams();
46 std::unique_ptr<QgsProcessingParameterNumber> output_nodata_parameter = std::make_unique<QgsProcessingParameterNumber>( QStringLiteral(
"OUTPUT_NODATA_VALUE" ), QObject::tr(
"Output NoData value" ),
Qgis::ProcessingNumberParameterType::Double, -9999,
false );
48 addParameter( output_nodata_parameter.release() );
50 std::unique_ptr<QgsProcessingParameterString> createOptsParam = std::make_unique<QgsProcessingParameterString>( QStringLiteral(
"CREATE_OPTIONS" ), QObject::tr(
"Creation options" ), QVariant(),
false,
true );
51 createOptsParam->setMetadata( QVariantMap( { { QStringLiteral(
"widget_wrapper" ), QVariantMap( { { QStringLiteral(
"widget_type" ), QStringLiteral(
"rasteroptions" ) } } ) } } ) );
53 addParameter( createOptsParam.release() );
66 QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, QStringLiteral(
"REFERENCE_LAYER" ), context );
67 if ( !referenceLayer )
70 mIgnoreNoData = parameterAsBool( parameters, QStringLiteral(
"IGNORE_NODATA" ), context );
71 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"OUTPUT_NODATA_VALUE" ), context );
72 mCrs = referenceLayer->
crs();
75 mLayerWidth = referenceLayer->
width();
76 mLayerHeight = referenceLayer->
height();
77 mExtent = referenceLayer->
extent();
79 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, QStringLiteral(
"INPUT" ), context );
80 QList<QgsRasterLayer *> rasterLayers;
81 rasterLayers.reserve( layers.count() );
90 QgsRasterAnalysisUtils::RasterLogicInput input;
94 input.interface = input.sourceDataProvider.get();
96 if ( layer->
crs() != mCrs )
98 input.projector = std::make_unique<QgsRasterProjector>();
99 input.projector->setInput( input.sourceDataProvider.get() );
101 input.interface = input.projector.get();
103 mInputs.emplace_back( std::move( input ) );
110 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
112 for (
int band : i.bands )
115 if (
static_cast<int>( mDataType ) <
static_cast<int>( inputDataType ) )
116 mDataType = inputDataType;
120 prepareSpecificAlgorithmParameters( parameters, context, feedback );
128 const QString createOptions = parameterAsString( parameters, QStringLiteral(
"CREATE_OPTIONS" ), context ).trimmed();
129 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
130 QFileInfo fi( outputFile );
133 std::unique_ptr<QgsRasterFileWriter> writer = std::make_unique<QgsRasterFileWriter>( outputFile );
134 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
135 if ( !createOptions.isEmpty() )
137 writer->setCreateOptions( createOptions.split(
'|' ) );
139 writer->setOutputFormat( outputFormat );
140 mOutputRasterDataProvider.reset( writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
141 if ( !mOutputRasterDataProvider )
143 if ( !mOutputRasterDataProvider->isValid() )
146 mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
150 processRasterStack( feedback );
152 mOutputRasterDataProvider.reset();
155 outputs.insert( QStringLiteral(
"EXTENT" ), mExtent.toString() );
156 outputs.insert( QStringLiteral(
"CRS_AUTHID" ), mCrs.authid() );
157 outputs.insert( QStringLiteral(
"WIDTH_IN_PIXELS" ), mLayerWidth );
158 outputs.insert( QStringLiteral(
"HEIGHT_IN_PIXELS" ), mLayerHeight );
159 outputs.insert( QStringLiteral(
"TOTAL_PIXEL_COUNT" ), layerSize );
160 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
169QString QgsCellStatisticsAlgorithm::displayName()
const
171 return QObject::tr(
"Cell statistics" );
174QString QgsCellStatisticsAlgorithm::name()
const
176 return QStringLiteral(
"cellstatistics" );
179QStringList QgsCellStatisticsAlgorithm::tags()
const
181 return QObject::tr(
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split(
',' );
184QString QgsCellStatisticsAlgorithm::shortHelpString()
const
186 return QObject::tr(
"The Cell statistics algorithm computes a value for each cell of the "
187 "output raster. At each cell location, "
188 "the output value is defined as a function of all overlaid cell values of the "
190 "The output raster's extent and resolution is defined by a reference "
191 "raster. The following functions can be applied on the input "
192 "raster cells per output raster cell location:\n"
198 " <li>Standard deviation</li>"
202 " <li>Minority (least frequent value)</li>"
203 " <li>Majority (most frequent value)</li>"
204 " <li>Range (max-min)</li>"
205 " <li>Variety (count of unique values)</li>"
207 "Input raster layers that do not match the cell size of the reference raster layer will be "
208 "resampled using nearest neighbor resampling. The output raster data type will be set to "
209 "the most complex data type present in the input datasets except when using the functions "
210 "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"
211 "<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"
212 "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n"
213 "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the "
214 "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n"
215 "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all "
216 "input cell values are equal." );
219QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
const
221 return new QgsCellStatisticsAlgorithm();
224void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
226 QStringList statistics = QStringList();
227 statistics << QObject::tr(
"Sum" )
228 << QObject::tr(
"Count" )
229 << QObject::tr(
"Mean" )
230 << QObject::tr(
"Median" )
231 << QObject::tr(
"Standard deviation" )
232 << QObject::tr(
"Variance" )
233 << QObject::tr(
"Minimum" )
234 << QObject::tr(
"Maximum" )
235 << QObject::tr(
"Minority" )
236 << QObject::tr(
"Majority" )
237 << QObject::tr(
"Range" )
238 << QObject::tr(
"Variety" );
240 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"STATISTIC" ), QObject::tr(
"Statistic" ), statistics,
false, 0,
false ) );
247 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, QStringLiteral(
"STATISTIC" ), context ) );
251 mMethod == QgsRasterAnalysisUtils::Mean || mMethod == QgsRasterAnalysisUtils::StandardDeviation || mMethod == QgsRasterAnalysisUtils::Variance || ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) )
254 if (
static_cast<int>( mDataType ) < 6 )
257 else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety )
259 if (
static_cast<int>( mDataType ) > 5 )
269 int nbBlocksWidth =
static_cast<int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
270 int nbBlocksHeight =
static_cast<int>( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
271 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
272 mOutputRasterDataProvider->setEditable(
true );
274 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
281 std::unique_ptr<QgsRasterBlock> outputBlock;
282 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
284 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
285 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
289 for (
int band : i.bands )
293 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
294 inputBlocks.emplace_back( std::move( b ) );
298 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
299 for (
int row = 0; row < iterRows; row++ )
304 for (
int col = 0; col < iterCols; col++ )
307 bool noDataInStack =
false;
308 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
309 int cellValueStackSize = cellValues.size();
311 if ( noDataInStack && !mIgnoreNoData )
315 if ( mMethod == QgsRasterAnalysisUtils::Count )
316 outputBlock->setValue( row, col, cellValueStackSize );
319 outputBlock->setValue( row, col, mNoDataValue );
322 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
326 case QgsRasterAnalysisUtils::Sum:
327 result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
329 case QgsRasterAnalysisUtils::Count:
330 result = cellValueStackSize;
332 case QgsRasterAnalysisUtils::Mean:
333 result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
335 case QgsRasterAnalysisUtils::Median:
336 result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
338 case QgsRasterAnalysisUtils::StandardDeviation:
339 result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
341 case QgsRasterAnalysisUtils::Variance:
342 result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
344 case QgsRasterAnalysisUtils::Minimum:
345 result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
347 case QgsRasterAnalysisUtils::Maximum:
348 result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
350 case QgsRasterAnalysisUtils::Minority:
351 result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
353 case QgsRasterAnalysisUtils::Majority:
354 result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
356 case QgsRasterAnalysisUtils::Range:
357 result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
359 case QgsRasterAnalysisUtils::Variety:
360 result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
363 outputBlock->setValue( row, col, result );
368 outputBlock->setValue( row, col, mNoDataValue );
372 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
374 mOutputRasterDataProvider->setEditable(
false );
380QString QgsCellStatisticsPercentileAlgorithm::displayName()
const
382 return QObject::tr(
"Cell stack percentile" );
385QString QgsCellStatisticsPercentileAlgorithm::name()
const
387 return QStringLiteral(
"cellstackpercentile" );
390QStringList QgsCellStatisticsPercentileAlgorithm::tags()
const
392 return QObject::tr(
"cell,pixel,statistic,percentile,quantile,quartile" ).split(
',' );
395QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
const
397 return QObject::tr(
"The Cell stack percentile algorithm returns the cell-wise percentile value of a stack of rasters "
398 "and writes the results to an output raster. The percentile to return is determined by the percentile input value (ranges between 0 and 1). "
399 "At each cell location, the specified percentile is obtained using the respective value from "
400 "the stack of all overlaid and sorted cell values of the input rasters.\n\n"
401 "There are three methods for percentile calculation:"
403 " <li>Nearest rank</li>"
404 " <li>Inclusive linear interpolation (PERCENTILE.INC)</li>"
405 " <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>"
407 "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the "
408 "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation "
409 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
410 "The output raster's extent and resolution is defined by a reference "
411 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
412 "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. "
413 "The output raster data type will be set to the most complex data type present in the input datasets. " );
416QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
const
418 return new QgsCellStatisticsPercentileAlgorithm();
421void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
423 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 ) );
430 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentileMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
431 mPercentile = parameterAsDouble( parameters, QStringLiteral(
"PERCENTILE" ), context );
435 if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile &&
static_cast<int>( mDataType ) < 6 )
445 int nbBlocksWidth =
static_cast<int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
446 int nbBlocksHeight =
static_cast<int>( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
447 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
448 mOutputRasterDataProvider->setEditable(
true );
450 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
457 std::unique_ptr<QgsRasterBlock> outputBlock;
458 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
460 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
461 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
465 for (
int band : i.bands )
469 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
470 inputBlocks.emplace_back( std::move( b ) );
474 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
475 for (
int row = 0; row < iterRows; row++ )
480 for (
int col = 0; col < iterCols; col++ )
483 bool noDataInStack =
false;
484 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
485 int cellValueStackSize = cellValues.size();
487 if ( noDataInStack && !mIgnoreNoData )
489 outputBlock->setValue( row, col, mNoDataValue );
491 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
495 case QgsRasterAnalysisUtils::NearestRankPercentile:
496 result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
498 case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
499 result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
501 case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
502 result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
505 outputBlock->setValue( row, col, result );
510 outputBlock->setValue( row, col, mNoDataValue );
514 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
516 mOutputRasterDataProvider->setEditable(
false );
522QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
const
524 return QObject::tr(
"Cell stack percent rank from value" );
527QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
const
529 return QStringLiteral(
"cellstackpercentrankfromvalue" );
532QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
const
534 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value" ).split(
',' );
537QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
const
539 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 "
540 "and writes them to an output raster.\n\n"
541 "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. "
542 "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
543 "There are two methods for percentile calculation:"
545 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
546 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
548 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
549 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
550 "The output raster's extent and resolution is defined by a reference "
551 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
552 "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. "
553 "The output raster data type will always be Float32." );
556QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
const
558 return new QgsCellStatisticsPercentRankFromValueAlgorithm();
561void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
563 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 ) );
570 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
571 mValue = parameterAsDouble( parameters, QStringLiteral(
"VALUE" ), context );
578void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
582 int nbBlocksWidth =
static_cast<int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
583 int nbBlocksHeight =
static_cast<int>( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
584 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
585 mOutputRasterDataProvider->setEditable(
true );
587 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
594 std::unique_ptr<QgsRasterBlock> outputBlock;
595 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
597 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
598 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
602 for (
int band : i.bands )
606 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
607 inputBlocks.emplace_back( std::move( b ) );
611 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
612 for (
int row = 0; row < iterRows; row++ )
617 for (
int col = 0; col < iterCols; col++ )
620 bool noDataInStack =
false;
621 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
622 int cellValueStackSize = cellValues.size();
624 if ( noDataInStack && !mIgnoreNoData )
626 outputBlock->setValue( row, col, mNoDataValue );
628 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
632 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
633 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
635 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
636 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
639 outputBlock->setValue( row, col, result );
644 outputBlock->setValue( row, col, mNoDataValue );
648 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
650 mOutputRasterDataProvider->setEditable(
false );
657QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
const
659 return QObject::tr(
"Cell stack percentrank from raster layer" );
662QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
const
664 return QStringLiteral(
"cellstackpercentrankfromrasterlayer" );
667QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
const
669 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split(
',' );
672QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
const
674 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 "
675 "and writes them to an output raster.\n\n"
676 "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. "
677 "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"
678 "There are two methods for percentile calculation:"
680 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
681 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
683 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
684 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
685 "The output raster's extent and resolution is defined by a reference "
686 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
687 "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. "
688 "The output raster data type will always be Float32." );
691QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
const
693 return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
696void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
699 addParameter(
new QgsProcessingParameterBand( QStringLiteral(
"VALUE_RASTER_BAND" ), QObject::tr(
"Value raster band" ), 1, QStringLiteral(
"VALUE_LAYER" ) ) );
700 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 ) );
706 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
708 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_VALUE_RASTER" ), context );
709 if ( !inputValueRaster )
714 mValueRasterBand = parameterAsInt( parameters, QStringLiteral(
"VALUE_RASTER_BAND" ), context );
721void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
725 int nbBlocksWidth =
static_cast<int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
726 int nbBlocksHeight =
static_cast<int>( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
727 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
728 mOutputRasterDataProvider->setEditable(
true );
730 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
737 std::unique_ptr<QgsRasterBlock> outputBlock;
738 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
740 std::unique_ptr<QgsRasterBlock> valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
742 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
743 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
747 for (
int band : i.bands )
751 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
752 inputBlocks.emplace_back( std::move( b ) );
756 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
757 for (
int row = 0; row < iterRows; row++ )
762 for (
int col = 0; col < iterCols; col++ )
764 bool percentRankValueIsNoData =
false;
765 double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
768 bool noDataInStack =
false;
769 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
770 int cellValueStackSize = cellValues.size();
772 if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
774 outputBlock->setValue( row, col, mNoDataValue );
776 else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
780 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
781 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
783 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
784 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
787 outputBlock->setValue( row, col, result );
792 outputBlock->setValue( row, col, mNoDataValue );
796 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
798 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)
@ 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.
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.
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...