QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsalgorithmrandomraster.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmrandomraster.cpp
3 ---------------------
4 begin : May 2020
5 copyright : (C) 2020 by Clemens Raffler
6 email : clemens dot raffler at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "qgsrasterfilewriter.h"
20#include "qgsstringutils.h"
21#include "random"
22#include "limits"
23
25
26//
27// QgsRandomRasterAlgorithmBase
28//
29QString QgsRandomRasterAlgorithmBase::group() const
30{
31 return QObject::tr( "Raster creation" );
32}
33
34QString QgsRandomRasterAlgorithmBase::groupId() const
35{
36 return QStringLiteral( "rastercreation" );
37}
38
39void QgsRandomRasterAlgorithmBase::initAlgorithm( const QVariantMap & )
40{
41 addParameter( new QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Desired extent" ) ) );
42 addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "ProjectCrs" ) ) );
43 addParameter( new QgsProcessingParameterNumber( QStringLiteral( "PIXEL_SIZE" ), QObject::tr( "Pixel size" ),
44 QgsProcessingParameterNumber::Double, 1, false, 0.01 ) );
45
46 //add specific parameters
47 addAlgorithmParams();
48
49 addParameter( new QgsProcessingParameterRasterDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Output raster" ) ) );
50}
51
52bool QgsRandomRasterAlgorithmBase::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
53{
54 Q_UNUSED( feedback );
55 mCrs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );
56 mExtent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, mCrs );
57 mPixelSize = parameterAsDouble( parameters, QStringLiteral( "PIXEL_SIZE" ), context );
58
59 return true;
60}
61
62QVariantMap QgsRandomRasterAlgorithmBase::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
63{
64 const int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
65 //prepare specific parameters
66 mRasterDataType = getRasterDataType( typeId );
67 prepareRandomParameters( parameters, context );
68
69 std::random_device rd {};
70 std::mt19937 mersenneTwister{rd()};
71
72 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( "OUTPUT" ), context );
73 const QFileInfo fi( outputFile );
74 const QString outputFormat = QgsRasterFileWriter::driverForExtension( fi.suffix() );
75
76 const int rows = std::max( std::ceil( mExtent.height() / mPixelSize ), 1.0 );
77 const int cols = std::max( std::ceil( mExtent.width() / mPixelSize ), 1.0 );
78
79 //build new raster extent based on number of columns and cellsize
80 //this prevents output cellsize being calculated too small
81 const QgsRectangle rasterExtent = QgsRectangle( mExtent.xMinimum(), mExtent.yMaximum() - ( rows * mPixelSize ), mExtent.xMinimum() + ( cols * mPixelSize ), mExtent.yMaximum() );
82
83 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
84 writer->setOutputProviderKey( QStringLiteral( "gdal" ) );
85 writer->setOutputFormat( outputFormat );
86 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mRasterDataType, cols, rows, rasterExtent, mCrs ) );
87 if ( !provider )
88 throw QgsProcessingException( QObject::tr( "Could not create raster output: %1" ).arg( outputFile ) );
89 if ( !provider->isValid() )
90 throw QgsProcessingException( QObject::tr( "Could not create raster output %1: %2" ).arg( outputFile, provider->error().message( QgsErrorMessage::Text ) ) );
91
92 const double step = rows > 0 ? 100.0 / rows : 1;
93
94 for ( int row = 0; row < rows ; row++ )
95 {
96 if ( feedback->isCanceled() )
97 {
98 break;
99 }
100 //prepare raw data depending on raster data type
101 QgsRasterBlock block( mRasterDataType, cols, 1 );
102 switch ( mRasterDataType )
103 {
105 {
106 std::vector<quint8> byteRow( cols );
107 for ( int col = 0; col < cols; col++ )
108 {
109 byteRow[col] = static_cast<quint8>( generateRandomLongValue( mersenneTwister ) );
110 }
111 block.setData( QByteArray( reinterpret_cast<const char *>( byteRow.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Byte ) * cols ) );
112 break;
113 }
115 {
116 std::vector<qint16> int16Row( cols );
117 for ( int col = 0; col < cols; col++ )
118 {
119 int16Row[col] = static_cast<qint16>( generateRandomLongValue( mersenneTwister ) );
120 }
121 block.setData( QByteArray( reinterpret_cast<const char *>( int16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int16 ) * cols ) );
122 break;
123 }
125 {
126 std::vector<quint16> uInt16Row( cols );
127 for ( int col = 0; col < cols; col++ )
128 {
129 uInt16Row[col] = static_cast<quint16>( generateRandomLongValue( mersenneTwister ) );
130 }
131 block.setData( QByteArray( reinterpret_cast<const char *>( uInt16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt16 ) * cols ) );
132 break;
133 }
135 {
136 std::vector<qint32> int32Row( cols );
137 for ( int col = 0; col < cols; col++ )
138 {
139 int32Row[col] = generateRandomLongValue( mersenneTwister );
140 }
141 block.setData( QByteArray( reinterpret_cast<const char *>( int32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int32 ) * cols ) );
142 break;
143 }
145 {
146 std::vector<quint32> uInt32Row( cols );
147 for ( int col = 0; col < cols; col++ )
148 {
149 uInt32Row[col] = static_cast<quint32>( generateRandomLongValue( mersenneTwister ) );
150 }
151 block.setData( QByteArray( reinterpret_cast<const char *>( uInt32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt32 ) * cols ) );
152 break;
153 }
155 {
156 std::vector<float> float32Row( cols );
157 for ( int col = 0; col < cols; col++ )
158 {
159 float32Row[col] = static_cast<float>( generateRandomDoubleValue( mersenneTwister ) );
160 }
161 block.setData( QByteArray( reinterpret_cast<const char *>( float32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float32 ) * cols ) );
162 break;
163 }
165 {
166 std::vector<double> float64Row( cols );
167 for ( int col = 0; col < cols; col++ )
168 {
169 float64Row[col] = generateRandomDoubleValue( mersenneTwister );
170 }
171 block.setData( QByteArray( reinterpret_cast<const char *>( float64Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float64 ) * cols ) );
172 break;
173 }
174 default:
175 break;
176 }
177 provider->writeBlock( &block, 1, 0, row );
178 feedback->setProgress( row * step );
179 }
180
181 QVariantMap outputs;
182 outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
183 return outputs;
184}
185
186//
187//QgsRandomUniformRasterAlgorithm
188//
189QString QgsRandomUniformRasterAlgorithm::name() const
190{
191 return QStringLiteral( "createrandomuniformrasterlayer" );
192}
193
194QString QgsRandomUniformRasterAlgorithm::displayName() const
195{
196 return QObject::tr( "Create random raster layer (uniform distribution)" );
197}
198
199QStringList QgsRandomUniformRasterAlgorithm::tags() const
200{
201 return QObject::tr( "raster,create,random" ).split( ',' );
202}
203
204QString QgsRandomUniformRasterAlgorithm::shortHelpString() const
205{
206 return QObject::tr( "Generates a raster layer for given extent and cell size "
207 "filled with random values.\n"
208 "By default, the values will range between the minimum and "
209 "maximum value of the specified output raster type. This can "
210 "be overridden by using the advanced parameters for lower and "
211 "upper bound value. If the bounds have the same value or both "
212 "are zero (default) the algorithm will create random values in "
213 "the full value range of the chosen raster data type. "
214 "Choosing bounds outside the acceptable range of the output "
215 "raster type will abort the algorithm." );
216}
217
218QgsRandomUniformRasterAlgorithm *QgsRandomUniformRasterAlgorithm::createInstance() const
219{
220 return new QgsRandomUniformRasterAlgorithm();
221}
222
223void QgsRandomUniformRasterAlgorithm::addAlgorithmParams()
224{
225 QStringList rasterDataTypes = QStringList();
226 rasterDataTypes << QStringLiteral( "Byte" )
227 << QStringLiteral( "Integer16" )
228 << QStringLiteral( "Unsigned Integer16" )
229 << QStringLiteral( "Integer32" )
230 << QStringLiteral( "Unsigned Integer32" )
231 << QStringLiteral( "Float32" )
232 << QStringLiteral( "Float64" );
233
234 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 5, false );
235 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
236 addParameter( rasterTypeParameter.release() );
237
238 std::unique_ptr< QgsProcessingParameterNumber > lowerBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LOWER_BOUND" ), QStringLiteral( "Lower bound for random number range" ), QgsProcessingParameterNumber::Double, QVariant(), true );
239 lowerBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
240 addParameter( lowerBoundParameter.release() );
241
242 std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "UPPER_BOUND" ), QStringLiteral( "Upper bound for random number range" ), QgsProcessingParameterNumber::Double, QVariant(), true );
243 upperBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
244 addParameter( upperBoundParameter.release() );
245}
246
247Qgis::DataType QgsRandomUniformRasterAlgorithm::getRasterDataType( int typeId )
248{
249 switch ( typeId )
250 {
251 case 0:
253 case 1:
255 case 2:
257 case 3:
259 case 4:
261 case 5:
263 case 6:
265 default:
267 }
268}
269
270bool QgsRandomUniformRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
271{
272 mRandomUpperBound = parameterAsDouble( parameters, QStringLiteral( "UPPER_BOUND" ), context );
273 mRandomLowerBound = parameterAsDouble( parameters, QStringLiteral( "LOWER_BOUND" ), context );
274
275 if ( mRandomLowerBound > mRandomUpperBound )
276 throw QgsProcessingException( QObject::tr( "The chosen lower bound for random number range is greater than the upper bound. The lower bound value must be smaller than the upper bound value." ) );
277
278 const int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
279 const Qgis::DataType rasterDataType = getRasterDataType( typeId );
280
281 switch ( rasterDataType )
282 {
284 if ( mRandomLowerBound < std::numeric_limits<quint8>::min() || mRandomUpperBound > std::numeric_limits<quint8>::max() )
285 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<quint8>::min() ).arg( std::numeric_limits<quint8>::max() ).arg( QLatin1String( "Byte" ) ) );
286 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
287 {
288 //if parameters unset (=both are 0 or equal) --> use the whole value range
289 mRandomUpperBound = std::numeric_limits<quint8>::max();
290 mRandomLowerBound = std::numeric_limits<quint8>::min();
291 }
292 break;
294 if ( mRandomLowerBound < std::numeric_limits<qint16>::min() || mRandomUpperBound > std::numeric_limits<qint16>::max() )
295 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<qint16>::min() ).arg( std::numeric_limits<qint16>::max() ).arg( QLatin1String( "Integer16" ) ) );
296 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
297 {
298 mRandomUpperBound = std::numeric_limits<qint16>::max();
299 mRandomLowerBound = std::numeric_limits<qint16>::min();
300 }
301 break;
303 if ( mRandomLowerBound < std::numeric_limits<quint16>::min() || mRandomUpperBound > std::numeric_limits<quint16>::max() )
304 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<quint16>::min() ).arg( std::numeric_limits<quint16>::max() ).arg( QLatin1String( "Unsigned Integer16" ) ) );
305 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
306 {
307 mRandomUpperBound = std::numeric_limits<quint16>::max();
308 mRandomLowerBound = std::numeric_limits<quint16>::min();
309 }
310 break;
312 if ( mRandomLowerBound < std::numeric_limits<qint32>::min() || mRandomUpperBound > std::numeric_limits<qint32>::max() )
313 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<qint32>::min() ).arg( std::numeric_limits<qint32>::max() ).arg( QLatin1String( "Integer32" ) ) );
314 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
315 {
316 mRandomUpperBound = std::numeric_limits<qint32>::max();
317 mRandomLowerBound = std::numeric_limits<qint32>::min();
318 }
319 break;
321 if ( mRandomLowerBound < std::numeric_limits<quint32>::min() || mRandomUpperBound > std::numeric_limits<quint32>::max() )
322 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<quint32>::min() ).arg( std::numeric_limits<quint32>::max() ).arg( QLatin1String( "Unsigned Integer32" ) ) );
323 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
324 {
325 mRandomUpperBound = std::numeric_limits<quint32>::max();
326 mRandomLowerBound = std::numeric_limits<quint32>::min();
327 }
328 break;
330 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
331 {
332 mRandomUpperBound = std::numeric_limits<float>::max();
333 mRandomLowerBound = std::numeric_limits<float>::min();
334 }
335 break;
337 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
338 {
339 mRandomUpperBound = std::numeric_limits<double>::max();
340 mRandomLowerBound = std::numeric_limits<double>::min();
341 }
342 break;
343 default:
344 break;
345 }
346
347 mRandomUniformIntDistribution = std::uniform_int_distribution<long>( mRandomLowerBound, mRandomUpperBound );
348 mRandomUniformDoubleDistribution = std::uniform_real_distribution<double>( mRandomLowerBound, mRandomUpperBound );
349
350 return true;
351}
352
353long QgsRandomUniformRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
354{
355 return mRandomUniformIntDistribution( mersenneTwister );
356}
357
358double QgsRandomUniformRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
359{
360 return mRandomUniformDoubleDistribution( mersenneTwister );
361}
362
363//
364// QgsRandomBinomialRasterAlgorithm
365//
366QString QgsRandomBinomialRasterAlgorithm::name() const
367{
368 return QStringLiteral( "createrandombinomialrasterlayer" );
369}
370
371QString QgsRandomBinomialRasterAlgorithm::displayName() const
372{
373 return QObject::tr( "Create random raster layer (binomial distribution)" );
374}
375
376QStringList QgsRandomBinomialRasterAlgorithm::tags() const
377{
378 return QObject::tr( "raster,create,binomial,random" ).split( ',' );
379}
380
381QString QgsRandomBinomialRasterAlgorithm::shortHelpString() const
382{
383 return QObject::tr( "Generates a raster layer for given extent and cell size "
384 "filled with binomially distributed random values.\n"
385 "By default, the values will be chosen given an N of 10 and a probability of 0.5. "
386 "This can be overridden by using the advanced parameter for N and probability. "
387 "The raster data type is set to Integer types (Integer16 by default). "
388 "The binomial distribution random values are defined as positive integer numbers. "
389 "A floating point raster will represent a cast of integer values "
390 "to floating point." );
391}
392
393QgsRandomBinomialRasterAlgorithm *QgsRandomBinomialRasterAlgorithm::createInstance() const
394{
395 return new QgsRandomBinomialRasterAlgorithm();
396}
397
398
399void QgsRandomBinomialRasterAlgorithm::addAlgorithmParams( )
400{
401 QStringList rasterDataTypes = QStringList();
402 rasterDataTypes << QStringLiteral( "Integer16" )
403 << QStringLiteral( "Unsigned Integer16" )
404 << QStringLiteral( "Integer32" )
405 << QStringLiteral( "Unsigned Integer32" )
406 << QStringLiteral( "Float32" )
407 << QStringLiteral( "Float64" );
408
409 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
410 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
411 addParameter( rasterTypeParameter.release() );
412
413 std::unique_ptr< QgsProcessingParameterNumber > nParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "N" ), QStringLiteral( "N" ), QgsProcessingParameterNumber::Integer, 10, true, 0 );
415 addParameter( nParameter.release() );
416
417 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0 );
418 probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
419 addParameter( probabilityParameter.release() );
420}
421
422Qgis::DataType QgsRandomBinomialRasterAlgorithm::getRasterDataType( int typeId )
423{
424 switch ( typeId )
425 {
426 case 0:
428 case 1:
430 case 2:
432 case 3:
434 case 4:
436 case 5:
438 default:
440 }
441}
442
443bool QgsRandomBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
444{
445 const int n = parameterAsInt( parameters, QStringLiteral( "N" ), context );
446 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
447 mRandombinomialDistribution = std::binomial_distribution<long>( n, probability );
448 return true;
449}
450
451long QgsRandomBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
452{
453 return mRandombinomialDistribution( mersenneTwister );
454}
455
456double QgsRandomBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
457{
458 return static_cast<double>( mRandombinomialDistribution( mersenneTwister ) );
459}
460
461//
462// QgsRandomExponentialRasterAlgorithm
463//
464QString QgsRandomExponentialRasterAlgorithm::name() const
465{
466 return QStringLiteral( "createrandomexponentialrasterlayer" );
467}
468
469QString QgsRandomExponentialRasterAlgorithm::displayName() const
470{
471 return QObject::tr( "Create random raster layer (exponential distribution)" );
472}
473
474QStringList QgsRandomExponentialRasterAlgorithm::tags() const
475{
476 return QObject::tr( "raster,create,random,exponential" ).split( ',' );
477}
478
479QString QgsRandomExponentialRasterAlgorithm::shortHelpString() const
480{
481 return QObject::tr( "Generates a raster layer for given extent and cell size "
482 "filled with exponentially distributed random values.\n"
483 "By default, the values will be chosen given a lambda of 1.0. "
484 "This can be overridden by using the advanced parameter for lambda. "
485 "The raster data type is set to Float32 by default as "
486 "the exponential distribution random values are floating point numbers." );
487}
488
489QgsRandomExponentialRasterAlgorithm *QgsRandomExponentialRasterAlgorithm::createInstance() const
490{
491 return new QgsRandomExponentialRasterAlgorithm();
492}
493
494
495void QgsRandomExponentialRasterAlgorithm::addAlgorithmParams()
496{
497 QStringList rasterDataTypes = QStringList();
498 rasterDataTypes << QStringLiteral( "Float32" )
499 << QStringLiteral( "Float64" );
500
501 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
502 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
503 addParameter( rasterTypeParameter.release() );
504
505 std::unique_ptr< QgsProcessingParameterNumber > lambdaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LAMBDA" ), QStringLiteral( "Lambda" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
506 lambdaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
507 addParameter( lambdaParameter.release() );
508}
509
510Qgis::DataType QgsRandomExponentialRasterAlgorithm::getRasterDataType( int typeId )
511{
512 switch ( typeId )
513 {
514 case 0:
516 case 1:
518 default:
520 }
521}
522
523bool QgsRandomExponentialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
524{
525 const double lambda = parameterAsDouble( parameters, QStringLiteral( "LAMBDA" ), context );
526 mRandomExponentialDistribution = std::exponential_distribution<double>( lambda );
527 return true;
528}
529
530long QgsRandomExponentialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
531{
532 return static_cast<long>( mRandomExponentialDistribution( mersenneTwister ) );
533}
534
535double QgsRandomExponentialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
536{
537 return mRandomExponentialDistribution( mersenneTwister );
538}
539
540//
541// QgsRandomGammaRasterAlgorithm
542//
543QString QgsRandomGammaRasterAlgorithm::name() const
544{
545 return QStringLiteral( "createrandomgammarasterlayer" );
546}
547
548QString QgsRandomGammaRasterAlgorithm::displayName() const
549{
550 return QObject::tr( "Create random raster layer (gamma distribution)" );
551}
552
553QStringList QgsRandomGammaRasterAlgorithm::tags() const
554{
555 return QObject::tr( "raster,create,random,gamma" ).split( ',' );
556}
557
558QString QgsRandomGammaRasterAlgorithm::shortHelpString() const
559{
560 return QObject::tr( "Generates a raster layer for given extent and cell size "
561 "filled with gamma distributed random values.\n"
562 "By default, the values will be chosen given an alpha and beta value of 1.0. "
563 "This can be overridden by using the advanced parameter for alpha and beta. "
564 "The raster data type is set to Float32 by default as "
565 "the gamma distribution random values are floating point numbers." );
566}
567
568QgsRandomGammaRasterAlgorithm *QgsRandomGammaRasterAlgorithm::createInstance() const
569{
570 return new QgsRandomGammaRasterAlgorithm();
571}
572
573
574void QgsRandomGammaRasterAlgorithm::addAlgorithmParams()
575{
576 QStringList rasterDataTypes = QStringList();
577 rasterDataTypes << QStringLiteral( "Float32" )
578 << QStringLiteral( "Float64" );
579
580 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
581 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
582 addParameter( rasterTypeParameter.release() );
583
584 std::unique_ptr< QgsProcessingParameterNumber > alphaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ALPHA" ), QStringLiteral( "Alpha" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
585 alphaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
586 addParameter( alphaParameter.release() );
587
588 std::unique_ptr< QgsProcessingParameterNumber > betaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "BETA" ), QStringLiteral( "Beta" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
589 betaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
590 addParameter( betaParameter.release() );
591}
592
593Qgis::DataType QgsRandomGammaRasterAlgorithm::getRasterDataType( int typeId )
594{
595 switch ( typeId )
596 {
597 case 0:
599 case 1:
601 default:
603 }
604}
605
606bool QgsRandomGammaRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
607{
608 const double alpha = parameterAsDouble( parameters, QStringLiteral( "ALPHA" ), context );
609 const double beta = parameterAsDouble( parameters, QStringLiteral( "BETA" ), context );
610 mRandomGammaDistribution = std::gamma_distribution<double>( alpha, beta );
611 return true;
612}
613
614long QgsRandomGammaRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
615{
616 return static_cast<long>( mRandomGammaDistribution( mersenneTwister ) );
617}
618
619double QgsRandomGammaRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
620{
621 return mRandomGammaDistribution( mersenneTwister );
622}
623
624//
625// QgsRandomGeometricRasterAlgorithm
626//
627QString QgsRandomGeometricRasterAlgorithm::name() const
628{
629 return QStringLiteral( "createrandomgeometricrasterlayer" );
630}
631
632QString QgsRandomGeometricRasterAlgorithm::displayName() const
633{
634 return QObject::tr( "Create random raster layer (geometric distribution)" );
635}
636
637QStringList QgsRandomGeometricRasterAlgorithm::tags() const
638{
639 return QObject::tr( "raster,create,random,geometric" ).split( ',' );
640}
641
642QString QgsRandomGeometricRasterAlgorithm::shortHelpString() const
643{
644 return QObject::tr( "Generates a raster layer for given extent and cell size "
645 "filled with geometrically distributed random values.\n"
646 "By default, the values will be chosen given a probability of 0.5. "
647 "This can be overridden by using the advanced parameter for mean "
648 "value. The raster data type is set to Integer types (Integer16 by default). "
649 "The geometric distribution random values are defined as positive integer numbers. "
650 "A floating point raster will represent a cast of "
651 "integer values to floating point." );
652}
653
654QgsRandomGeometricRasterAlgorithm *QgsRandomGeometricRasterAlgorithm::createInstance() const
655{
656 return new QgsRandomGeometricRasterAlgorithm();
657}
658
659
660void QgsRandomGeometricRasterAlgorithm::addAlgorithmParams()
661{
662 QStringList rasterDataTypes = QStringList();
663 rasterDataTypes << QStringLiteral( "Integer16" )
664 << QStringLiteral( "Unsigned Integer16" )
665 << QStringLiteral( "Integer32" )
666 << QStringLiteral( "Unsigned Integer32" )
667 << QStringLiteral( "Float32" )
668 << QStringLiteral( "Float64" );
669
670 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
671 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
672 addParameter( rasterTypeParameter.release() );
673
674 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0.00001 );
675 probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
676 addParameter( probabilityParameter.release() );
677}
678
679Qgis::DataType QgsRandomGeometricRasterAlgorithm::getRasterDataType( int typeId )
680{
681 switch ( typeId )
682 {
683 case 0:
685 case 1:
687 case 2:
689 case 3:
691 case 4:
693 case 5:
695 default:
697 }
698}
699
700bool QgsRandomGeometricRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
701{
702 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
703 mRandomGeometricDistribution = std::geometric_distribution<long>( probability );
704 return true;
705}
706
707long QgsRandomGeometricRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
708{
709 return mRandomGeometricDistribution( mersenneTwister );
710}
711
712double QgsRandomGeometricRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
713{
714 return static_cast<double>( mRandomGeometricDistribution( mersenneTwister ) );
715}
716
717//
718// QgsRandomNegativeBinomialRasterAlgorithm
719//
720QString QgsRandomNegativeBinomialRasterAlgorithm::name() const
721{
722 return QStringLiteral( "createrandomnegativebinomialrasterlayer" );
723}
724
725QString QgsRandomNegativeBinomialRasterAlgorithm::displayName() const
726{
727 return QObject::tr( "Create random raster layer (negative binomial distribution)" );
728}
729
730QStringList QgsRandomNegativeBinomialRasterAlgorithm::tags() const
731{
732 return QObject::tr( "raster,create,random,negative,binomial,negative-binomial" ).split( ',' );
733}
734
735QString QgsRandomNegativeBinomialRasterAlgorithm::shortHelpString() const
736{
737 return QObject::tr( "Generates a raster layer for given extent and cell size "
738 "filled with negative binomially distributed random values.\n"
739 "By default, the values will be chosen given a distribution parameter k of 10.0 "
740 "and a probability of 0.5. "
741 "This can be overridden by using the advanced parameters for k and probability. "
742 "The raster data type is set to Integer types (Integer 16 by default). "
743 "The negative binomial distribution random values are defined as positive integer numbers. "
744 "A floating point raster will represent a cast of "
745 "integer values to floating point." );
746}
747
748QgsRandomNegativeBinomialRasterAlgorithm *QgsRandomNegativeBinomialRasterAlgorithm::createInstance() const
749{
750 return new QgsRandomNegativeBinomialRasterAlgorithm();
751}
752
753
754void QgsRandomNegativeBinomialRasterAlgorithm::addAlgorithmParams( )
755{
756 QStringList rasterDataTypes = QStringList();
757 rasterDataTypes << QStringLiteral( "Integer16" )
758 << QStringLiteral( "Unsigned Integer16" )
759 << QStringLiteral( "Integer32" )
760 << QStringLiteral( "Unsigned Integer32" )
761 << QStringLiteral( "Float32" )
762 << QStringLiteral( "Float64" );
763
764 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
765 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
766 addParameter( rasterTypeParameter.release() );
767
768 std::unique_ptr< QgsProcessingParameterNumber > kParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "K_PARAMETER" ), QStringLiteral( "Distribution parameter k" ), QgsProcessingParameterNumber::Integer, 10, true, 0.00001 );
770 addParameter( kParameter.release() );
771
772 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0.00001 );
773 probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
774 addParameter( probabilityParameter.release() );
775}
776
777Qgis::DataType QgsRandomNegativeBinomialRasterAlgorithm::getRasterDataType( int typeId )
778{
779 switch ( typeId )
780 {
781 case 0:
783 case 1:
785 case 2:
787 case 3:
789 case 4:
791 case 5:
793 default:
795 }
796}
797
798bool QgsRandomNegativeBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
799{
800 const int k = parameterAsInt( parameters, QStringLiteral( "K_PARAMETER" ), context );
801 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
802 mRandomNegativeBinomialDistribution = std::negative_binomial_distribution<long>( k, probability );
803 return true;
804}
805
806long QgsRandomNegativeBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
807{
808 return mRandomNegativeBinomialDistribution( mersenneTwister );
809}
810
811double QgsRandomNegativeBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
812{
813 return static_cast<double>( mRandomNegativeBinomialDistribution( mersenneTwister ) );
814}
815
816//
817// QgsRandomNormalRasterAlgorithm
818//
819QString QgsRandomNormalRasterAlgorithm::name() const
820{
821 return QStringLiteral( "createrandomnormalrasterlayer" );
822}
823
824QString QgsRandomNormalRasterAlgorithm::displayName() const
825{
826 return QObject::tr( "Create random raster layer (normal distribution)" );
827}
828
829QStringList QgsRandomNormalRasterAlgorithm::tags() const
830{
831 return QObject::tr( "raster,create,normal,distribution,random" ).split( ',' );
832}
833
834QString QgsRandomNormalRasterAlgorithm::shortHelpString() const
835{
836 return QObject::tr( "Generates a raster layer for given extent and cell size "
837 "filled with normally distributed random values.\n"
838 "By default, the values will be chosen given a mean of 0.0 and "
839 "a standard deviation of 1.0. This can be overridden by "
840 "using the advanced parameters for mean and standard deviation "
841 "value. The raster data type is set to Float32 by default "
842 "as the normal distribution random values are floating point numbers." );
843}
844
845QgsRandomNormalRasterAlgorithm *QgsRandomNormalRasterAlgorithm::createInstance() const
846{
847 return new QgsRandomNormalRasterAlgorithm();
848}
849
850void QgsRandomNormalRasterAlgorithm::addAlgorithmParams()
851{
852 QStringList rasterDataTypes = QStringList();
853 rasterDataTypes << QStringLiteral( "Float32" )
854 << QStringLiteral( "Float64" );
855
856 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
857 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
858 addParameter( rasterTypeParameter.release() );
859
860 std::unique_ptr< QgsProcessingParameterNumber > meanParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean of normal distribution" ), QgsProcessingParameterNumber::Double, 0, true );
861 meanParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
862 addParameter( meanParameter.release() );
863
864 std::unique_ptr< QgsProcessingParameterNumber > stdevParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "STDDEV" ), QStringLiteral( "Standard deviation of normal distribution" ), QgsProcessingParameterNumber::Double, 1, true, 0 );
865 stdevParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
866 addParameter( stdevParameter.release() );
867}
868
869Qgis::DataType QgsRandomNormalRasterAlgorithm::getRasterDataType( int typeId )
870{
871 switch ( typeId )
872 {
873 case 0:
875 case 1:
877 default:
879 }
880}
881
882bool QgsRandomNormalRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
883{
884 const double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
885 const double stddev = parameterAsDouble( parameters, QStringLiteral( "STDDEV" ), context );
886 mRandomNormalDistribution = std::normal_distribution<double>( mean, stddev );
887 return true;
888}
889
890long QgsRandomNormalRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
891{
892 return static_cast<long>( mRandomNormalDistribution( mersenneTwister ) );
893}
894
895double QgsRandomNormalRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
896{
897 return mRandomNormalDistribution( mersenneTwister );
898}
899
900//
901// QgsRandomPoissonRasterAlgorithm
902//
903QString QgsRandomPoissonRasterAlgorithm::name() const
904{
905 return QStringLiteral( "createrandompoissonrasterlayer" );
906}
907
908QString QgsRandomPoissonRasterAlgorithm::displayName() const
909{
910 return QObject::tr( "Create random raster layer (poisson distribution)" );
911}
912
913QStringList QgsRandomPoissonRasterAlgorithm::tags() const
914{
915 return QObject::tr( "raster,create,random,poisson" ).split( ',' );
916}
917
918QString QgsRandomPoissonRasterAlgorithm::shortHelpString() const
919{
920 return QObject::tr( "Generates a raster layer for given extent and cell size "
921 "filled with poisson distributed random values.\n"
922 "By default, the values will be chosen given a mean of 1.0. "
923 "This can be overridden by using the advanced parameter for mean "
924 "value. The raster data type is set to Integer types (Integer16 by default). "
925 "The poisson distribution random values are positive integer numbers. "
926 "A floating point raster will represent a cast of integer values to floating point." );
927}
928
929QgsRandomPoissonRasterAlgorithm *QgsRandomPoissonRasterAlgorithm::createInstance() const
930{
931 return new QgsRandomPoissonRasterAlgorithm();
932}
933
934
935void QgsRandomPoissonRasterAlgorithm::addAlgorithmParams()
936{
937 QStringList rasterDataTypes = QStringList();
938 rasterDataTypes << QStringLiteral( "Integer16" )
939 << QStringLiteral( "Unsigned Integer16" )
940 << QStringLiteral( "Integer32" )
941 << QStringLiteral( "Unsigned Integer32" )
942 << QStringLiteral( "Float32" )
943 << QStringLiteral( "Float64" );
944
945 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
946 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
947 addParameter( rasterTypeParameter.release() );
948
949 std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean" ), QgsProcessingParameterNumber::Double, 1.0, true, 0 );
950 upperBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
951 addParameter( upperBoundParameter.release() );
952}
953
954Qgis::DataType QgsRandomPoissonRasterAlgorithm::getRasterDataType( int typeId )
955{
956 switch ( typeId )
957 {
958 case 0:
960 case 1:
962 case 2:
964 case 3:
966 case 4:
968 case 5:
970 default:
972 }
973}
974
975bool QgsRandomPoissonRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
976{
977 const double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
978 mRandomPoissonDistribution = std::poisson_distribution<long>( mean );
979 return true;
980}
981
982long QgsRandomPoissonRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
983{
984 return mRandomPoissonDistribution( mersenneTwister );
985}
986
987double QgsRandomPoissonRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
988{
989 return static_cast<double>( mRandomPoissonDistribution( mersenneTwister ) );
990}
991
DataType
Raster data types.
Definition: qgis.h:129
@ Float32
Thirty two bit floating point (float)
@ Int16
Sixteen bit signed integer (qint16)
@ UInt16
Sixteen bit unsigned integer (quint16)
@ Byte
Eight bit unsigned integer (quint8)
@ Int32
Thirty two bit signed integer (qint32)
@ Float64
Sixty four bit floating point (double)
@ UInt32
Thirty two bit unsigned integer (quint32)
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
A coordinate reference system parameter for processing algorithms.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
A rectangular map extent parameter for processing algorithms.
A numeric parameter for processing algorithms.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
Raster data container.
static int typeSize(Qgis::DataType dataType) SIP_HOLDGIL
Returns the size in bytes for the specified dataType.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2527