26QString QgsCellStatisticsAlgorithmBase::group()
const
28 return QObject::tr(
"Raster analysis" );
31QString QgsCellStatisticsAlgorithmBase::groupId()
const
33 return QStringLiteral(
"rasteranalysis" );
36void QgsCellStatisticsAlgorithmBase::initAlgorithm(
const QVariantMap & )
41 addSpecificAlgorithmParams();
47 std::unique_ptr< QgsProcessingParameterNumber > output_nodata_parameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral(
"OUTPUT_NODATA_VALUE" ), QObject::tr(
"Output NoData value" ),
Qgis::ProcessingNumberParameterType::Double, -9999,
false );
49 addParameter( output_nodata_parameter.release() );
51 std::unique_ptr< QgsProcessingParameterString > createOptsParam = std::make_unique< QgsProcessingParameterString >( QStringLiteral(
"CREATE_OPTIONS" ), QObject::tr(
"Creation options" ), QVariant(),
false,
true );
52 createOptsParam->setMetadata( QVariantMap( {{QStringLiteral(
"widget_wrapper" ), QVariantMap( {{QStringLiteral(
"widget_type" ), QStringLiteral(
"rasteroptions" ) }} ) }} ) );
54 addParameter( createOptsParam.release() );
57 QObject::tr(
"Output layer" ) ) );
68 QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, QStringLiteral(
"REFERENCE_LAYER" ), context );
69 if ( !referenceLayer )
72 mIgnoreNoData = parameterAsBool( parameters, QStringLiteral(
"IGNORE_NODATA" ), context );
73 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"OUTPUT_NODATA_VALUE" ), context );
74 mCrs = referenceLayer->
crs();
77 mLayerWidth = referenceLayer->
width();
78 mLayerHeight = referenceLayer->
height();
79 mExtent = referenceLayer->
extent();
81 const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral(
"INPUT" ), context );
82 QList< QgsRasterLayer * > rasterLayers;
83 rasterLayers.reserve( layers.count() );
92 QgsRasterAnalysisUtils::RasterLogicInput input;
96 input.interface = input.sourceDataProvider.get();
98 if ( layer->
crs() != mCrs )
100 input.projector = std::make_unique< QgsRasterProjector >();
101 input.projector->setInput( input.sourceDataProvider.get() );
103 input.interface = input.projector.get();
105 mInputs.emplace_back( std::move( input ) );
112 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
114 for (
int band : i.bands )
117 if (
static_cast<int>( mDataType ) <
static_cast<int>( inputDataType ) )
118 mDataType = inputDataType;
122 prepareSpecificAlgorithmParameters( parameters, context, feedback );
130 const QString createOptions = parameterAsString( parameters, QStringLiteral(
"CREATE_OPTIONS" ), context ).trimmed();
131 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
132 QFileInfo fi( outputFile );
135 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
136 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
137 if ( !createOptions.isEmpty() )
139 writer->setCreateOptions( createOptions.split(
'|' ) );
141 writer->setOutputFormat( outputFormat );
142 mOutputRasterDataProvider.reset( writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
143 if ( !mOutputRasterDataProvider )
145 if ( !mOutputRasterDataProvider->isValid() )
148 mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
152 processRasterStack( feedback );
154 mOutputRasterDataProvider.reset();
157 outputs.insert( QStringLiteral(
"EXTENT" ), mExtent.toString() );
158 outputs.insert( QStringLiteral(
"CRS_AUTHID" ), mCrs.authid() );
159 outputs.insert( QStringLiteral(
"WIDTH_IN_PIXELS" ), mLayerWidth );
160 outputs.insert( QStringLiteral(
"HEIGHT_IN_PIXELS" ), mLayerHeight );
161 outputs.insert( QStringLiteral(
"TOTAL_PIXEL_COUNT" ), layerSize );
162 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
171QString QgsCellStatisticsAlgorithm::displayName()
const
173 return QObject::tr(
"Cell statistics" );
176QString QgsCellStatisticsAlgorithm::name()
const
178 return QStringLiteral(
"cellstatistics" );
181QStringList QgsCellStatisticsAlgorithm::tags()
const
183 return QObject::tr(
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split(
',' );
186QString QgsCellStatisticsAlgorithm::shortHelpString()
const
188 return QObject::tr(
"The Cell statistics algorithm computes a value for each cell of the "
189 "output raster. At each cell location, "
190 "the output value is defined as a function of all overlaid cell values of the "
192 "The output raster's extent and resolution is defined by a reference "
193 "raster. The following functions can be applied on the input "
194 "raster cells per output raster cell location:\n"
200 " <li>Standard deviation</li>"
204 " <li>Minority (least frequent value)</li>"
205 " <li>Majority (most frequent value)</li>"
206 " <li>Range (max-min)</li>"
207 " <li>Variety (count of unique values)</li>"
209 "Input raster layers that do not match the cell size of the reference raster layer will be "
210 "resampled using nearest neighbor resampling. The output raster data type will be set to "
211 "the most complex data type present in the input datasets except when using the functions "
212 "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"
213 "<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"
214 "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n"
215 "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the "
216 "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n"
217 "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all "
218 "input cell values are equal." );
221QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
const
223 return new QgsCellStatisticsAlgorithm();
226void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
228 QStringList statistics = QStringList();
229 statistics << QObject::tr(
"Sum" )
230 << QObject::tr(
"Count" )
231 << QObject::tr(
"Mean" )
232 << QObject::tr(
"Median" )
233 << QObject::tr(
"Standard deviation" )
234 << QObject::tr(
"Variance" )
235 << QObject::tr(
"Minimum" )
236 << QObject::tr(
"Maximum" )
237 << QObject::tr(
"Minority" )
238 << QObject::tr(
"Majority" )
239 << QObject::tr(
"Range" )
240 << QObject::tr(
"Variety" );
242 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"STATISTIC" ), QObject::tr(
"Statistic" ), statistics,
false, 0,
false ) );
249 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, QStringLiteral(
"STATISTIC" ), context ) );
253 mMethod == QgsRasterAnalysisUtils::Mean ||
254 mMethod == QgsRasterAnalysisUtils::StandardDeviation ||
255 mMethod == QgsRasterAnalysisUtils::Variance ||
256 ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) )
259 if (
static_cast<int>( mDataType ) < 6 )
262 else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety )
264 if (
static_cast<int>( mDataType ) > 5 )
274 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
275 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
276 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
277 mOutputRasterDataProvider->setEditable(
true );
279 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
286 std::unique_ptr< QgsRasterBlock > outputBlock;
287 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
289 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
290 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
294 for (
int band : i.bands )
298 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
299 inputBlocks.emplace_back( std::move( b ) );
303 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
304 for (
int row = 0; row < iterRows; row++ )
309 for (
int col = 0; col < iterCols; col++ )
312 bool noDataInStack =
false;
313 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
314 int cellValueStackSize = cellValues.size();
316 if ( noDataInStack && !mIgnoreNoData )
320 if ( mMethod == QgsRasterAnalysisUtils::Count )
321 outputBlock->setValue( row, col, cellValueStackSize );
324 outputBlock->setValue( row, col, mNoDataValue );
327 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
331 case QgsRasterAnalysisUtils::Sum:
332 result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
334 case QgsRasterAnalysisUtils::Count:
335 result = cellValueStackSize;
337 case QgsRasterAnalysisUtils::Mean:
338 result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
340 case QgsRasterAnalysisUtils::Median:
341 result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
343 case QgsRasterAnalysisUtils::StandardDeviation:
344 result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
346 case QgsRasterAnalysisUtils::Variance:
347 result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
349 case QgsRasterAnalysisUtils::Minimum:
350 result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
352 case QgsRasterAnalysisUtils::Maximum:
353 result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
355 case QgsRasterAnalysisUtils::Minority:
356 result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
358 case QgsRasterAnalysisUtils::Majority:
359 result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
361 case QgsRasterAnalysisUtils::Range:
362 result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
364 case QgsRasterAnalysisUtils::Variety:
365 result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
368 outputBlock->setValue( row, col, result );
373 outputBlock->setValue( row, col, mNoDataValue );
377 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
379 mOutputRasterDataProvider->setEditable(
false );
385QString QgsCellStatisticsPercentileAlgorithm::displayName()
const
387 return QObject::tr(
"Cell stack percentile" );
390QString QgsCellStatisticsPercentileAlgorithm::name()
const
392 return QStringLiteral(
"cellstackpercentile" );
395QStringList QgsCellStatisticsPercentileAlgorithm::tags()
const
397 return QObject::tr(
"cell,pixel,statistic,percentile,quantile,quartile" ).split(
',' );
400QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
const
402 return QObject::tr(
"The Cell stack percentile algorithm returns the cell-wise percentile value of a stack of rasters "
403 "and writes the results to an output raster. The percentile to return is determined by the percentile input value (ranges between 0 and 1). "
404 "At each cell location, the specified percentile is obtained using the respective value from "
405 "the stack of all overlaid and sorted cell values of the input rasters.\n\n"
406 "There are three methods for percentile calculation:"
408 " <li>Nearest rank</li>"
409 " <li>Inclusive linear interpolation (PERCENTILE.INC)</li>"
410 " <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>"
412 "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the "
413 "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation "
414 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
415 "The output raster's extent and resolution is defined by a reference "
416 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
417 "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. "
418 "The output raster data type will be set to the most complex data type present in the input datasets. " );
421QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
const
423 return new QgsCellStatisticsPercentileAlgorithm();
426void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
428 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 ) );
435 mMethod =
static_cast< QgsRasterAnalysisUtils::CellValuePercentileMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
436 mPercentile = parameterAsDouble( parameters, QStringLiteral(
"PERCENTILE" ), context );
440 if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile &&
static_cast< int >( mDataType ) < 6 )
451 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
452 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
453 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
454 mOutputRasterDataProvider->setEditable(
true );
456 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
463 std::unique_ptr< QgsRasterBlock > outputBlock;
464 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
466 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
467 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
471 for (
int band : i.bands )
475 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
476 inputBlocks.emplace_back( std::move( b ) );
480 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
481 for (
int row = 0; row < iterRows; row++ )
486 for (
int col = 0; col < iterCols; col++ )
489 bool noDataInStack =
false;
490 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
491 int cellValueStackSize = cellValues.size();
493 if ( noDataInStack && !mIgnoreNoData )
495 outputBlock->setValue( row, col, mNoDataValue );
497 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
501 case QgsRasterAnalysisUtils::NearestRankPercentile:
502 result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
504 case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
505 result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
507 case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
508 result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
511 outputBlock->setValue( row, col, result );
516 outputBlock->setValue( row, col, mNoDataValue );
520 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
522 mOutputRasterDataProvider->setEditable(
false );
528QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
const
530 return QObject::tr(
"Cell stack percent rank from value" );
533QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
const
535 return QStringLiteral(
"cellstackpercentrankfromvalue" );
538QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
const
540 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value" ).split(
',' );
543QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
const
545 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 "
546 "and writes them to an output raster.\n\n"
547 "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. "
548 "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
549 "There are two methods for percentile calculation:"
551 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
552 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
554 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
555 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
556 "The output raster's extent and resolution is defined by a reference "
557 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
558 "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. "
559 "The output raster data type will always be Float32." );
562QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
const
564 return new QgsCellStatisticsPercentRankFromValueAlgorithm();
567void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
569 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 ) );
576 mMethod =
static_cast< QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
577 mValue = parameterAsDouble( parameters, QStringLiteral(
"VALUE" ), context );
584void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
589 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
590 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
591 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
592 mOutputRasterDataProvider->setEditable(
true );
594 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
601 std::unique_ptr< QgsRasterBlock > outputBlock;
602 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
604 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
605 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
609 for (
int band : i.bands )
613 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
614 inputBlocks.emplace_back( std::move( b ) );
618 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
619 for (
int row = 0; row < iterRows; row++ )
624 for (
int col = 0; col < iterCols; col++ )
627 bool noDataInStack =
false;
628 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
629 int cellValueStackSize = cellValues.size();
631 if ( noDataInStack && !mIgnoreNoData )
633 outputBlock->setValue( row, col, mNoDataValue );
635 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
639 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
640 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
642 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
643 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
646 outputBlock->setValue( row, col, result );
651 outputBlock->setValue( row, col, mNoDataValue );
655 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
657 mOutputRasterDataProvider->setEditable(
false );
664QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
const
666 return QObject::tr(
"Cell stack percentrank from raster layer" );
669QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
const
671 return QStringLiteral(
"cellstackpercentrankfromrasterlayer" );
674QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
const
676 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split(
',' );
679QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
const
681 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 "
682 "and writes them to an output raster.\n\n"
683 "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. "
684 "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"
685 "There are two methods for percentile calculation:"
687 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
688 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
690 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
691 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
692 "The output raster's extent and resolution is defined by a reference "
693 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
694 "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. "
695 "The output raster data type will always be Float32." );
698QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
const
700 return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
703void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
706 addParameter(
new QgsProcessingParameterBand( QStringLiteral(
"VALUE_RASTER_BAND" ), QObject::tr(
"Value raster band" ), 1, QStringLiteral(
"VALUE_LAYER" ) ) );
707 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 ) );
713 mMethod =
static_cast< QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
715 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_VALUE_RASTER" ), context );
716 if ( !inputValueRaster )
721 mValueRasterBand = parameterAsInt( parameters, QStringLiteral(
"VALUE_RASTER_BAND" ), context );
728void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
732 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
733 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
734 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
735 mOutputRasterDataProvider->setEditable(
true );
737 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
744 std::unique_ptr< QgsRasterBlock > outputBlock;
745 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
747 std::unique_ptr< QgsRasterBlock > valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
749 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
750 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
754 for (
int band : i.bands )
758 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
759 inputBlocks.emplace_back( std::move( b ) );
763 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
764 for (
int row = 0; row < iterRows; row++ )
769 for (
int col = 0; col < iterCols; col++ )
771 bool percentRankValueIsNoData =
false;
772 double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
775 bool noDataInStack =
false;
776 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
777 int cellValueStackSize = cellValues.size();
779 if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
781 outputBlock->setValue( row, col, mNoDataValue );
783 else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
787 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
788 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
790 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
791 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
794 outputBlock->setValue( row, col, result );
799 outputBlock->setValue( row, col, mNoDataValue );
803 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
805 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...