QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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" ),
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 if ( mPixelSize <= 0 )
60 {
61 throw QgsProcessingException( QObject::tr( "Pixel size must be greater than 0." ) );
62 }
63
64 return true;
65}
66
67QVariantMap QgsRandomRasterAlgorithmBase::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
68{
69 const int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
70 //prepare specific parameters
71 mRasterDataType = getRasterDataType( typeId );
72 prepareRandomParameters( parameters, context );
73
74 std::random_device rd {};
75 std::mt19937 mersenneTwister{rd()};
76
77 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( "OUTPUT" ), context );
78 const QFileInfo fi( outputFile );
79 const QString outputFormat = QgsRasterFileWriter::driverForExtension( fi.suffix() );
80
81 const int rows = std::max( std::ceil( mExtent.height() / mPixelSize ), 1.0 );
82 const int cols = std::max( std::ceil( mExtent.width() / mPixelSize ), 1.0 );
83
84 //build new raster extent based on number of columns and cellsize
85 //this prevents output cellsize being calculated too small
86 const QgsRectangle rasterExtent = QgsRectangle( mExtent.xMinimum(), mExtent.yMaximum() - ( rows * mPixelSize ), mExtent.xMinimum() + ( cols * mPixelSize ), mExtent.yMaximum() );
87
88 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
89 writer->setOutputProviderKey( QStringLiteral( "gdal" ) );
90 writer->setOutputFormat( outputFormat );
91 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mRasterDataType, cols, rows, rasterExtent, mCrs ) );
92 if ( !provider )
93 throw QgsProcessingException( QObject::tr( "Could not create raster output: %1" ).arg( outputFile ) );
94 if ( !provider->isValid() )
95 throw QgsProcessingException( QObject::tr( "Could not create raster output %1: %2" ).arg( outputFile, provider->error().message( QgsErrorMessage::Text ) ) );
96
97 const double step = rows > 0 ? 100.0 / rows : 1;
98
99 for ( int row = 0; row < rows ; row++ )
100 {
101 if ( feedback->isCanceled() )
102 {
103 break;
104 }
105 //prepare raw data depending on raster data type
106 QgsRasterBlock block( mRasterDataType, cols, 1 );
107 switch ( mRasterDataType )
108 {
110 {
111 std::vector<quint8> byteRow( cols );
112 for ( int col = 0; col < cols; col++ )
113 {
114 byteRow[col] = static_cast<quint8>( generateRandomLongValue( mersenneTwister ) );
115 }
116 block.setData( QByteArray( reinterpret_cast<const char *>( byteRow.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Byte ) * cols ) );
117 break;
118 }
120 {
121 std::vector<qint8> int8Row( cols );
122 for ( int col = 0; col < cols; col++ )
123 {
124 int8Row[col] = static_cast<qint8>( generateRandomLongValue( mersenneTwister ) );
125 }
126 block.setData( QByteArray( reinterpret_cast<const char *>( int8Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int8 ) * cols ) );
127 break;
128 }
130 {
131 std::vector<qint16> int16Row( cols );
132 for ( int col = 0; col < cols; col++ )
133 {
134 int16Row[col] = static_cast<qint16>( generateRandomLongValue( mersenneTwister ) );
135 }
136 block.setData( QByteArray( reinterpret_cast<const char *>( int16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int16 ) * cols ) );
137 break;
138 }
140 {
141 std::vector<quint16> uInt16Row( cols );
142 for ( int col = 0; col < cols; col++ )
143 {
144 uInt16Row[col] = static_cast<quint16>( generateRandomLongValue( mersenneTwister ) );
145 }
146 block.setData( QByteArray( reinterpret_cast<const char *>( uInt16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt16 ) * cols ) );
147 break;
148 }
150 {
151 std::vector<qint32> int32Row( cols );
152 for ( int col = 0; col < cols; col++ )
153 {
154 int32Row[col] = generateRandomLongValue( mersenneTwister );
155 }
156 block.setData( QByteArray( reinterpret_cast<const char *>( int32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int32 ) * cols ) );
157 break;
158 }
160 {
161 std::vector<quint32> uInt32Row( cols );
162 for ( int col = 0; col < cols; col++ )
163 {
164 uInt32Row[col] = static_cast<quint32>( generateRandomLongValue( mersenneTwister ) );
165 }
166 block.setData( QByteArray( reinterpret_cast<const char *>( uInt32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt32 ) * cols ) );
167 break;
168 }
170 {
171 std::vector<float> float32Row( cols );
172 for ( int col = 0; col < cols; col++ )
173 {
174 float32Row[col] = static_cast<float>( generateRandomDoubleValue( mersenneTwister ) );
175 }
176 block.setData( QByteArray( reinterpret_cast<const char *>( float32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float32 ) * cols ) );
177 break;
178 }
180 {
181 std::vector<double> float64Row( cols );
182 for ( int col = 0; col < cols; col++ )
183 {
184 float64Row[col] = generateRandomDoubleValue( mersenneTwister );
185 }
186 block.setData( QByteArray( reinterpret_cast<const char *>( float64Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float64 ) * cols ) );
187 break;
188 }
189 default:
190 break;
191 }
192 provider->writeBlock( &block, 1, 0, row );
193 feedback->setProgress( row * step );
194 }
195
196 QVariantMap outputs;
197 outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
198 return outputs;
199}
200
201//
202//QgsRandomUniformRasterAlgorithm
203//
204QString QgsRandomUniformRasterAlgorithm::name() const
205{
206 return QStringLiteral( "createrandomuniformrasterlayer" );
207}
208
209QString QgsRandomUniformRasterAlgorithm::displayName() const
210{
211 return QObject::tr( "Create random raster layer (uniform distribution)" );
212}
213
214QStringList QgsRandomUniformRasterAlgorithm::tags() const
215{
216 return QObject::tr( "raster,create,random" ).split( ',' );
217}
218
219QString QgsRandomUniformRasterAlgorithm::shortHelpString() const
220{
221 return QObject::tr( "Generates a raster layer for given extent and cell size "
222 "filled with random values.\n"
223 "By default, the values will range between the minimum and "
224 "maximum value of the specified output raster type. This can "
225 "be overridden by using the advanced parameters for lower and "
226 "upper bound value. If the bounds have the same value or both "
227 "are zero (default) the algorithm will create random values in "
228 "the full value range of the chosen raster data type. "
229 "Choosing bounds outside the acceptable range of the output "
230 "raster type will abort the algorithm." );
231}
232
233QgsRandomUniformRasterAlgorithm *QgsRandomUniformRasterAlgorithm::createInstance() const
234{
235 return new QgsRandomUniformRasterAlgorithm();
236}
237
238void QgsRandomUniformRasterAlgorithm::addAlgorithmParams()
239{
240 QStringList rasterDataTypes = QStringList();
241 rasterDataTypes << QStringLiteral( "Byte" )
242 << QStringLiteral( "Integer16" )
243 << QStringLiteral( "Unsigned Integer16" )
244 << QStringLiteral( "Integer32" )
245 << QStringLiteral( "Unsigned Integer32" )
246 << QStringLiteral( "Float32" )
247 << QStringLiteral( "Float64" );
248
249 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 5, false );
250 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
251 addParameter( rasterTypeParameter.release() );
252
253 std::unique_ptr< QgsProcessingParameterNumber > lowerBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LOWER_BOUND" ), QStringLiteral( "Lower bound for random number range" ), Qgis::ProcessingNumberParameterType::Double, QVariant(), true );
254 lowerBoundParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
255 addParameter( lowerBoundParameter.release() );
256
257 std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "UPPER_BOUND" ), QStringLiteral( "Upper bound for random number range" ), Qgis::ProcessingNumberParameterType::Double, QVariant(), true );
258 upperBoundParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
259 addParameter( upperBoundParameter.release() );
260}
261
262Qgis::DataType QgsRandomUniformRasterAlgorithm::getRasterDataType( int typeId )
263{
264 switch ( typeId )
265 {
266 case 0:
268 case 1:
270 case 2:
272 case 3:
274 case 4:
276 case 5:
278 case 6:
280 default:
282 }
283}
284
285bool QgsRandomUniformRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
286{
287 mRandomUpperBound = parameterAsDouble( parameters, QStringLiteral( "UPPER_BOUND" ), context );
288 mRandomLowerBound = parameterAsDouble( parameters, QStringLiteral( "LOWER_BOUND" ), context );
289
290 if ( mRandomLowerBound > mRandomUpperBound )
291 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." ) );
292
293 const int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
294 const Qgis::DataType rasterDataType = getRasterDataType( typeId );
295
296 switch ( rasterDataType )
297 {
299 if ( mRandomLowerBound < std::numeric_limits<quint8>::min() || mRandomUpperBound > std::numeric_limits<quint8>::max() )
300 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" ) ) );
301 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
302 {
303 //if parameters unset (=both are 0 or equal) --> use the whole value range
304 mRandomUpperBound = std::numeric_limits<quint8>::max();
305 mRandomLowerBound = std::numeric_limits<quint8>::min();
306 }
307 break;
309 if ( mRandomLowerBound < std::numeric_limits<qint8>::min() || mRandomUpperBound > std::numeric_limits<qint8>::max() )
310 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<qint8>::min() ).arg( std::numeric_limits<qint8>::max() ).arg( QLatin1String( "Int8" ) ) );
311 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
312 {
313 //if parameters unset (=both are 0 or equal) --> use the whole value range
314 mRandomUpperBound = std::numeric_limits<qint8>::max();
315 mRandomLowerBound = std::numeric_limits<qint8>::min();
316 }
317 break;
319 if ( mRandomLowerBound < std::numeric_limits<qint16>::min() || mRandomUpperBound > std::numeric_limits<qint16>::max() )
320 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" ) ) );
321 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
322 {
323 mRandomUpperBound = std::numeric_limits<qint16>::max();
324 mRandomLowerBound = std::numeric_limits<qint16>::min();
325 }
326 break;
328 if ( mRandomLowerBound < std::numeric_limits<quint16>::min() || mRandomUpperBound > std::numeric_limits<quint16>::max() )
329 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" ) ) );
330 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
331 {
332 mRandomUpperBound = std::numeric_limits<quint16>::max();
333 mRandomLowerBound = std::numeric_limits<quint16>::min();
334 }
335 break;
337 if ( mRandomLowerBound < std::numeric_limits<qint32>::min() || mRandomUpperBound > std::numeric_limits<qint32>::max() )
338 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" ) ) );
339 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
340 {
341 mRandomUpperBound = std::numeric_limits<qint32>::max();
342 mRandomLowerBound = std::numeric_limits<qint32>::min();
343 }
344 break;
346 if ( mRandomLowerBound < std::numeric_limits<quint32>::min() || mRandomUpperBound > std::numeric_limits<quint32>::max() )
347 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" ) ) );
348 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
349 {
350 mRandomUpperBound = std::numeric_limits<quint32>::max();
351 mRandomLowerBound = std::numeric_limits<quint32>::min();
352 }
353 break;
355 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
356 {
357 mRandomUpperBound = std::numeric_limits<float>::max();
358 mRandomLowerBound = std::numeric_limits<float>::min();
359 }
360 break;
362 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
363 {
364 mRandomUpperBound = std::numeric_limits<double>::max();
365 mRandomLowerBound = std::numeric_limits<double>::min();
366 }
367 break;
375 break;
376 }
377
378 mRandomUniformIntDistribution = std::uniform_int_distribution<long>( mRandomLowerBound, mRandomUpperBound );
379 mRandomUniformDoubleDistribution = std::uniform_real_distribution<double>( mRandomLowerBound, mRandomUpperBound );
380
381 return true;
382}
383
384long QgsRandomUniformRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
385{
386 return mRandomUniformIntDistribution( mersenneTwister );
387}
388
389double QgsRandomUniformRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
390{
391 return mRandomUniformDoubleDistribution( mersenneTwister );
392}
393
394//
395// QgsRandomBinomialRasterAlgorithm
396//
397QString QgsRandomBinomialRasterAlgorithm::name() const
398{
399 return QStringLiteral( "createrandombinomialrasterlayer" );
400}
401
402QString QgsRandomBinomialRasterAlgorithm::displayName() const
403{
404 return QObject::tr( "Create random raster layer (binomial distribution)" );
405}
406
407QStringList QgsRandomBinomialRasterAlgorithm::tags() const
408{
409 return QObject::tr( "raster,create,binomial,random" ).split( ',' );
410}
411
412QString QgsRandomBinomialRasterAlgorithm::shortHelpString() const
413{
414 return QObject::tr( "Generates a raster layer for given extent and cell size "
415 "filled with binomially distributed random values.\n"
416 "By default, the values will be chosen given an N of 10 and a probability of 0.5. "
417 "This can be overridden by using the advanced parameter for N and probability. "
418 "The raster data type is set to Integer types (Integer16 by default). "
419 "The binomial distribution random values are defined as positive integer numbers. "
420 "A floating point raster will represent a cast of integer values "
421 "to floating point." );
422}
423
424QgsRandomBinomialRasterAlgorithm *QgsRandomBinomialRasterAlgorithm::createInstance() const
425{
426 return new QgsRandomBinomialRasterAlgorithm();
427}
428
429
430void QgsRandomBinomialRasterAlgorithm::addAlgorithmParams( )
431{
432 QStringList rasterDataTypes = QStringList();
433 rasterDataTypes << QStringLiteral( "Integer16" )
434 << QStringLiteral( "Unsigned Integer16" )
435 << QStringLiteral( "Integer32" )
436 << QStringLiteral( "Unsigned Integer32" )
437 << QStringLiteral( "Float32" )
438 << QStringLiteral( "Float64" );
439
440 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
441 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
442 addParameter( rasterTypeParameter.release() );
443
444 std::unique_ptr< QgsProcessingParameterNumber > nParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "N" ), QStringLiteral( "N" ), Qgis::ProcessingNumberParameterType::Integer, 10, true, 0 );
445 nParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
446 addParameter( nParameter.release() );
447
448 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), Qgis::ProcessingNumberParameterType::Double, 0.5, true, 0 );
449 probabilityParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
450 addParameter( probabilityParameter.release() );
451}
452
453Qgis::DataType QgsRandomBinomialRasterAlgorithm::getRasterDataType( int typeId )
454{
455 switch ( typeId )
456 {
457 case 0:
459 case 1:
461 case 2:
463 case 3:
465 case 4:
467 case 5:
469 default:
471 }
472}
473
474bool QgsRandomBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
475{
476 const int n = parameterAsInt( parameters, QStringLiteral( "N" ), context );
477 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
478 mRandombinomialDistribution = std::binomial_distribution<long>( n, probability );
479 return true;
480}
481
482long QgsRandomBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
483{
484 return mRandombinomialDistribution( mersenneTwister );
485}
486
487double QgsRandomBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
488{
489 return static_cast<double>( mRandombinomialDistribution( mersenneTwister ) );
490}
491
492//
493// QgsRandomExponentialRasterAlgorithm
494//
495QString QgsRandomExponentialRasterAlgorithm::name() const
496{
497 return QStringLiteral( "createrandomexponentialrasterlayer" );
498}
499
500QString QgsRandomExponentialRasterAlgorithm::displayName() const
501{
502 return QObject::tr( "Create random raster layer (exponential distribution)" );
503}
504
505QStringList QgsRandomExponentialRasterAlgorithm::tags() const
506{
507 return QObject::tr( "raster,create,random,exponential" ).split( ',' );
508}
509
510QString QgsRandomExponentialRasterAlgorithm::shortHelpString() const
511{
512 return QObject::tr( "Generates a raster layer for given extent and cell size "
513 "filled with exponentially distributed random values.\n"
514 "By default, the values will be chosen given a lambda of 1.0. "
515 "This can be overridden by using the advanced parameter for lambda. "
516 "The raster data type is set to Float32 by default as "
517 "the exponential distribution random values are floating point numbers." );
518}
519
520QgsRandomExponentialRasterAlgorithm *QgsRandomExponentialRasterAlgorithm::createInstance() const
521{
522 return new QgsRandomExponentialRasterAlgorithm();
523}
524
525
526void QgsRandomExponentialRasterAlgorithm::addAlgorithmParams()
527{
528 QStringList rasterDataTypes = QStringList();
529 rasterDataTypes << QStringLiteral( "Float32" )
530 << QStringLiteral( "Float64" );
531
532 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
533 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
534 addParameter( rasterTypeParameter.release() );
535
536 std::unique_ptr< QgsProcessingParameterNumber > lambdaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LAMBDA" ), QStringLiteral( "Lambda" ), Qgis::ProcessingNumberParameterType::Double, 1.0, true, 0.000001 );
537 lambdaParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
538 addParameter( lambdaParameter.release() );
539}
540
541Qgis::DataType QgsRandomExponentialRasterAlgorithm::getRasterDataType( int typeId )
542{
543 switch ( typeId )
544 {
545 case 0:
547 case 1:
549 default:
551 }
552}
553
554bool QgsRandomExponentialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
555{
556 const double lambda = parameterAsDouble( parameters, QStringLiteral( "LAMBDA" ), context );
557 mRandomExponentialDistribution = std::exponential_distribution<double>( lambda );
558 return true;
559}
560
561long QgsRandomExponentialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
562{
563 return static_cast<long>( mRandomExponentialDistribution( mersenneTwister ) );
564}
565
566double QgsRandomExponentialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
567{
568 return mRandomExponentialDistribution( mersenneTwister );
569}
570
571//
572// QgsRandomGammaRasterAlgorithm
573//
574QString QgsRandomGammaRasterAlgorithm::name() const
575{
576 return QStringLiteral( "createrandomgammarasterlayer" );
577}
578
579QString QgsRandomGammaRasterAlgorithm::displayName() const
580{
581 return QObject::tr( "Create random raster layer (gamma distribution)" );
582}
583
584QStringList QgsRandomGammaRasterAlgorithm::tags() const
585{
586 return QObject::tr( "raster,create,random,gamma" ).split( ',' );
587}
588
589QString QgsRandomGammaRasterAlgorithm::shortHelpString() const
590{
591 return QObject::tr( "Generates a raster layer for given extent and cell size "
592 "filled with gamma distributed random values.\n"
593 "By default, the values will be chosen given an alpha and beta value of 1.0. "
594 "This can be overridden by using the advanced parameter for alpha and beta. "
595 "The raster data type is set to Float32 by default as "
596 "the gamma distribution random values are floating point numbers." );
597}
598
599QgsRandomGammaRasterAlgorithm *QgsRandomGammaRasterAlgorithm::createInstance() const
600{
601 return new QgsRandomGammaRasterAlgorithm();
602}
603
604
605void QgsRandomGammaRasterAlgorithm::addAlgorithmParams()
606{
607 QStringList rasterDataTypes = QStringList();
608 rasterDataTypes << QStringLiteral( "Float32" )
609 << QStringLiteral( "Float64" );
610
611 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
612 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
613 addParameter( rasterTypeParameter.release() );
614
615 std::unique_ptr< QgsProcessingParameterNumber > alphaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ALPHA" ), QStringLiteral( "Alpha" ), Qgis::ProcessingNumberParameterType::Double, 1.0, true, 0.000001 );
616 alphaParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
617 addParameter( alphaParameter.release() );
618
619 std::unique_ptr< QgsProcessingParameterNumber > betaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "BETA" ), QStringLiteral( "Beta" ), Qgis::ProcessingNumberParameterType::Double, 1.0, true, 0.000001 );
620 betaParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
621 addParameter( betaParameter.release() );
622}
623
624Qgis::DataType QgsRandomGammaRasterAlgorithm::getRasterDataType( int typeId )
625{
626 switch ( typeId )
627 {
628 case 0:
630 case 1:
632 default:
634 }
635}
636
637bool QgsRandomGammaRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
638{
639 const double alpha = parameterAsDouble( parameters, QStringLiteral( "ALPHA" ), context );
640 const double beta = parameterAsDouble( parameters, QStringLiteral( "BETA" ), context );
641 mRandomGammaDistribution = std::gamma_distribution<double>( alpha, beta );
642 return true;
643}
644
645long QgsRandomGammaRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
646{
647 return static_cast<long>( mRandomGammaDistribution( mersenneTwister ) );
648}
649
650double QgsRandomGammaRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
651{
652 return mRandomGammaDistribution( mersenneTwister );
653}
654
655//
656// QgsRandomGeometricRasterAlgorithm
657//
658QString QgsRandomGeometricRasterAlgorithm::name() const
659{
660 return QStringLiteral( "createrandomgeometricrasterlayer" );
661}
662
663QString QgsRandomGeometricRasterAlgorithm::displayName() const
664{
665 return QObject::tr( "Create random raster layer (geometric distribution)" );
666}
667
668QStringList QgsRandomGeometricRasterAlgorithm::tags() const
669{
670 return QObject::tr( "raster,create,random,geometric" ).split( ',' );
671}
672
673QString QgsRandomGeometricRasterAlgorithm::shortHelpString() const
674{
675 return QObject::tr( "Generates a raster layer for given extent and cell size "
676 "filled with geometrically distributed random values.\n"
677 "By default, the values will be chosen given a probability of 0.5. "
678 "This can be overridden by using the advanced parameter for mean "
679 "value. The raster data type is set to Integer types (Integer16 by default). "
680 "The geometric distribution random values are defined as positive integer numbers. "
681 "A floating point raster will represent a cast of "
682 "integer values to floating point." );
683}
684
685QgsRandomGeometricRasterAlgorithm *QgsRandomGeometricRasterAlgorithm::createInstance() const
686{
687 return new QgsRandomGeometricRasterAlgorithm();
688}
689
690
691void QgsRandomGeometricRasterAlgorithm::addAlgorithmParams()
692{
693 QStringList rasterDataTypes = QStringList();
694 rasterDataTypes << QStringLiteral( "Integer16" )
695 << QStringLiteral( "Unsigned Integer16" )
696 << QStringLiteral( "Integer32" )
697 << QStringLiteral( "Unsigned Integer32" )
698 << QStringLiteral( "Float32" )
699 << QStringLiteral( "Float64" );
700
701 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
702 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
703 addParameter( rasterTypeParameter.release() );
704
705 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), Qgis::ProcessingNumberParameterType::Double, 0.5, true, 0.00001 );
706 probabilityParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
707 addParameter( probabilityParameter.release() );
708}
709
710Qgis::DataType QgsRandomGeometricRasterAlgorithm::getRasterDataType( int typeId )
711{
712 switch ( typeId )
713 {
714 case 0:
716 case 1:
718 case 2:
720 case 3:
722 case 4:
724 case 5:
726 default:
728 }
729}
730
731bool QgsRandomGeometricRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
732{
733 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
734 mRandomGeometricDistribution = std::geometric_distribution<long>( probability );
735 return true;
736}
737
738long QgsRandomGeometricRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
739{
740 return mRandomGeometricDistribution( mersenneTwister );
741}
742
743double QgsRandomGeometricRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
744{
745 return static_cast<double>( mRandomGeometricDistribution( mersenneTwister ) );
746}
747
748//
749// QgsRandomNegativeBinomialRasterAlgorithm
750//
751QString QgsRandomNegativeBinomialRasterAlgorithm::name() const
752{
753 return QStringLiteral( "createrandomnegativebinomialrasterlayer" );
754}
755
756QString QgsRandomNegativeBinomialRasterAlgorithm::displayName() const
757{
758 return QObject::tr( "Create random raster layer (negative binomial distribution)" );
759}
760
761QStringList QgsRandomNegativeBinomialRasterAlgorithm::tags() const
762{
763 return QObject::tr( "raster,create,random,negative,binomial,negative-binomial" ).split( ',' );
764}
765
766QString QgsRandomNegativeBinomialRasterAlgorithm::shortHelpString() const
767{
768 return QObject::tr( "Generates a raster layer for given extent and cell size "
769 "filled with negative binomially distributed random values.\n"
770 "By default, the values will be chosen given a distribution parameter k of 10.0 "
771 "and a probability of 0.5. "
772 "This can be overridden by using the advanced parameters for k and probability. "
773 "The raster data type is set to Integer types (Integer 16 by default). "
774 "The negative binomial distribution random values are defined as positive integer numbers. "
775 "A floating point raster will represent a cast of "
776 "integer values to floating point." );
777}
778
779QgsRandomNegativeBinomialRasterAlgorithm *QgsRandomNegativeBinomialRasterAlgorithm::createInstance() const
780{
781 return new QgsRandomNegativeBinomialRasterAlgorithm();
782}
783
784
785void QgsRandomNegativeBinomialRasterAlgorithm::addAlgorithmParams( )
786{
787 QStringList rasterDataTypes = QStringList();
788 rasterDataTypes << QStringLiteral( "Integer16" )
789 << QStringLiteral( "Unsigned Integer16" )
790 << QStringLiteral( "Integer32" )
791 << QStringLiteral( "Unsigned Integer32" )
792 << QStringLiteral( "Float32" )
793 << QStringLiteral( "Float64" );
794
795 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
796 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
797 addParameter( rasterTypeParameter.release() );
798
799 std::unique_ptr< QgsProcessingParameterNumber > kParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "K_PARAMETER" ), QStringLiteral( "Distribution parameter k" ), Qgis::ProcessingNumberParameterType::Integer, 10, true, 0.00001 );
800 kParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
801 addParameter( kParameter.release() );
802
803 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), Qgis::ProcessingNumberParameterType::Double, 0.5, true, 0.00001 );
804 probabilityParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
805 addParameter( probabilityParameter.release() );
806}
807
808Qgis::DataType QgsRandomNegativeBinomialRasterAlgorithm::getRasterDataType( int typeId )
809{
810 switch ( typeId )
811 {
812 case 0:
814 case 1:
816 case 2:
818 case 3:
820 case 4:
822 case 5:
824 default:
826 }
827}
828
829bool QgsRandomNegativeBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
830{
831 const int k = parameterAsInt( parameters, QStringLiteral( "K_PARAMETER" ), context );
832 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
833 mRandomNegativeBinomialDistribution = std::negative_binomial_distribution<long>( k, probability );
834 return true;
835}
836
837long QgsRandomNegativeBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
838{
839 return mRandomNegativeBinomialDistribution( mersenneTwister );
840}
841
842double QgsRandomNegativeBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
843{
844 return static_cast<double>( mRandomNegativeBinomialDistribution( mersenneTwister ) );
845}
846
847//
848// QgsRandomNormalRasterAlgorithm
849//
850QString QgsRandomNormalRasterAlgorithm::name() const
851{
852 return QStringLiteral( "createrandomnormalrasterlayer" );
853}
854
855QString QgsRandomNormalRasterAlgorithm::displayName() const
856{
857 return QObject::tr( "Create random raster layer (normal distribution)" );
858}
859
860QStringList QgsRandomNormalRasterAlgorithm::tags() const
861{
862 return QObject::tr( "raster,create,normal,distribution,random" ).split( ',' );
863}
864
865QString QgsRandomNormalRasterAlgorithm::shortHelpString() const
866{
867 return QObject::tr( "Generates a raster layer for given extent and cell size "
868 "filled with normally distributed random values.\n"
869 "By default, the values will be chosen given a mean of 0.0 and "
870 "a standard deviation of 1.0. This can be overridden by "
871 "using the advanced parameters for mean and standard deviation "
872 "value. The raster data type is set to Float32 by default "
873 "as the normal distribution random values are floating point numbers." );
874}
875
876QgsRandomNormalRasterAlgorithm *QgsRandomNormalRasterAlgorithm::createInstance() const
877{
878 return new QgsRandomNormalRasterAlgorithm();
879}
880
881void QgsRandomNormalRasterAlgorithm::addAlgorithmParams()
882{
883 QStringList rasterDataTypes = QStringList();
884 rasterDataTypes << QStringLiteral( "Float32" )
885 << QStringLiteral( "Float64" );
886
887 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
888 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
889 addParameter( rasterTypeParameter.release() );
890
891 std::unique_ptr< QgsProcessingParameterNumber > meanParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean of normal distribution" ), Qgis::ProcessingNumberParameterType::Double, 0, true );
892 meanParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
893 addParameter( meanParameter.release() );
894
895 std::unique_ptr< QgsProcessingParameterNumber > stdevParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "STDDEV" ), QStringLiteral( "Standard deviation of normal distribution" ), Qgis::ProcessingNumberParameterType::Double, 1, true, 0 );
896 stdevParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
897 addParameter( stdevParameter.release() );
898}
899
900Qgis::DataType QgsRandomNormalRasterAlgorithm::getRasterDataType( int typeId )
901{
902 switch ( typeId )
903 {
904 case 0:
906 case 1:
908 default:
910 }
911}
912
913bool QgsRandomNormalRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
914{
915 const double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
916 const double stddev = parameterAsDouble( parameters, QStringLiteral( "STDDEV" ), context );
917 mRandomNormalDistribution = std::normal_distribution<double>( mean, stddev );
918 return true;
919}
920
921long QgsRandomNormalRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
922{
923 return static_cast<long>( mRandomNormalDistribution( mersenneTwister ) );
924}
925
926double QgsRandomNormalRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
927{
928 return mRandomNormalDistribution( mersenneTwister );
929}
930
931//
932// QgsRandomPoissonRasterAlgorithm
933//
934QString QgsRandomPoissonRasterAlgorithm::name() const
935{
936 return QStringLiteral( "createrandompoissonrasterlayer" );
937}
938
939QString QgsRandomPoissonRasterAlgorithm::displayName() const
940{
941 return QObject::tr( "Create random raster layer (poisson distribution)" );
942}
943
944QStringList QgsRandomPoissonRasterAlgorithm::tags() const
945{
946 return QObject::tr( "raster,create,random,poisson" ).split( ',' );
947}
948
949QString QgsRandomPoissonRasterAlgorithm::shortHelpString() const
950{
951 return QObject::tr( "Generates a raster layer for given extent and cell size "
952 "filled with poisson distributed random values.\n"
953 "By default, the values will be chosen given a mean of 1.0. "
954 "This can be overridden by using the advanced parameter for mean "
955 "value. The raster data type is set to Integer types (Integer16 by default). "
956 "The poisson distribution random values are positive integer numbers. "
957 "A floating point raster will represent a cast of integer values to floating point." );
958}
959
960QgsRandomPoissonRasterAlgorithm *QgsRandomPoissonRasterAlgorithm::createInstance() const
961{
962 return new QgsRandomPoissonRasterAlgorithm();
963}
964
965
966void QgsRandomPoissonRasterAlgorithm::addAlgorithmParams()
967{
968 QStringList rasterDataTypes = QStringList();
969 rasterDataTypes << QStringLiteral( "Integer16" )
970 << QStringLiteral( "Unsigned Integer16" )
971 << QStringLiteral( "Integer32" )
972 << QStringLiteral( "Unsigned Integer32" )
973 << QStringLiteral( "Float32" )
974 << QStringLiteral( "Float64" );
975
976 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
977 rasterTypeParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
978 addParameter( rasterTypeParameter.release() );
979
980 std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean" ), Qgis::ProcessingNumberParameterType::Double, 1.0, true, 0 );
981 upperBoundParameter->setFlags( Qgis::ProcessingParameterFlag::Advanced );
982 addParameter( upperBoundParameter.release() );
983}
984
985Qgis::DataType QgsRandomPoissonRasterAlgorithm::getRasterDataType( int typeId )
986{
987 switch ( typeId )
988 {
989 case 0:
991 case 1:
993 case 2:
995 case 3:
997 case 4:
999 case 5:
1001 default:
1003 }
1004}
1005
1006bool QgsRandomPoissonRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
1007{
1008 const double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
1009 mRandomPoissonDistribution = std::poisson_distribution<long>( mean );
1010 return true;
1011}
1012
1013long QgsRandomPoissonRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
1014{
1015 return mRandomPoissonDistribution( mersenneTwister );
1016}
1017
1018double QgsRandomPoissonRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
1019{
1020 return static_cast<double>( mRandomPoissonDistribution( mersenneTwister ) );
1021}
1022
DataType
Raster data types.
Definition: qgis.h:269
@ CInt32
Complex Int32.
@ Float32
Thirty two bit floating point (float)
@ CFloat64
Complex Float64.
@ Int16
Sixteen bit signed integer (qint16)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30)
@ UInt16
Sixteen bit unsigned integer (quint16)
@ Byte
Eight bit unsigned integer (quint8)
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Int32
Thirty two bit signed integer (qint32)
@ Float64
Sixty four bit floating point (double)
@ CFloat32
Complex Float32.
@ CInt16
Complex Int16.
@ UInt32
Thirty two bit unsigned integer (quint32)
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:61
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.
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)
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:5207