QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsprocessingparameters.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingparameters.cpp
3 ---------------------------
4 begin : April 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson 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
21#include "qgsprocessingutils.h"
24#include "qgsvectorfilewriter.h"
28#include "qgsrasterfilewriter.h"
29#include "qgsvectorlayer.h"
30#include "qgsmeshlayer.h"
31#include "qgspointcloudlayer.h"
32#include "qgsannotationlayer.h"
33#include "qgsapplication.h"
34#include "qgslayoutmanager.h"
35#include "qgsprintlayout.h"
36#include "qgssymbollayerutils.h"
37#include "qgsfileutils.h"
38#include "qgsproviderregistry.h"
39#include "qgsvariantutils.h"
40#include <functional>
41#include <QRegularExpression>
42
43
45{
46 QVariantMap map;
47 map.insert( QStringLiteral( "source" ), source.toVariant() );
48 map.insert( QStringLiteral( "selected_only" ), selectedFeaturesOnly );
49 map.insert( QStringLiteral( "feature_limit" ), featureLimit );
50 map.insert( QStringLiteral( "flags" ), static_cast< int >( flags ) );
51 map.insert( QStringLiteral( "geometry_check" ), static_cast< int >( geometryCheck ) );
52 return map;
53}
54
56{
57 source.loadVariant( map.value( QStringLiteral( "source" ) ) );
58 selectedFeaturesOnly = map.value( QStringLiteral( "selected_only" ), false ).toBool();
59 featureLimit = map.value( QStringLiteral( "feature_limit" ), -1 ).toLongLong();
60 flags = static_cast< Flags >( map.value( QStringLiteral( "flags" ), 0 ).toInt() );
61 geometryCheck = static_cast< QgsFeatureRequest::InvalidGeometryCheck >( map.value( QStringLiteral( "geometry_check" ), QgsFeatureRequest::GeometryAbortOnInvalid ).toInt() );
62 return true;
63}
64
65
66//
67// QgsProcessingOutputLayerDefinition
68//
69
71{
72 mUseRemapping = true;
73 mRemappingDefinition = definition;
74}
75
77{
78 QVariantMap map;
79 map.insert( QStringLiteral( "sink" ), sink.toVariant() );
80 map.insert( QStringLiteral( "create_options" ), createOptions );
81 if ( mUseRemapping )
82 map.insert( QStringLiteral( "remapping" ), QVariant::fromValue( mRemappingDefinition ) );
83 return map;
84}
85
87{
88 sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
89 createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
90 if ( map.contains( QStringLiteral( "remapping" ) ) )
91 {
92 mUseRemapping = true;
93 mRemappingDefinition = map.value( QStringLiteral( "remapping" ) ).value< QgsRemappingSinkDefinition >();
94 }
95 else
96 {
97 mUseRemapping = false;
98 }
99 return true;
100}
101
103{
105 && mUseRemapping == other.mUseRemapping && mRemappingDefinition == other.mRemappingDefinition;
106}
107
109{
110 return !( *this == other );
111}
112
113bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
114{
115 const QVariant val = parameters.value( name );
116 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
117 return val.value< QgsProperty >().propertyType() != QgsProperty::StaticProperty;
118 else
119 return false;
120}
121
122QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
123{
124 if ( !definition )
125 return QString();
126
127 return parameterAsString( definition, parameters.value( definition->name() ), context );
128}
129
130QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
131{
132 if ( !definition )
133 return QString();
134
135 QVariant val = value;
136 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
137 return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
138
139 if ( !val.isValid() )
140 {
141 // fall back to default
142 val = definition->defaultValue();
143 }
144
146 {
147 if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
148 return destParam->generateTemporaryDestination();
149 }
150
151 return val.toString();
152}
153
154QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
155{
156 if ( !definition )
157 return QString();
158
159 return parameterAsExpression( definition, parameters.value( definition->name() ), context );
160}
161
162QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
163{
164 if ( !definition )
165 return QString();
166
167 const QVariant val = value;
168 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
169 return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
170
171 if ( val.isValid() && !val.toString().isEmpty() )
172 {
173 const QgsExpression e( val.toString() );
174 if ( e.isValid() )
175 return val.toString();
176 }
177
178 // fall back to default
179 return definition->defaultValue().toString();
180}
181
182double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
183{
184 if ( !definition )
185 return 0;
186
187 return parameterAsDouble( definition, parameters.value( definition->name() ), context );
188}
189
190double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
191{
192 if ( !definition )
193 return 0;
194
195 QVariant val = value;
196 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
197 return val.value< QgsProperty >().valueAsDouble( context.expressionContext(), definition->defaultValue().toDouble() );
198
199 bool ok = false;
200 const double res = val.toDouble( &ok );
201 if ( ok )
202 return res;
203
204 // fall back to default
205 val = definition->defaultValue();
206 return val.toDouble();
207}
208
209int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
210{
211 if ( !definition )
212 return 0;
213
214 return parameterAsInt( definition, parameters.value( definition->name() ), context );
215}
216
217int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
218{
219 if ( !definition )
220 return 0;
221
222 QVariant val = value;
223 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
224 return val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
225
226 bool ok = false;
227 double dbl = val.toDouble( &ok );
228 if ( !ok )
229 {
230 // fall back to default
231 val = definition->defaultValue();
232 dbl = val.toDouble( &ok );
233 }
234
235 //String representations of doubles in QVariant will not convert to int
236 //work around this by first converting to double, and then checking whether the double is convertible to int
237 if ( ok )
238 {
239 const double round = std::round( dbl );
240 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
241 {
242 //double too large to fit in int
243 return 0;
244 }
245 return static_cast< int >( std::round( dbl ) );
246 }
247
248 return val.toInt();
249}
250
251QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
252{
253 if ( !definition )
254 return QList< int >();
255
256 return parameterAsInts( definition, parameters.value( definition->name() ), context );
257}
258
259QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
260{
261 if ( !definition )
262 return QList< int >();
263
264 QList< int > resultList;
265 const QVariant val = value;
266 if ( val.isValid() )
267 {
268 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
269 resultList << val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
270 else if ( val.type() == QVariant::List )
271 {
272 const QVariantList list = val.toList();
273 for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
274 resultList << it->toInt();
275 }
276 else
277 {
278 const QStringList parts = val.toString().split( ';' );
279 for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
280 resultList << it->toInt();
281 }
282 }
283
284 if ( resultList.isEmpty() )
285 {
286 // check default
287 if ( definition->defaultValue().isValid() )
288 {
289 if ( definition->defaultValue().type() == QVariant::List )
290 {
291 const QVariantList list = definition->defaultValue().toList();
292 for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
293 resultList << it->toInt();
294 }
295 else
296 {
297 const QStringList parts = definition->defaultValue().toString().split( ';' );
298 for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
299 resultList << it->toInt();
300 }
301 }
302 }
303
304 return resultList;
305}
306
307QDateTime QgsProcessingParameters::parameterAsDateTime( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
308{
309 if ( !definition )
310 return QDateTime();
311
312 return parameterAsDateTime( definition, parameters.value( definition->name() ), context );
313}
314
315QDateTime QgsProcessingParameters::parameterAsDateTime( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
316{
317 if ( !definition )
318 return QDateTime();
319
320 QVariant val = value;
321 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
322 val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
323
324 QDateTime d = val.toDateTime();
325 if ( !d.isValid() && val.type() == QVariant::String )
326 {
327 d = QDateTime::fromString( val.toString() );
328 }
329
330 if ( !d.isValid() )
331 {
332 // fall back to default
333 val = definition->defaultValue();
334 d = val.toDateTime();
335 }
336 if ( !d.isValid() && val.type() == QVariant::String )
337 {
338 d = QDateTime::fromString( val.toString() );
339 }
340
341 return d;
342}
343
344QDate QgsProcessingParameters::parameterAsDate( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
345{
346 if ( !definition )
347 return QDate();
348
349 return parameterAsDate( definition, parameters.value( definition->name() ), context );
350}
351
352QDate QgsProcessingParameters::parameterAsDate( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
353{
354 if ( !definition )
355 return QDate();
356
357 QVariant val = value;
358 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
359 val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
360
361 QDate d = val.toDate();
362 if ( !d.isValid() && val.type() == QVariant::String )
363 {
364 d = QDate::fromString( val.toString() );
365 }
366
367 if ( !d.isValid() )
368 {
369 // fall back to default
370 val = definition->defaultValue();
371 d = val.toDate();
372 }
373 if ( !d.isValid() && val.type() == QVariant::String )
374 {
375 d = QDate::fromString( val.toString() );
376 }
377
378 return d;
379}
380
381QTime QgsProcessingParameters::parameterAsTime( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
382{
383 if ( !definition )
384 return QTime();
385
386 return parameterAsTime( definition, parameters.value( definition->name() ), context );
387}
388
389QTime QgsProcessingParameters::parameterAsTime( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
390{
391 if ( !definition )
392 return QTime();
393
394 QVariant val = value;
395 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
396 val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
397
398 QTime d;
399
400 if ( val.type() == QVariant::DateTime )
401 d = val.toDateTime().time();
402 else
403 d = val.toTime();
404
405 if ( !d.isValid() && val.type() == QVariant::String )
406 {
407 d = QTime::fromString( val.toString() );
408 }
409
410 if ( !d.isValid() )
411 {
412 // fall back to default
413 val = definition->defaultValue();
414 d = val.toTime();
415 }
416 if ( !d.isValid() && val.type() == QVariant::String )
417 {
418 d = QTime::fromString( val.toString() );
419 }
420
421 return d;
422}
423
424int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
425{
426 if ( !definition )
427 return 0;
428
429 return parameterAsEnum( definition, parameters.value( definition->name() ), context );
430}
431
432int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
433{
434 if ( !definition )
435 return 0;
436
437 const int val = parameterAsInt( definition, value, context );
438 const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
439 if ( enumDef && val >= enumDef->options().size() )
440 {
441 return enumDef->defaultValue().toInt();
442 }
443 return val;
444}
445
446QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
447{
448 if ( !definition )
449 return QList<int>();
450
451 return parameterAsEnums( definition, parameters.value( definition->name() ), context );
452}
453
454QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
455{
456 if ( !definition )
457 return QList<int>();
458
459 QVariantList resultList;
460 const QVariant val = value;
461 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
462 resultList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
463 else if ( val.type() == QVariant::List )
464 {
465 const auto constToList = val.toList();
466 for ( const QVariant &var : constToList )
467 resultList << var;
468 }
469 else if ( val.type() == QVariant::String )
470 {
471 const auto constSplit = val.toString().split( ',' );
472 for ( const QString &var : constSplit )
473 resultList << var;
474 }
475 else
476 resultList << val;
477
478 if ( resultList.isEmpty() )
479 return QList< int >();
480
481 if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
482 {
483 resultList.clear();
484 // check default
485 if ( definition->defaultValue().type() == QVariant::List )
486 {
487 const auto constToList = definition->defaultValue().toList();
488 for ( const QVariant &var : constToList )
489 resultList << var;
490 }
491 else if ( definition->defaultValue().type() == QVariant::String )
492 {
493 const auto constSplit = definition->defaultValue().toString().split( ',' );
494 for ( const QString &var : constSplit )
495 resultList << var;
496 }
497 else
498 resultList << definition->defaultValue();
499 }
500
501 QList< int > result;
502 const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
503 const auto constResultList = resultList;
504 for ( const QVariant &var : constResultList )
505 {
506 const int resInt = var.toInt();
507 if ( !enumDef || resInt < enumDef->options().size() )
508 {
509 result << resInt;
510 }
511 }
512 return result;
513}
514
515QString QgsProcessingParameters::parameterAsEnumString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
516{
517 if ( !definition )
518 return QString();
519
520 return parameterAsEnumString( definition, parameters.value( definition->name() ), context );
521}
522
523QString QgsProcessingParameters::parameterAsEnumString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
524{
525 if ( !definition )
526 return QString();
527
528 QString enumText = parameterAsString( definition, value, context );
529 const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
530 if ( enumText.isEmpty() || !enumDef->options().contains( enumText ) )
531 enumText = definition->defaultValue().toString();
532
533 return enumText;
534}
535
536QStringList QgsProcessingParameters::parameterAsEnumStrings( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
537{
538 if ( !definition )
539 return QStringList();
540
541 return parameterAsEnumStrings( definition, parameters.value( definition->name() ), context );
542}
543
544QStringList QgsProcessingParameters::parameterAsEnumStrings( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
545{
546 if ( !definition )
547 return QStringList();
548
549 const QVariant val = value;
550
551 QStringList enumValues;
552
553 std::function< void( const QVariant &var ) > processVariant;
554 processVariant = [ &enumValues, &context, &definition, &processVariant ]( const QVariant & var )
555 {
556 if ( var.type() == QVariant::List )
557 {
558 const auto constToList = var.toList();
559 for ( const QVariant &listVar : constToList )
560 {
561 processVariant( listVar );
562 }
563 }
564 else if ( var.type() == QVariant::StringList )
565 {
566 const auto constToStringList = var.toStringList();
567 for ( const QString &s : constToStringList )
568 {
569 processVariant( s );
570 }
571 }
572 else if ( var.userType() == QMetaType::type( "QgsProperty" ) )
573 processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
574 else
575 {
576 const QStringList parts = var.toString().split( ',' );
577 for ( const QString &s : parts )
578 {
579 enumValues << s;
580 }
581 }
582 };
583
584 processVariant( val );
585
586 const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
587 // check that values are valid enum values. The resulting set will be empty
588 // if all values are present in the enumDef->options(), otherwise it will contain
589 // values which are invalid
590 const QStringList options = enumDef->options();
591 const QSet<QString> subtraction = QSet<QString>( enumValues.begin(), enumValues.end() ).subtract( QSet<QString>( options.begin(), options.end() ) );
592
593 if ( enumValues.isEmpty() || !subtraction.isEmpty() )
594 {
595 enumValues.clear();
596 processVariant( definition->defaultValue() );
597 }
598
599 return enumValues;
600}
601
602bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
603{
604 if ( !definition )
605 return false;
606
607 return parameterAsBool( definition, parameters.value( definition->name() ), context );
608}
609
610bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
611{
612 if ( !definition )
613 return false;
614
615 return parameterAsBoolean( definition, parameters.value( definition->name() ), context );
616}
617
618bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
619{
620 if ( !definition )
621 return false;
622
623 const QVariant def = definition->defaultValue();
624
625 const QVariant val = value;
626 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
627 return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
628 else if ( val.isValid() )
629 return val.toBool();
630 else
631 return def.toBool();
632}
633
634bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
635{
636 if ( !definition )
637 return false;
638
639 const QVariant def = definition->defaultValue();
640
641 const QVariant val = value;
642 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
643 return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
644 else if ( val.isValid() )
645 return val.toBool();
646 else
647 return def.toBool();
648}
649
650QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
652 QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags,
653 const QVariantMap &createOptions, const QStringList &datasourceOptions, const QStringList &layerOptions )
654{
655 QVariant val;
656 if ( definition )
657 {
658 val = parameters.value( definition->name() );
659 }
660
661 return parameterAsSink( definition, val, fields, geometryType, crs, context, destinationIdentifier, sinkFlags, createOptions, datasourceOptions, layerOptions );
662}
663
664QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags, const QVariantMap &createOptions, const QStringList &datasourceOptions, const QStringList &layerOptions )
665{
666 QVariantMap options = createOptions;
667 QVariant val = value;
668
669 QgsProject *destinationProject = nullptr;
670 QString destName;
671 QgsRemappingSinkDefinition remapDefinition;
672 bool useRemapDefinition = false;
673 if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
674 {
675 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
676 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
677 destinationProject = fromVar.destinationProject;
678 options = fromVar.createOptions;
679
680 val = fromVar.sink;
681 destName = fromVar.destinationName;
682 if ( fromVar.useRemapping() )
683 {
684 useRemapDefinition = true;
685 remapDefinition = fromVar.remappingDefinition();
686 }
687 }
688
689 QString dest;
690 if ( definition && val.userType() == QMetaType::type( "QgsProperty" ) )
691 {
692 dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
693 }
694 else if ( !val.isValid() || val.toString().isEmpty() )
695 {
696 if ( definition && definition->flags() & QgsProcessingParameterDefinition::FlagOptional && !definition->defaultValue().isValid() )
697 {
698 // unset, optional sink, no default => no sink
699 return nullptr;
700 }
701 // fall back to default
702 if ( !definition )
703 {
704 throw QgsProcessingException( QObject::tr( "No parameter definition for the sink" ) );
705 }
706 dest = definition->defaultValue().toString();
707 }
708 else
709 {
710 dest = val.toString();
711 }
713 {
714 if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
715 dest = destParam->generateTemporaryDestination();
716 }
717
718 if ( dest.isEmpty() )
719 return nullptr;
720
721 std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, options, datasourceOptions, layerOptions, sinkFlags, useRemapDefinition ? &remapDefinition : nullptr ) );
722 destinationIdentifier = dest;
723
724 if ( destinationProject )
725 {
726 if ( destName.isEmpty() && definition )
727 {
728 destName = definition->description();
729 }
730 QString outputName;
731 if ( definition )
732 outputName = definition->name();
733 context.addLayerToLoadOnCompletion( destinationIdentifier, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, QgsProcessingUtils::LayerHint::Vector ) );
734 }
735
736 return sink.release();
737}
738
740{
741 if ( !definition )
742 return nullptr;
743
744 return parameterAsSource( definition, parameters.value( definition->name() ), context );
745}
746
748{
749 if ( !definition )
750 return nullptr;
751
752 return QgsProcessingUtils::variantToSource( value, context, definition->defaultValue() );
753}
754
755QString parameterAsCompatibleSourceLayerPathInternal( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
756{
757 if ( !definition )
758 return QString();
759
760 QVariant val = parameters.value( definition->name() );
761
762 bool selectedFeaturesOnly = false;
763 long long featureLimit = -1;
764 if ( val.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
765 {
766 // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
767 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
768 selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
769 featureLimit = fromVar.featureLimit;
770 val = fromVar.source;
771 }
772 else if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
773 {
774 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
775 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
776 val = fromVar.sink;
777 }
778
779 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
780 {
781 val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
782 }
783
784 QgsVectorLayer *vl = nullptr;
785 vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
786
787 if ( !vl )
788 {
789 QString layerRef;
790 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
791 {
792 layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
793 }
794 else if ( !val.isValid() || val.toString().isEmpty() )
795 {
796 // fall back to default
797 val = definition->defaultValue();
798
799 // default value may be a vector layer
800 vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
801 if ( !vl )
802 layerRef = definition->defaultValue().toString();
803 }
804 else
805 {
806 layerRef = val.toString();
807 }
808
809 if ( !vl )
810 {
811 if ( layerRef.isEmpty() )
812 return QString();
813
814 vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, QgsProcessingUtils::LayerHint::Vector ) );
815 }
816 }
817
818 if ( !vl )
819 return QString();
820
821 if ( layerName )
822 return QgsProcessingUtils::convertToCompatibleFormatAndLayerName( vl, selectedFeaturesOnly, definition->name(),
823 compatibleFormats, preferredFormat, context, feedback, *layerName, featureLimit );
824 else
825 return QgsProcessingUtils::convertToCompatibleFormat( vl, selectedFeaturesOnly, definition->name(),
826 compatibleFormats, preferredFormat, context, feedback, featureLimit );
827}
828
829QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback )
830{
831 return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, nullptr );
832}
833
834QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPathAndLayerName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName )
835{
836 QString *destLayer = layerName;
837 QString tmp;
838 if ( destLayer )
839 destLayer->clear();
840 else
841 destLayer = &tmp;
842
843 return parameterAsCompatibleSourceLayerPathInternal( definition, parameters, context, compatibleFormats, preferredFormat, feedback, destLayer );
844}
845
847{
848 if ( !definition )
849 return nullptr;
850
851 return parameterAsLayer( definition, parameters.value( definition->name() ), context, layerHint );
852}
853
855{
856 if ( !definition )
857 return nullptr;
858
859 QVariant val = value;
860 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
861 {
862 val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
863 }
864
865 if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
866 {
867 return layer;
868 }
869
870 if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
871 {
872 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
873 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
874 val = fromVar.sink;
875 }
876
877 if ( val.userType() == QMetaType::type( "QgsProperty" ) && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
878 {
879 val = val.value< QgsProperty >().staticValue();
880 }
881
882 if ( !val.isValid() || val.toString().isEmpty() )
883 {
884 // fall back to default
885 val = definition->defaultValue();
886 }
887
888 if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
889 {
890 return layer;
891 }
892
893 QString layerRef = val.toString();
894 if ( layerRef.isEmpty() )
895 layerRef = definition->defaultValue().toString();
896
897 if ( layerRef.isEmpty() )
898 return nullptr;
899
900 return QgsProcessingUtils::mapLayerFromString( layerRef, context, true, layerHint );
901}
902
904{
905 return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Raster ) );
906}
907
909{
910 return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Raster ) );
911}
912
914{
915 return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Mesh ) );
916}
917
919{
920 return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Mesh ) );
921}
922
923QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
924{
925 QVariant val;
926 if ( definition )
927 {
928 val = parameters.value( definition->name() );
929 }
930 return parameterAsOutputLayer( definition, val, context );
931}
932
934{
935 QVariant val = value;
936
937 QgsProject *destinationProject = nullptr;
938 QString destName;
939 if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
940 {
941 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
942 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
943 destinationProject = fromVar.destinationProject;
944 val = fromVar.sink;
945 destName = fromVar.destinationName;
946 }
947
948 QString dest;
949 if ( definition && val.userType() == QMetaType::type( "QgsProperty" ) )
950 {
951 dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
952 }
953 else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
954 {
955 // fall back to default
956 dest = definition->defaultValue().toString();
957 }
958 else
959 {
960 dest = val.toString();
961 }
963 {
964 if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
965 dest = destParam->generateTemporaryDestination();
966 }
967
968 if ( destinationProject )
969 {
970 QString outputName;
971 if ( destName.isEmpty() && definition )
972 {
973 destName = definition->description();
974 }
975 if ( definition )
976 outputName = definition->name();
977
979 if ( definition && definition->type() == QgsProcessingParameterVectorDestination::typeName() )
981 else if ( definition && definition->type() == QgsProcessingParameterRasterDestination::typeName() )
983 else if ( definition && definition->type() == QgsProcessingParameterPointCloudDestination::typeName() )
985
986 context.addLayerToLoadOnCompletion( dest, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, layerTypeHint ) );
987 }
988
989 return dest;
990}
991
992QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
993{
994 QVariant val;
995 if ( definition )
996 {
997 val = parameters.value( definition->name() );
998 }
999 return parameterAsFileOutput( definition, val, context );
1000}
1001
1003{
1004 QVariant val = value;
1005
1006 if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
1007 {
1008 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1009 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1010 val = fromVar.sink;
1011 }
1012
1013 QString dest;
1014 if ( definition && val.userType() == QMetaType::type( "QgsProperty" ) )
1015 {
1016 dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1017 }
1018 else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
1019 {
1020 // fall back to default
1021 dest = definition->defaultValue().toString();
1022 }
1023 else
1024 {
1025 dest = val.toString();
1026 }
1027 if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
1028 {
1029 if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
1030 dest = destParam->generateTemporaryDestination();
1031 }
1032 return dest;
1033}
1034
1036{
1037 return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Vector ) );
1038}
1039
1041{
1042 return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Vector ) );
1043}
1044
1046{
1047 if ( !definition )
1049
1050 return parameterAsCrs( definition, parameters.value( definition->name() ), context );
1051}
1052
1054{
1055 if ( !definition )
1057
1058 return QgsProcessingUtils::variantToCrs( value, context, definition->defaultValue() );
1059}
1060
1063{
1064 if ( !definition )
1065 return QgsRectangle();
1066
1067 return parameterAsExtent( definition, parameters.value( definition->name() ), context, crs );
1068}
1069
1071{
1072 if ( !definition )
1073 return QgsRectangle();
1074
1075 QVariant val = value;
1076
1077 if ( val.userType() == QMetaType::type( "QgsRectangle" ) )
1078 {
1079 return val.value<QgsRectangle>();
1080 }
1081 if ( val.userType() == QMetaType::type( "QgsGeometry" ) )
1082 {
1083 const QgsGeometry geom = val.value<QgsGeometry>();
1084 if ( !geom.isNull() )
1085 return geom.boundingBox();
1086 }
1087 if ( val.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
1088 {
1089 const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1090 if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1091 {
1092 QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1094 try
1095 {
1096 return ct.transformBoundingBox( rr );
1097 }
1098 catch ( QgsCsException & )
1099 {
1100 QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1101 }
1102 }
1103 return rr;
1104 }
1105
1106 if ( val.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
1107 {
1108 // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1109 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1110 val = fromVar.source;
1111 }
1112 else if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
1113 {
1114 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1115 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1116 val = fromVar.sink;
1117 }
1118
1119 if ( val.userType() == QMetaType::type( "QgsProperty" ) && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1120 {
1121 val = val.value< QgsProperty >().staticValue();
1122 }
1123
1124 // maybe parameter is a direct layer value?
1125 QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1126
1127 QString rectText;
1128 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
1129 rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1130 else
1131 rectText = val.toString();
1132
1133 if ( rectText.isEmpty() && !layer )
1134 return QgsRectangle();
1135
1136 const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1137 const QRegularExpressionMatch match = rx.match( rectText );
1138 if ( match.hasMatch() )
1139 {
1140 bool xMinOk = false;
1141 const double xMin = match.captured( 1 ).toDouble( &xMinOk );
1142 bool xMaxOk = false;
1143 const double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1144 bool yMinOk = false;
1145 const double yMin = match.captured( 3 ).toDouble( &yMinOk );
1146 bool yMaxOk = false;
1147 const double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1148 if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1149 {
1150 const QgsRectangle rect( xMin, yMin, xMax, yMax );
1151 const QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1152 if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1153 {
1154 QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1156 try
1157 {
1158 return ct.transformBoundingBox( rect );
1159 }
1160 catch ( QgsCsException & )
1161 {
1162 QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1163 }
1164 }
1165 return rect;
1166 }
1167 }
1168
1169 // try as layer extent
1170 if ( !layer )
1171 layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1172
1173 if ( layer )
1174 {
1175 const QgsRectangle rect = layer->extent();
1176 if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1177 {
1178 QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1180 try
1181 {
1182 return ct.transformBoundingBox( rect );
1183 }
1184 catch ( QgsCsException & )
1185 {
1186 QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1187 }
1188 }
1189 return rect;
1190 }
1191 return QgsRectangle();
1192}
1193
1195{
1196 if ( !definition )
1197 return QgsGeometry();
1198
1199 QVariant val = parameters.value( definition->name() );
1200
1201 if ( val.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
1202 {
1203 const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1205 if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1206 {
1207 g = g.densifyByCount( 20 );
1208 const QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1209 try
1210 {
1211 g.transform( ct );
1212 }
1213 catch ( QgsCsException & )
1214 {
1215 QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1216 }
1217 return g;
1218 }
1219 }
1220
1221 if ( val.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
1222 {
1223 // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1224 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1225 val = fromVar.source;
1226 }
1227 else if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
1228 {
1229 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1230 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1231 val = fromVar.sink;
1232 }
1233
1234 if ( val.userType() == QMetaType::type( "QgsProperty" ) && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1235 {
1236 val = val.value< QgsProperty >().staticValue();
1237 }
1238
1239 QString rectText;
1240 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
1241 rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1242 else
1243 rectText = val.toString();
1244
1245 if ( !rectText.isEmpty() )
1246 {
1247 const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1248 const QRegularExpressionMatch match = rx.match( rectText );
1249 if ( match.hasMatch() )
1250 {
1251 bool xMinOk = false;
1252 const double xMin = match.captured( 1 ).toDouble( &xMinOk );
1253 bool xMaxOk = false;
1254 const double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1255 bool yMinOk = false;
1256 const double yMin = match.captured( 3 ).toDouble( &yMinOk );
1257 bool yMaxOk = false;
1258 const double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1259 if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1260 {
1261 const QgsRectangle rect( xMin, yMin, xMax, yMax );
1262 const QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1264 if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1265 {
1266 g = g.densifyByCount( 20 );
1267 const QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1268 try
1269 {
1270 g.transform( ct );
1271 }
1272 catch ( QgsCsException & )
1273 {
1274 QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1275 }
1276 return g;
1277 }
1278 }
1279 }
1280 }
1281
1282 // try as layer extent
1283
1284 // maybe parameter is a direct layer value?
1285 QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1286 if ( !layer )
1287 layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1288
1289 if ( layer )
1290 {
1291 const QgsRectangle rect = layer->extent();
1293 if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1294 {
1295 g = g.densifyByCount( 20 );
1296 const QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1297 try
1298 {
1299 g.transform( ct );
1300 }
1301 catch ( QgsCsException & )
1302 {
1303 QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1304 }
1305 }
1306 return g;
1307 }
1308
1309 return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
1310}
1311
1313{
1314 const QVariant val = parameters.value( definition->name() );
1315 return parameterAsExtentCrs( definition, val, context );
1316}
1317
1319{
1320 QVariant val = value;
1321 if ( val.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
1322 {
1323 const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1324 if ( rr.crs().isValid() )
1325 {
1326 return rr.crs();
1327 }
1328 }
1329
1330 if ( val.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
1331 {
1332 // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1333 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1334 val = fromVar.source;
1335 }
1336 else if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
1337 {
1338 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1339 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1340 val = fromVar.sink;
1341 }
1342
1343 if ( val.userType() == QMetaType::type( "QgsProperty" ) && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1344 {
1345 val = val.value< QgsProperty >().staticValue();
1346 }
1347
1348 QString valueAsString;
1349 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
1350 valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1351 else
1352 valueAsString = val.toString();
1353
1354 const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1355
1356 const QRegularExpressionMatch match = rx.match( valueAsString );
1357 if ( match.hasMatch() )
1358 {
1359 const QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
1360 if ( crs.isValid() )
1361 return crs;
1362 }
1363
1364 if ( val.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
1365 {
1366 // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1367 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
1368 val = fromVar.source;
1369 }
1370 else if ( val.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
1371 {
1372 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1373 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
1374 val = fromVar.sink;
1375 }
1376
1377 if ( val.userType() == QMetaType::type( "QgsProperty" ) && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1378 {
1379 val = val.value< QgsProperty >().staticValue();
1380 }
1381
1382 // try as layer crs
1383 if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1384 return layer->crs();
1385 else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( valueAsString, context ) )
1386 return layer->crs();
1387
1388 if ( auto *lProject = context.project() )
1389 return lProject->crs();
1390 else
1392}
1393
1395{
1396 if ( !definition )
1397 return QgsPointXY();
1398
1399 return parameterAsPoint( definition, parameters.value( definition->name() ), context, crs );
1400}
1401
1403{
1404 if ( !definition )
1405 return QgsPointXY();
1406
1407 const QVariant val = value;
1408 if ( val.userType() == QMetaType::type( "QgsPointXY" ) )
1409 {
1410 return val.value<QgsPointXY>();
1411 }
1412 if ( val.userType() == QMetaType::type( "QgsGeometry" ) )
1413 {
1414 const QgsGeometry geom = val.value<QgsGeometry>();
1415 if ( !geom.isNull() )
1416 return geom.centroid().asPoint();
1417 }
1418 if ( val.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
1419 {
1420 const QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1421 if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1422 {
1423 const QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1424 try
1425 {
1426 return ct.transform( rp );
1427 }
1428 catch ( QgsCsException & )
1429 {
1430 QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1431 }
1432 }
1433 return rp;
1434 }
1435
1436 QString pointText = parameterAsString( definition, value, context );
1437 if ( pointText.isEmpty() )
1438 pointText = definition->defaultValue().toString();
1439
1440 if ( pointText.isEmpty() )
1441 return QgsPointXY();
1442
1443 const QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1444
1445 const QString valueAsString = parameterAsString( definition, value, context );
1446 const QRegularExpressionMatch match = rx.match( valueAsString );
1447 if ( match.hasMatch() )
1448 {
1449 bool xOk = false;
1450 const double x = match.captured( 1 ).toDouble( &xOk );
1451 bool yOk = false;
1452 const double y = match.captured( 2 ).toDouble( &yOk );
1453
1454 if ( xOk && yOk )
1455 {
1456 const QgsPointXY pt( x, y );
1457
1458 const QgsCoordinateReferenceSystem pointCrs( match.captured( 3 ) );
1459 if ( crs.isValid() && pointCrs.isValid() && crs != pointCrs )
1460 {
1461 const QgsCoordinateTransform ct( pointCrs, crs, context.project() );
1462 try
1463 {
1464 return ct.transform( pt );
1465 }
1466 catch ( QgsCsException & )
1467 {
1468 QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1469 }
1470 }
1471 return pt;
1472 }
1473 }
1474
1475 return QgsPointXY();
1476}
1477
1479{
1480 const QVariant val = parameters.value( definition->name() );
1481 return parameterAsPointCrs( definition, val, context );
1482}
1483
1485{
1486 if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
1487 {
1488 const QgsReferencedPointXY rr = value.value<QgsReferencedPointXY>();
1489 if ( rr.crs().isValid() )
1490 {
1491 return rr.crs();
1492 }
1493 }
1494
1495 const QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1496
1497 const QString valueAsString = parameterAsString( definition, value, context );
1498 const QRegularExpressionMatch match = rx.match( valueAsString );
1499 if ( match.hasMatch() )
1500 {
1501 const QgsCoordinateReferenceSystem crs( match.captured( 3 ) );
1502 if ( crs.isValid() )
1503 return crs;
1504 }
1505
1506 if ( auto *lProject = context.project() )
1507 return lProject->crs();
1508 else
1510}
1511
1513{
1514 if ( !definition )
1515 return QgsGeometry();
1516
1517 return parameterAsGeometry( definition, parameters.value( definition->name() ), context, crs );
1518}
1519
1521{
1522 if ( !definition )
1523 return QgsGeometry();
1524
1525 const QVariant val = value;
1526 if ( val.userType() == QMetaType::type( "QgsGeometry" ) )
1527 {
1528 return val.value<QgsGeometry>();
1529 }
1530
1531 if ( val.userType() == QMetaType::type( "QgsPointXY" ) )
1532 {
1533 return QgsGeometry::fromPointXY( val.value<QgsPointXY>() );
1534 }
1535
1536 if ( val.userType() == QMetaType::type( "QgsRectangle" ) )
1537 {
1538 return QgsGeometry::fromRect( val.value<QgsRectangle>() );
1539 }
1540
1541 if ( val.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
1542 {
1543 const QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1544 if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1545 {
1546 const QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1547 try
1548 {
1549 return QgsGeometry::fromPointXY( ct.transform( rp ) );
1550 }
1551 catch ( QgsCsException & )
1552 {
1553 QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1554 }
1555 }
1556 return QgsGeometry::fromPointXY( rp );
1557 }
1558
1559 if ( val.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
1560 {
1561 const QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
1563 if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
1564 {
1565 g = g.densifyByCount( 20 );
1566 const QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
1567 try
1568 {
1569 g.transform( ct );
1570 }
1571 catch ( QgsCsException & )
1572 {
1573 QgsMessageLog::logMessage( QObject::tr( "Error transforming rectangle geometry" ) );
1574 }
1575 }
1576 return g;
1577 }
1578
1579 if ( val.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
1580 {
1582 if ( crs.isValid() && rg.crs().isValid() && crs != rg.crs() )
1583 {
1584 const QgsCoordinateTransform ct( rg.crs(), crs, context.project() );
1585 try
1586 {
1587 rg.transform( ct );
1588 }
1589 catch ( QgsCsException & )
1590 {
1591 QgsMessageLog::logMessage( QObject::tr( "Error transforming geometry" ) );
1592 }
1593 }
1594 return rg;
1595 }
1596
1597 QString valueAsString = parameterAsString( definition, value, context );
1598 if ( valueAsString.isEmpty() )
1599 valueAsString = definition->defaultValue().toString();
1600
1601 if ( valueAsString.isEmpty() )
1602 return QgsGeometry();
1603
1604 const QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1605
1606 const QRegularExpressionMatch match = rx.match( valueAsString );
1607 if ( match.hasMatch() )
1608 {
1609 QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
1610 if ( !g.isNull() )
1611 {
1612 const QgsCoordinateReferenceSystem geomCrs( match.captured( 1 ) );
1613 if ( crs.isValid() && geomCrs.isValid() && crs != geomCrs )
1614 {
1615 const QgsCoordinateTransform ct( geomCrs, crs, context.project() );
1616 try
1617 {
1618 g.transform( ct );
1619 }
1620 catch ( QgsCsException & )
1621 {
1622 QgsMessageLog::logMessage( QObject::tr( "Error transforming geometry" ) );
1623 }
1624 }
1625 return g;
1626 }
1627 }
1628
1629 return QgsGeometry();
1630}
1631
1633{
1634 const QVariant val = parameters.value( definition->name() );
1635 return parameterAsGeometryCrs( definition, val, context );
1636}
1637
1639{
1640 if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
1641 {
1642 const QgsReferencedGeometry rg = value.value<QgsReferencedGeometry>();
1643 if ( rg.crs().isValid() )
1644 {
1645 return rg.crs();
1646 }
1647 }
1648
1649 if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
1650 {
1651 const QgsReferencedPointXY rp = value.value<QgsReferencedPointXY>();
1652 if ( rp.crs().isValid() )
1653 {
1654 return rp.crs();
1655 }
1656 }
1657
1658 if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
1659 {
1660 const QgsReferencedRectangle rr = value.value<QgsReferencedRectangle>();
1661 if ( rr.crs().isValid() )
1662 {
1663 return rr.crs();
1664 }
1665 }
1666
1667 // Match against EWKT
1668 const QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1669
1670 const QString valueAsString = parameterAsString( definition, value, context );
1671 const QRegularExpressionMatch match = rx.match( valueAsString );
1672 if ( match.hasMatch() )
1673 {
1674 const QgsCoordinateReferenceSystem crs( match.captured( 1 ) );
1675 if ( crs.isValid() )
1676 return crs;
1677 }
1678
1679 if ( auto *lProject = context.project() )
1680 return lProject->crs();
1681 else
1683}
1684
1685QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1686{
1687 if ( !definition )
1688 return QString();
1689
1690 QString fileText = parameterAsString( definition, parameters, context );
1691 if ( fileText.isEmpty() )
1692 fileText = definition->defaultValue().toString();
1693 return fileText;
1694}
1695
1697{
1698 if ( !definition )
1699 return QString();
1700
1701 QString fileText = parameterAsString( definition, value, context );
1702 if ( fileText.isEmpty() )
1703 fileText = definition->defaultValue().toString();
1704 return fileText;
1705}
1706
1707QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1708{
1709 if ( !definition )
1710 return QVariantList();
1711
1712 return parameterAsMatrix( definition, parameters.value( definition->name() ), context );
1713}
1714
1715QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1716{
1717 if ( !definition )
1718 return QVariantList();
1719
1720 QString resultString;
1721 const QVariant val = value;
1722 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
1723 resultString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1724 else if ( val.type() == QVariant::List )
1725 return val.toList();
1726 else
1727 resultString = val.toString();
1728
1729 if ( resultString.isEmpty() )
1730 {
1731 // check default
1732 if ( definition->defaultValue().type() == QVariant::List )
1733 return definition->defaultValue().toList();
1734 else
1735 resultString = definition->defaultValue().toString();
1736 }
1737
1738 QVariantList result;
1739 const auto constSplit = resultString.split( ',' );
1740 bool ok;
1741 double number;
1742 for ( const QString &s : constSplit )
1743 {
1744 number = s.toDouble( &ok );
1745 result << ( ok ? QVariant( number ) : s );
1746 }
1747
1748 return result;
1749}
1750
1751QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1752{
1753 if ( !definition )
1754 return QList<QgsMapLayer *>();
1755
1756 return parameterAsLayerList( definition, parameters.value( definition->name() ), context );
1757}
1758
1759QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1760{
1761 if ( !definition )
1762 return QList<QgsMapLayer *>();
1763
1764 const QVariant val = value;
1765 if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1766 {
1767 return QList<QgsMapLayer *>() << layer;
1768 }
1769
1770 QList<QgsMapLayer *> layers;
1771
1772 std::function< void( const QVariant &var ) > processVariant;
1773 processVariant = [ &layers, &context, &definition, &processVariant ]( const QVariant & var )
1774 {
1775 if ( var.type() == QVariant::List )
1776 {
1777 const auto constToList = var.toList();
1778 for ( const QVariant &listVar : constToList )
1779 {
1780 processVariant( listVar );
1781 }
1782 }
1783 else if ( var.type() == QVariant::StringList )
1784 {
1785 const auto constToStringList = var.toStringList();
1786 for ( const QString &s : constToStringList )
1787 {
1788 processVariant( s );
1789 }
1790 }
1791 else if ( var.userType() == QMetaType::type( "QgsProperty" ) )
1792 processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1793 else if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
1794 {
1795 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1796 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
1797 const QVariant sink = fromVar.sink;
1798 if ( sink.userType() == QMetaType::type( "QgsProperty" ) )
1799 {
1800 processVariant( sink.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1801 }
1802 }
1803 else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1804 {
1805 layers << layer;
1806 }
1807 else
1808 {
1809 QgsMapLayer *alayer = QgsProcessingUtils::mapLayerFromString( var.toString(), context );
1810 if ( alayer )
1811 layers << alayer;
1812 }
1813 };
1814
1815 processVariant( val );
1816
1817 if ( layers.isEmpty() )
1818 {
1819 // check default
1820 if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->defaultValue() ) ) )
1821 {
1822 layers << layer;
1823 }
1824 else if ( definition->defaultValue().type() == QVariant::List )
1825 {
1826 const auto constToList = definition->defaultValue().toList();
1827 for ( const QVariant &var : constToList )
1828 {
1829 if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1830 {
1831 layers << layer;
1832 }
1833 else
1834 {
1835 processVariant( var );
1836 }
1837 }
1838 }
1839 else
1840 processVariant( definition->defaultValue() );
1841 }
1842
1843 return layers;
1844}
1845
1846QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1847{
1848 if ( !definition )
1849 return QStringList();
1850
1851 const QVariant val = value;
1852
1853 QStringList files;
1854
1855 std::function< void( const QVariant &var ) > processVariant;
1856 processVariant = [ &files, &context, &definition, &processVariant ]( const QVariant & var )
1857 {
1858 if ( var.type() == QVariant::List )
1859 {
1860 const auto constToList = var.toList();
1861 for ( const QVariant &listVar : constToList )
1862 {
1863 processVariant( listVar );
1864 }
1865 }
1866 else if ( var.type() == QVariant::StringList )
1867 {
1868 const auto constToStringList = var.toStringList();
1869 for ( const QString &s : constToStringList )
1870 {
1871 processVariant( s );
1872 }
1873 }
1874 else if ( var.userType() == QMetaType::type( "QgsProperty" ) )
1875 processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1876 else
1877 {
1878 files << var.toString();
1879 }
1880 };
1881
1882 processVariant( val );
1883
1884 if ( files.isEmpty() )
1885 {
1886 processVariant( definition->defaultValue() );
1887 }
1888
1889 return files;
1890}
1891
1892QStringList QgsProcessingParameters::parameterAsFileList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1893{
1894 if ( !definition )
1895 return QStringList();
1896
1897 return parameterAsFileList( definition, parameters.value( definition->name() ), context );
1898}
1899
1900QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1901{
1902 if ( !definition )
1903 return QList<double>();
1904
1905 return parameterAsRange( definition, parameters.value( definition->name() ), context );
1906}
1907
1908QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1909{
1910 if ( !definition )
1911 return QList<double>();
1912
1913 QStringList resultStringList;
1914 const QVariant val = value;
1915
1916 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
1917 resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1918 else if ( val.type() == QVariant::List )
1919 {
1920 const auto constToList = val.toList();
1921 for ( const QVariant &var : constToList )
1922 resultStringList << var.toString();
1923 }
1924 else
1925 resultStringList << val.toString();
1926
1927 if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
1928 {
1929 resultStringList.clear();
1930 // check default
1931 if ( definition->defaultValue().type() == QVariant::List )
1932 {
1933 const auto constToList = definition->defaultValue().toList();
1934 for ( const QVariant &var : constToList )
1935 resultStringList << var.toString();
1936 }
1937 else
1938 resultStringList << definition->defaultValue().toString();
1939 }
1940
1941 if ( resultStringList.size() == 1 )
1942 {
1943 resultStringList = resultStringList.at( 0 ).split( ',' );
1944 }
1945
1946 if ( resultStringList.size() < 2 )
1947 return QList< double >() << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN() ;
1948
1949 QList< double > result;
1950 bool ok = false;
1951 double n = resultStringList.at( 0 ).toDouble( &ok );
1952 if ( ok )
1953 result << n;
1954 else
1955 result << std::numeric_limits<double>::quiet_NaN() ;
1956 ok = false;
1957 n = resultStringList.at( 1 ).toDouble( &ok );
1958 if ( ok )
1959 result << n;
1960 else
1961 result << std::numeric_limits<double>::quiet_NaN() ;
1962
1963 return result;
1964}
1965
1966QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1967{
1968 if ( !definition )
1969 return QStringList();
1970
1971 const QStringList resultStringList;
1972 return parameterAsFields( definition, parameters.value( definition->name() ), context );
1973}
1974
1975QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1976{
1977 if ( !definition )
1978 return QStringList();
1979
1980 QStringList resultStringList;
1981 const QVariant val = value;
1982 if ( val.isValid() )
1983 {
1984 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
1985 resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1986 else if ( val.type() == QVariant::List )
1987 {
1988 const auto constToList = val.toList();
1989 for ( const QVariant &var : constToList )
1990 resultStringList << var.toString();
1991 }
1992 else if ( val.type() == QVariant::StringList )
1993 {
1994 resultStringList = val.toStringList();
1995 }
1996 else
1997 resultStringList.append( val.toString().split( ';' ) );
1998 }
1999
2000 if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
2001 {
2002 resultStringList.clear();
2003 // check default
2004 if ( definition->defaultValue().isValid() )
2005 {
2006 if ( definition->defaultValue().type() == QVariant::List )
2007 {
2008 const auto constToList = definition->defaultValue().toList();
2009 for ( const QVariant &var : constToList )
2010 resultStringList << var.toString();
2011 }
2012 else if ( definition->defaultValue().type() == QVariant::StringList )
2013 {
2014 resultStringList = definition->defaultValue().toStringList();
2015 }
2016 else
2017 resultStringList.append( definition->defaultValue().toString().split( ';' ) );
2018 }
2019 }
2020
2021 return resultStringList;
2022}
2023
2025{
2026 if ( !definition )
2027 return nullptr;
2028
2029 return parameterAsLayout( definition, parameters.value( definition->name() ), context );
2030}
2031
2033{
2034 const QString layoutName = parameterAsString( definition, value, context );
2035 if ( layoutName.isEmpty() )
2036 return nullptr;
2037
2038 if ( !context.project() )
2039 return nullptr;
2040
2041 QgsMasterLayoutInterface *l = context.project()->layoutManager()->layoutByName( layoutName );
2043 return static_cast< QgsPrintLayout * >( l );
2044 else
2045 return nullptr;
2046}
2047
2049{
2050 if ( !definition )
2051 return nullptr;
2052
2053 return parameterAsLayoutItem( definition, parameters.value( definition->name() ), context, layout );
2054}
2055
2057{
2058 if ( !layout )
2059 return nullptr;
2060
2061 const QString id = parameterAsString( definition, value, context );
2062 if ( id.isEmpty() )
2063 return nullptr;
2064
2065 // prefer matching by uuid, since it's guaranteed to be unique.
2066 if ( QgsLayoutItem *item = layout->itemByUuid( id ) )
2067 return item;
2068 else if ( QgsLayoutItem *item = layout->itemById( id ) )
2069 return item;
2070 else
2071 return nullptr;
2072}
2073
2074QColor QgsProcessingParameters::parameterAsColor( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
2075{
2076 if ( !definition )
2077 return QColor();
2078
2079 return parameterAsColor( definition, parameters.value( definition->name() ), context );
2080}
2081
2083{
2084 if ( !definition )
2085 return QColor();
2086
2087 QVariant val = value;
2088 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
2089 {
2090 val = val.value< QgsProperty >().value( context.expressionContext(), definition->defaultValue() );
2091 }
2092 if ( val.type() == QVariant::Color )
2093 {
2094 QColor c = val.value< QColor >();
2095 if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
2096 if ( !colorParam->opacityEnabled() )
2097 c.setAlpha( 255 );
2098 return c;
2099 }
2100
2101 QString colorText = parameterAsString( definition, value, context );
2102 if ( colorText.isEmpty() && !( definition->flags() & QgsProcessingParameterDefinition::FlagOptional ) )
2103 {
2104 if ( definition->defaultValue().type() == QVariant::Color )
2105 return definition->defaultValue().value< QColor >();
2106 else
2107 colorText = definition->defaultValue().toString();
2108 }
2109
2110 if ( colorText.isEmpty() )
2111 return QColor();
2112
2113 bool containsAlpha = false;
2114 QColor c = QgsSymbolLayerUtils::parseColorWithAlpha( colorText, containsAlpha );
2115 if ( const QgsProcessingParameterColor *colorParam = dynamic_cast< const QgsProcessingParameterColor * >( definition ) )
2116 if ( c.isValid() && !colorParam->opacityEnabled() )
2117 c.setAlpha( 255 );
2118 return c;
2119}
2120
2121QString QgsProcessingParameters::parameterAsConnectionName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2122{
2123 if ( !definition )
2124 return QString();
2125
2126 return parameterAsConnectionName( definition, parameters.value( definition->name() ), context );
2127}
2128
2130{
2131 // for now it's just treated identical to strings, but in future we may want flexibility to amend this
2132 // (hence the new method)
2133 return parameterAsString( definition, value, context );
2134}
2135
2136QString QgsProcessingParameters::parameterAsSchema( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2137{
2138 if ( !definition )
2139 return QString();
2140
2141 return parameterAsSchema( definition, parameters.value( definition->name() ), context );
2142}
2143
2144QString QgsProcessingParameters::parameterAsSchema( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
2145{
2146 // for now it's just treated identical to strings, but in future we may want flexibility to amend this (e.g. if we want to embed connection details into the schema
2147 // parameter values, such as via a delimiter separated string)
2148 return parameterAsString( definition, value, context );
2149}
2150
2151QString QgsProcessingParameters::parameterAsDatabaseTableName( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
2152{
2153 if ( !definition )
2154 return QString();
2155
2156 return parameterAsDatabaseTableName( definition, parameters.value( definition->name() ), context );
2157}
2158
2160{
2161 // for now it's just treated identical to strings, but in future we may want flexibility to amend this (e.g. if we want to embed connection details into the table name
2162 // parameter values, such as via a delimiter separated string)
2163 return parameterAsString( definition, value, context );
2164}
2165
2167{
2168 return qobject_cast< QgsPointCloudLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::PointCloud ) );
2169}
2170
2172{
2173 return qobject_cast< QgsPointCloudLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::PointCloud ) );
2174}
2175
2177{
2178 return qobject_cast< QgsAnnotationLayer *>( parameterAsLayer( definition, parameters, context, QgsProcessingUtils::LayerHint::Annotation ) );
2179}
2180
2182{
2183 return qobject_cast< QgsAnnotationLayer *>( parameterAsLayer( definition, value, context, QgsProcessingUtils::LayerHint::Annotation ) );
2184}
2185
2187{
2188 const QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
2189 const QString name = map.value( QStringLiteral( "name" ) ).toString();
2190 std::unique_ptr< QgsProcessingParameterDefinition > def;
2191
2192 // probably all these hardcoded values aren't required anymore, and we could
2193 // always resort to the registry lookup...
2194 // TODO: confirm
2196 def.reset( new QgsProcessingParameterBoolean( name ) );
2197 else if ( type == QgsProcessingParameterCrs::typeName() )
2198 def.reset( new QgsProcessingParameterCrs( name ) );
2199 else if ( type == QgsProcessingParameterMapLayer::typeName() )
2200 def.reset( new QgsProcessingParameterMapLayer( name ) );
2201 else if ( type == QgsProcessingParameterExtent::typeName() )
2202 def.reset( new QgsProcessingParameterExtent( name ) );
2203 else if ( type == QgsProcessingParameterPoint::typeName() )
2204 def.reset( new QgsProcessingParameterPoint( name ) );
2205 else if ( type == QgsProcessingParameterFile::typeName() )
2206 def.reset( new QgsProcessingParameterFile( name ) );
2207 else if ( type == QgsProcessingParameterMatrix::typeName() )
2208 def.reset( new QgsProcessingParameterMatrix( name ) );
2210 def.reset( new QgsProcessingParameterMultipleLayers( name ) );
2211 else if ( type == QgsProcessingParameterNumber::typeName() )
2212 def.reset( new QgsProcessingParameterNumber( name ) );
2213 else if ( type == QgsProcessingParameterRange::typeName() )
2214 def.reset( new QgsProcessingParameterRange( name ) );
2216 def.reset( new QgsProcessingParameterRasterLayer( name ) );
2217 else if ( type == QgsProcessingParameterEnum::typeName() )
2218 def.reset( new QgsProcessingParameterEnum( name ) );
2219 else if ( type == QgsProcessingParameterString::typeName() )
2220 def.reset( new QgsProcessingParameterString( name ) );
2221 else if ( type == QgsProcessingParameterAuthConfig::typeName() )
2222 def.reset( new QgsProcessingParameterAuthConfig( name ) );
2223 else if ( type == QgsProcessingParameterExpression::typeName() )
2224 def.reset( new QgsProcessingParameterExpression( name ) );
2226 def.reset( new QgsProcessingParameterVectorLayer( name ) );
2227 else if ( type == QgsProcessingParameterField::typeName() )
2228 def.reset( new QgsProcessingParameterField( name ) );
2230 def.reset( new QgsProcessingParameterFeatureSource( name ) );
2232 def.reset( new QgsProcessingParameterFeatureSink( name ) );
2234 def.reset( new QgsProcessingParameterVectorDestination( name ) );
2236 def.reset( new QgsProcessingParameterRasterDestination( name ) );
2238 def.reset( new QgsProcessingParameterPointCloudDestination( name ) );
2240 def.reset( new QgsProcessingParameterFileDestination( name ) );
2242 def.reset( new QgsProcessingParameterFolderDestination( name ) );
2243 else if ( type == QgsProcessingParameterBand::typeName() )
2244 def.reset( new QgsProcessingParameterBand( name ) );
2245 else if ( type == QgsProcessingParameterMeshLayer::typeName() )
2246 def.reset( new QgsProcessingParameterMeshLayer( name ) );
2247 else if ( type == QgsProcessingParameterLayout::typeName() )
2248 def.reset( new QgsProcessingParameterLayout( name ) );
2249 else if ( type == QgsProcessingParameterLayoutItem::typeName() )
2250 def.reset( new QgsProcessingParameterLayoutItem( name ) );
2251 else if ( type == QgsProcessingParameterColor::typeName() )
2252 def.reset( new QgsProcessingParameterColor( name ) );
2254 def.reset( new QgsProcessingParameterCoordinateOperation( name ) );
2256 def.reset( new QgsProcessingParameterPointCloudLayer( name ) );
2258 def.reset( new QgsProcessingParameterAnnotationLayer( name ) );
2259 else
2260 {
2262 if ( paramType )
2263 def.reset( paramType->create( name ) );
2264 }
2265
2266 if ( !def )
2267 return nullptr;
2268
2269 def->fromVariantMap( map );
2270 return def.release();
2271}
2272
2274{
2275 QString desc = name;
2276 desc.replace( '_', ' ' );
2277 return desc;
2278}
2279
2281{
2282 bool isOptional = false;
2283 QString name;
2284 QString definition;
2285 QString type;
2286 if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
2287 return nullptr;
2288
2289 const QString description = descriptionFromName( name );
2290
2291 if ( type == QLatin1String( "boolean" ) )
2292 return QgsProcessingParameterBoolean::fromScriptCode( name, description, isOptional, definition );
2293 else if ( type == QLatin1String( "crs" ) )
2294 return QgsProcessingParameterCrs::fromScriptCode( name, description, isOptional, definition );
2295 else if ( type == QLatin1String( "layer" ) )
2296 return QgsProcessingParameterMapLayer::fromScriptCode( name, description, isOptional, definition );
2297 else if ( type == QLatin1String( "extent" ) )
2298 return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
2299 else if ( type == QLatin1String( "point" ) )
2300 return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
2301 else if ( type == QLatin1String( "geometry" ) )
2302 return QgsProcessingParameterGeometry::fromScriptCode( name, description, isOptional, definition );
2303 else if ( type == QLatin1String( "file" ) )
2304 return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
2305 else if ( type == QLatin1String( "folder" ) )
2306 return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::Folder );
2307 else if ( type == QLatin1String( "matrix" ) )
2308 return QgsProcessingParameterMatrix::fromScriptCode( name, description, isOptional, definition );
2309 else if ( type == QLatin1String( "multiple" ) )
2310 return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
2311 else if ( type == QLatin1String( "number" ) )
2312 return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
2313 else if ( type == QLatin1String( "distance" ) )
2314 return QgsProcessingParameterDistance::fromScriptCode( name, description, isOptional, definition );
2315 else if ( type == QLatin1String( "duration" ) )
2316 return QgsProcessingParameterDuration::fromScriptCode( name, description, isOptional, definition );
2317 else if ( type == QLatin1String( "scale" ) )
2318 return QgsProcessingParameterScale::fromScriptCode( name, description, isOptional, definition );
2319 else if ( type == QLatin1String( "range" ) )
2320 return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
2321 else if ( type == QLatin1String( "raster" ) )
2322 return QgsProcessingParameterRasterLayer::fromScriptCode( name, description, isOptional, definition );
2323 else if ( type == QLatin1String( "enum" ) )
2324 return QgsProcessingParameterEnum::fromScriptCode( name, description, isOptional, definition );
2325 else if ( type == QLatin1String( "string" ) )
2326 return QgsProcessingParameterString::fromScriptCode( name, description, isOptional, definition );
2327 else if ( type == QLatin1String( "authcfg" ) )
2328 return QgsProcessingParameterAuthConfig::fromScriptCode( name, description, isOptional, definition );
2329 else if ( type == QLatin1String( "expression" ) )
2330 return QgsProcessingParameterExpression::fromScriptCode( name, description, isOptional, definition );
2331 else if ( type == QLatin1String( "field" ) )
2332 return QgsProcessingParameterField::fromScriptCode( name, description, isOptional, definition );
2333 else if ( type == QLatin1String( "vector" ) )
2334 return QgsProcessingParameterVectorLayer::fromScriptCode( name, description, isOptional, definition );
2335 else if ( type == QLatin1String( "source" ) )
2336 return QgsProcessingParameterFeatureSource::fromScriptCode( name, description, isOptional, definition );
2337 else if ( type == QLatin1String( "sink" ) )
2338 return QgsProcessingParameterFeatureSink::fromScriptCode( name, description, isOptional, definition );
2339 else if ( type == QLatin1String( "vectordestination" ) )
2340 return QgsProcessingParameterVectorDestination::fromScriptCode( name, description, isOptional, definition );
2341 else if ( type == QLatin1String( "rasterdestination" ) )
2342 return QgsProcessingParameterRasterDestination::fromScriptCode( name, description, isOptional, definition );
2343 else if ( type == QLatin1String( "pointclouddestination" ) )
2344 return QgsProcessingParameterPointCloudDestination::fromScriptCode( name, description, isOptional, definition );
2345 else if ( type == QLatin1String( "filedestination" ) )
2346 return QgsProcessingParameterFileDestination::fromScriptCode( name, description, isOptional, definition );
2347 else if ( type == QLatin1String( "folderdestination" ) )
2348 return QgsProcessingParameterFolderDestination::fromScriptCode( name, description, isOptional, definition );
2349 else if ( type == QLatin1String( "band" ) )
2350 return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
2351 else if ( type == QLatin1String( "mesh" ) )
2352 return QgsProcessingParameterMeshLayer::fromScriptCode( name, description, isOptional, definition );
2353 else if ( type == QLatin1String( "layout" ) )
2354 return QgsProcessingParameterLayout::fromScriptCode( name, description, isOptional, definition );
2355 else if ( type == QLatin1String( "layoutitem" ) )
2356 return QgsProcessingParameterLayoutItem::fromScriptCode( name, description, isOptional, definition );
2357 else if ( type == QLatin1String( "color" ) )
2358 return QgsProcessingParameterColor::fromScriptCode( name, description, isOptional, definition );
2359 else if ( type == QLatin1String( "coordinateoperation" ) )
2360 return QgsProcessingParameterCoordinateOperation::fromScriptCode( name, description, isOptional, definition );
2361 else if ( type == QLatin1String( "maptheme" ) )
2362 return QgsProcessingParameterMapTheme::fromScriptCode( name, description, isOptional, definition );
2363 else if ( type == QLatin1String( "datetime" ) )
2364 return QgsProcessingParameterDateTime::fromScriptCode( name, description, isOptional, definition );
2365 else if ( type == QLatin1String( "providerconnection" ) )
2366 return QgsProcessingParameterProviderConnection::fromScriptCode( name, description, isOptional, definition );
2367 else if ( type == QLatin1String( "databaseschema" ) )
2368 return QgsProcessingParameterDatabaseSchema::fromScriptCode( name, description, isOptional, definition );
2369 else if ( type == QLatin1String( "databasetable" ) )
2370 return QgsProcessingParameterDatabaseTable::fromScriptCode( name, description, isOptional, definition );
2371 else if ( type == QLatin1String( "pointcloud" ) )
2372 return QgsProcessingParameterPointCloudLayer::fromScriptCode( name, description, isOptional, definition );
2373 else if ( type == QLatin1String( "annotation" ) )
2374 return QgsProcessingParameterAnnotationLayer::fromScriptCode( name, description, isOptional, definition );
2375
2376 return nullptr;
2377}
2378
2379bool QgsProcessingParameters::parseScriptCodeParameterOptions( const QString &code, bool &isOptional, QString &name, QString &type, QString &definition )
2380{
2381 const QRegularExpression re( QStringLiteral( "(?:#*)(.*?)=\\s*(.*)" ) );
2382 QRegularExpressionMatch m = re.match( code );
2383 if ( !m.hasMatch() )
2384 return false;
2385
2386 name = m.captured( 1 );
2387 QString tokens = m.captured( 2 );
2388 if ( tokens.startsWith( QLatin1String( "optional" ), Qt::CaseInsensitive ) )
2389 {
2390 isOptional = true;
2391 tokens.remove( 0, 8 ); // length "optional" = 8
2392 }
2393 else
2394 {
2395 isOptional = false;
2396 }
2397
2398 tokens = tokens.trimmed();
2399
2400 const QRegularExpression re2( QStringLiteral( "(.*?)\\s+(.*)" ) );
2401 m = re2.match( tokens );
2402 if ( !m.hasMatch() )
2403 {
2404 type = tokens.toLower().trimmed();
2405 definition.clear();
2406 }
2407 else
2408 {
2409 type = m.captured( 1 ).toLower().trimmed();
2410 definition = m.captured( 2 );
2411 }
2412 return true;
2413}
2414
2415//
2416// QgsProcessingParameterDefinition
2417//
2418
2419QgsProcessingParameterDefinition::QgsProcessingParameterDefinition( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QString &help )
2420 : mName( name )
2421 , mDescription( description )
2422 , mHelp( help )
2423 , mDefault( defaultValue )
2424 , mFlags( optional ? FlagOptional : 0 )
2425{}
2426
2428{
2429 if ( !input.isValid() && !mDefault.isValid() )
2430 return mFlags & FlagOptional;
2431
2432 if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
2433 || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
2434 return mFlags & FlagOptional;
2435
2436 return true;
2437}
2438
2440{
2441 if ( !value.isValid() )
2442 return QStringLiteral( "None" );
2443
2444 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
2445 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2446
2447 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
2448}
2449
2450QVariant QgsProcessingParameterDefinition::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const
2451{
2452 return valueAsJsonObjectPrivate( value, context, ValueAsStringFlags() );
2453}
2454
2455QVariant QgsProcessingParameterDefinition::valueAsJsonObjectPrivate( const QVariant &value, QgsProcessingContext &context, ValueAsStringFlags flags ) const
2456{
2457 if ( !value.isValid() )
2458 return value;
2459
2460 // dive into map and list types and convert each value
2461 if ( value.type() == QVariant::Type::Map )
2462 {
2463 const QVariantMap sourceMap = value.toMap();
2464 QVariantMap resultMap;
2465 for ( auto it = sourceMap.constBegin(); it != sourceMap.constEnd(); it++ )
2466 {
2467 resultMap[ it.key() ] = valueAsJsonObject( it.value(), context );
2468 }
2469 return resultMap;
2470 }
2471 else if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList )
2472 {
2473 const QVariantList sourceList = value.toList();
2474 QVariantList resultList;
2475 resultList.reserve( sourceList.size() );
2476 for ( const QVariant &v : sourceList )
2477 {
2478 resultList.push_back( valueAsJsonObject( v, context ) );
2479 }
2480 return resultList;
2481 }
2482 else
2483 {
2484 switch ( value.userType() )
2485 {
2486 // simple types which can be directly represented in JSON -- note that strings are NOT handled here yet!
2487 case QMetaType::Bool:
2488 case QMetaType::Char:
2489 case QMetaType::Int:
2490 case QMetaType::Double:
2491 case QMetaType::Float:
2492 case QMetaType::LongLong:
2493 case QMetaType::ULongLong:
2494 case QMetaType::UInt:
2495 case QMetaType::ULong:
2496 case QMetaType::UShort:
2497 return value;
2498
2499 default:
2500 break;
2501 }
2502
2503
2504 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
2505 {
2506 const QgsProperty prop = value.value< QgsProperty >();
2507 switch ( prop.propertyType() )
2508 {
2510 return QVariant();
2512 return valueAsJsonObject( prop.staticValue(), context );
2513
2514 // these are not supported for serialization
2517 QgsDebugMsg( QStringLiteral( "could not convert expression/field based property to JSON object" ) );
2518 return QVariant();
2519 }
2520 }
2521
2522 // value may be a CRS
2523 if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
2524 {
2526 if ( !crs.isValid() )
2527 return QString();
2528 else if ( !crs.authid().isEmpty() )
2529 return crs.authid();
2530 else
2532 }
2533 else if ( value.userType() == QMetaType::type( "QgsRectangle" ) )
2534 {
2535 const QgsRectangle r = value.value<QgsRectangle>();
2536 return QStringLiteral( "%1, %3, %2, %4" ).arg( qgsDoubleToString( r.xMinimum() ),
2539 qgsDoubleToString( r.yMaximum() ) );
2540 }
2541 else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
2542 {
2543 const QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
2544 return QStringLiteral( "%1, %3, %2, %4 [%5]" ).arg( qgsDoubleToString( r.xMinimum() ),
2548 r.crs().authid() );
2549 }
2550 else if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
2551 {
2552 const QgsGeometry g = value.value<QgsGeometry>();
2553 if ( !g.isNull() )
2554 {
2555 return g.asWkt();
2556 }
2557 else
2558 {
2559 return QString();
2560 }
2561 }
2562 else if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
2563 {
2564 const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
2565 if ( !g.isNull() )
2566 {
2567 if ( !g.crs().isValid() )
2568 return g.asWkt();
2569 else
2570 return QStringLiteral( "CRS=%1;%2" ).arg( g.crs().authid().isEmpty() ? g.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : g.crs().authid(), g.asWkt() );
2571 }
2572 else
2573 {
2574 return QString();
2575 }
2576 }
2577 else if ( value.userType() == QMetaType::type( "QgsPointXY" ) )
2578 {
2579 const QgsPointXY r = value.value<QgsPointXY>();
2580 return QStringLiteral( "%1,%2" ).arg( qgsDoubleToString( r.x() ),
2581 qgsDoubleToString( r.y() ) );
2582 }
2583 else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
2584 {
2585 const QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
2586 return QStringLiteral( "%1,%2 [%3]" ).arg( qgsDoubleToString( r.x() ),
2587 qgsDoubleToString( r.y() ),
2588 r.crs().authid() );
2589 }
2590 else if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
2591 {
2592 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
2593
2594 // TODO -- we could consider also serializating the additional properties like invalid feature handling, limits, etc
2595 return valueAsJsonObject( fromVar.source, context );
2596 }
2597 else if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
2598 {
2599 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
2600 return valueAsJsonObject( fromVar.sink, context );
2601 }
2602 else if ( value.userType() == QMetaType::type( "QColor" ) )
2603 {
2604 const QColor fromVar = value.value< QColor >();
2605 if ( !fromVar.isValid() )
2606 return QString();
2607
2608 return QStringLiteral( "rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(), 'f', 2 ) );
2609 }
2610 else if ( value.userType() == QMetaType::type( "QDateTime" ) )
2611 {
2612 const QDateTime fromVar = value.toDateTime();
2613 if ( !fromVar.isValid() )
2614 return QString();
2615
2616 return fromVar.toString( Qt::ISODate );
2617 }
2618 else if ( value.userType() == QMetaType::type( "QDate" ) )
2619 {
2620 const QDate fromVar = value.toDate();
2621 if ( !fromVar.isValid() )
2622 return QString();
2623
2624 return fromVar.toString( Qt::ISODate );
2625 }
2626 else if ( value.userType() == QMetaType::type( "QTime" ) )
2627 {
2628 const QTime fromVar = value.toTime();
2629 if ( !fromVar.isValid() )
2630 return QString();
2631
2632 return fromVar.toString( Qt::ISODate );
2633 }
2634
2636 {
2637 // value may be a map layer
2638 QVariantMap p;
2639 p.insert( name(), value );
2640 if ( QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ) )
2641 {
2642 const QString source = QgsProcessingUtils::normalizeLayerSource( layer->source() );
2643 if ( !source.isEmpty() )
2644 return source;
2645 return layer->id();
2646 }
2647 }
2648
2649 // now we handle strings, after any other specific logic has already been applied
2650 if ( value.userType() == QMetaType::QString )
2651 return value;
2652 }
2653
2654 // unhandled type
2655 Q_ASSERT_X( false, "QgsProcessingParameterDefinition::valueAsJsonObject", QStringLiteral( "unsupported variant type %1" ).arg( QMetaType::typeName( value.userType() ) ).toLocal8Bit() );
2656 return value;
2657}
2658
2659QString QgsProcessingParameterDefinition::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
2660{
2661 return valueAsStringPrivate( value, context, ok, ValueAsStringFlags() );
2662}
2663
2664QString QgsProcessingParameterDefinition::valueAsStringPrivate( const QVariant &value, QgsProcessingContext &context, bool &ok, ValueAsStringFlags flags ) const
2665{
2666 ok = true;
2667
2668 if ( !value.isValid() )
2669 return QString();
2670
2671 switch ( value.userType() )
2672 {
2673 // simple types which can be directly represented in JSON -- note that strings are NOT handled here yet!
2674 case QMetaType::Bool:
2675 case QMetaType::Char:
2676 case QMetaType::Int:
2677 case QMetaType::Double:
2678 case QMetaType::Float:
2679 case QMetaType::LongLong:
2680 case QMetaType::ULongLong:
2681 case QMetaType::UInt:
2682 case QMetaType::ULong:
2683 case QMetaType::UShort:
2684 return value.toString();
2685
2686 default:
2687 break;
2688 }
2689
2690 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
2691 {
2692 const QgsProperty prop = value.value< QgsProperty >();
2693 switch ( prop.propertyType() )
2694 {
2696 return QString();
2698 return valueAsString( prop.staticValue(), context, ok );
2699
2700 // these are not supported for serialization
2703 QgsDebugMsg( QStringLiteral( "could not convert expression/field based property to string" ) );
2704 return QString();
2705 }
2706 }
2707
2708 // value may be a CRS
2709 if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
2710 {
2712 if ( !crs.isValid() )
2713 return QString();
2714 else if ( !crs.authid().isEmpty() )
2715 return crs.authid();
2716 else
2718 }
2719 else if ( value.userType() == QMetaType::type( "QgsRectangle" ) )
2720 {
2721 const QgsRectangle r = value.value<QgsRectangle>();
2722 return QStringLiteral( "%1, %3, %2, %4" ).arg( qgsDoubleToString( r.xMinimum() ),
2725 qgsDoubleToString( r.yMaximum() ) );
2726 }
2727 else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
2728 {
2729 const QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
2730 return QStringLiteral( "%1, %3, %2, %4 [%5]" ).arg( qgsDoubleToString( r.xMinimum() ),
2733 qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2734 }
2735 else if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
2736 {
2737 const QgsGeometry g = value.value<QgsGeometry>();
2738 if ( !g.isNull() )
2739 {
2740 return g.asWkt();
2741 }
2742 else
2743 {
2744 return QString();
2745 }
2746 }
2747 else if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
2748 {
2749 const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
2750 if ( !g.isNull() )
2751 {
2752 if ( !g.crs().isValid() )
2753 return g.asWkt();
2754 else
2755 return QStringLiteral( "CRS=%1;%2" ).arg( g.crs().authid().isEmpty() ? g.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : g.crs().authid(), g.asWkt() );
2756 }
2757 else
2758 {
2759 return QString();
2760 }
2761 }
2762 else if ( value.userType() == QMetaType::type( "QgsPointXY" ) )
2763 {
2764 const QgsPointXY r = value.value<QgsPointXY>();
2765 return QStringLiteral( "%1,%2" ).arg( qgsDoubleToString( r.x() ),
2766 qgsDoubleToString( r.y() ) );
2767 }
2768 else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
2769 {
2770 const QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
2771 return QStringLiteral( "%1,%2 [%3]" ).arg( qgsDoubleToString( r.x() ),
2772 qgsDoubleToString( r.y() ),
2773 r.crs().authid() );
2774 }
2775 else if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
2776 {
2777 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
2778 return valueAsString( fromVar.source, context, ok );
2779 }
2780 else if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
2781 {
2782 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
2783 return valueAsString( fromVar.sink, context, ok );
2784 }
2785 else if ( value.userType() == QMetaType::type( "QColor" ) )
2786 {
2787 const QColor fromVar = value.value< QColor >();
2788 if ( !fromVar.isValid() )
2789 return QString();
2790
2791 return QStringLiteral( "rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(), 'f', 2 ) );
2792 }
2793 else if ( value.userType() == QMetaType::type( "QDateTime" ) )
2794 {
2795 const QDateTime fromVar = value.toDateTime();
2796 if ( !fromVar.isValid() )
2797 return QString();
2798
2799 return fromVar.toString( Qt::ISODate );
2800 }
2801 else if ( value.userType() == QMetaType::type( "QDate" ) )
2802 {
2803 const QDate fromVar = value.toDate();
2804 if ( !fromVar.isValid() )
2805 return QString();
2806
2807 return fromVar.toString( Qt::ISODate );
2808 }
2809 else if ( value.userType() == QMetaType::type( "QTime" ) )
2810 {
2811 const QTime fromVar = value.toTime();
2812 if ( !fromVar.isValid() )
2813 return QString();
2814
2815 return fromVar.toString( Qt::ISODate );
2816 }
2817
2819 {
2820 // value may be a map layer
2821 QVariantMap p;
2822 p.insert( name(), value );
2823 if ( QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ) )
2824 {
2825 const QString source = QgsProcessingUtils::normalizeLayerSource( layer->source() );
2826 if ( !source.isEmpty() )
2827 return source;
2828 return layer->id();
2829 }
2830 }
2831
2832 // now we handle strings, after any other specific logic has already been applied
2833 if ( value.userType() == QMetaType::QString )
2834 return value.toString();
2835
2836 // unhandled type
2837 QgsDebugMsg( QStringLiteral( "unsupported variant type %1" ).arg( QMetaType::typeName( value.userType() ) ) );
2838 ok = false;
2839 return value.toString();
2840}
2841
2842QStringList QgsProcessingParameterDefinition::valueAsStringList( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
2843{
2844 ok = true;
2845 if ( !value.isValid( ) )
2846 return QStringList();
2847
2848 if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList )
2849 {
2850 const QVariantList sourceList = value.toList();
2851 QStringList resultList;
2852 resultList.reserve( sourceList.size() );
2853 for ( const QVariant &v : sourceList )
2854 {
2855 resultList.append( valueAsStringList( v, context, ok ) );
2856 }
2857 return resultList;
2858 }
2859
2860 const QString res = valueAsString( value, context, ok );
2861 if ( !ok )
2862 return QStringList();
2863
2864 return {res};
2865}
2866
2868{
2869 return QString();
2870}
2871
2873{
2874 QString code = QStringLiteral( "##%1=" ).arg( mName );
2875 if ( mFlags & FlagOptional )
2876 code += QLatin1String( "optional " );
2877 code += type() + ' ';
2878 code += mDefault.toString();
2879 return code.trimmed();
2880}
2881
2883{
2884 // base class method is probably not much use
2886 {
2887 switch ( outputType )
2888 {
2890 {
2891 QString code = t->className() + QStringLiteral( "('%1', %2" )
2893 if ( mFlags & FlagOptional )
2894 code += QLatin1String( ", optional=True" );
2895
2897 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2898 return code;
2899 }
2900 }
2901 }
2902
2903 // oh well, we tried
2904 return QString();
2905}
2906
2908{
2909 QVariantMap map;
2910 map.insert( QStringLiteral( "parameter_type" ), type() );
2911 map.insert( QStringLiteral( "name" ), mName );
2912 map.insert( QStringLiteral( "description" ), mDescription );
2913 map.insert( QStringLiteral( "help" ), mHelp );
2914 map.insert( QStringLiteral( "default" ), mDefault );
2915 map.insert( QStringLiteral( "defaultGui" ), mGuiDefault );
2916 map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
2917 map.insert( QStringLiteral( "metadata" ), mMetadata );
2918 return map;
2919}
2920
2922{
2923 mName = map.value( QStringLiteral( "name" ) ).toString();
2924 mDescription = map.value( QStringLiteral( "description" ) ).toString();
2925 mHelp = map.value( QStringLiteral( "help" ) ).toString();
2926 mDefault = map.value( QStringLiteral( "default" ) );
2927 mGuiDefault = map.value( QStringLiteral( "defaultGui" ) );
2928 mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
2929 mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
2930 return true;
2931}
2932
2934{
2935 return mAlgorithm;
2936}
2937
2939{
2940 return mAlgorithm ? mAlgorithm->provider() : nullptr;
2941}
2942
2944{
2945 QString text = QStringLiteral( "<p><b>%1</b></p>" ).arg( description() );
2946 if ( !help().isEmpty() )
2947 {
2948 text += QStringLiteral( "<p>%1</p>" ).arg( help() );
2949 }
2950 text += QStringLiteral( "<p>%1</p>" ).arg( QObject::tr( "Python identifier: ‘%1’" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
2951 return text;
2952}
2953
2954QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2955 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2956{}
2957
2959{
2960 return new QgsProcessingParameterBoolean( *this );
2961}
2962
2964{
2965 if ( !val.isValid() )
2966 return QStringLiteral( "None" );
2967
2968 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
2969 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2970 return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
2971}
2972
2974{
2975 QString code = QStringLiteral( "##%1=" ).arg( mName );
2976 if ( mFlags & FlagOptional )
2977 code += QLatin1String( "optional " );
2978 code += type() + ' ';
2979 code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
2980 return code.trimmed();
2981}
2982
2983QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2984{
2985 return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
2986}
2987
2988QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2989 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2990{
2991
2992}
2993
2995{
2996 return new QgsProcessingParameterCrs( *this );
2997}
2998
3000{
3001 if ( !input.isValid() )
3002 return mFlags & FlagOptional;
3003
3004 if ( input.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
3005 {
3006 return true;
3007 }
3008 else if ( input.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
3009 {
3010 return true;
3011 }
3012 else if ( input.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
3013 {
3014 return true;
3015 }
3016
3017 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
3018 {
3019 return true;
3020 }
3021
3022 // direct map layer value
3023 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3024 return true;
3025
3026 if ( input.type() != QVariant::String || input.toString().isEmpty() )
3027 return mFlags & FlagOptional;
3028
3029 return true;
3030}
3031
3032QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3033{
3034 if ( !value.isValid() )
3035 return QStringLiteral( "None" );
3036
3037 if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
3038 {
3039 if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
3040 return QStringLiteral( "QgsCoordinateReferenceSystem()" );
3041 else
3042 return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
3043 }
3044
3045 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
3046 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3047
3048 QVariantMap p;
3049 p.insert( name(), value );
3050 QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
3051 if ( layer )
3053
3055}
3056
3057QString QgsProcessingParameterCrs::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
3058{
3060}
3061
3062QVariant QgsProcessingParameterCrs::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const
3063{
3065}
3066
3067QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3068{
3069 return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
3070}
3071
3072QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QList<int> &types )
3073 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3075{
3076
3077}
3078
3080{
3081 return new QgsProcessingParameterMapLayer( *this );
3082}
3083
3085{
3086 if ( !input.isValid() )
3087 return mFlags & FlagOptional;
3088
3089 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
3090 {
3091 return true;
3092 }
3093
3094 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3095 {
3096 return true;
3097 }
3098
3099 if ( input.type() != QVariant::String || input.toString().isEmpty() )
3100 return mFlags & FlagOptional;
3101
3102 if ( !context )
3103 {
3104 // that's as far as we can get without a context
3105 return true;
3106 }
3107
3108 // try to load as layer
3109 if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
3110 return true;
3111
3112 return false;
3113}
3114
3116{
3117 if ( !val.isValid() )
3118 return QStringLiteral( "None" );
3119
3120 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
3121 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3122
3123 QVariantMap p;
3124 p.insert( name(), val );
3125 QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
3128}
3129
3130QString QgsProcessingParameterMapLayer::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
3131{
3133}
3134
3135QVariant QgsProcessingParameterMapLayer::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const
3136{
3138}
3139
3141{
3142 QStringList vectors = QgsProviderRegistry::instance()->fileVectorFilters().split( QStringLiteral( ";;" ) );
3143 const QStringList rasters = QgsProviderRegistry::instance()->fileRasterFilters().split( QStringLiteral( ";;" ) );
3144 for ( const QString &raster : rasters )
3145 {
3146 if ( !vectors.contains( raster ) )
3147 vectors << raster;
3148 }
3149 const QStringList meshFilters = QgsProviderRegistry::instance()->fileMeshFilters().split( QStringLiteral( ";;" ) );
3150 for ( const QString &mesh : meshFilters )
3151 {
3152 if ( !vectors.contains( mesh ) )
3153 vectors << mesh;
3154 }
3155 const QStringList pointCloudFilters = QgsProviderRegistry::instance()->filePointCloudFilters().split( QStringLiteral( ";;" ) );
3156 for ( const QString &pointCloud : pointCloudFilters )
3157 {
3158 if ( !vectors.contains( pointCloud ) )
3159 vectors << pointCloud;
3160 }
3161 vectors.removeAll( QObject::tr( "All files (*.*)" ) );
3162 std::sort( vectors.begin(), vectors.end() );
3163
3164 return QObject::tr( "All files (*.*)" ) + QStringLiteral( ";;" ) + vectors.join( QLatin1String( ";;" ) );
3165}
3166
3168{
3170}
3171
3173{
3174 QString code = QStringLiteral( "##%1=" ).arg( mName );
3175 if ( mFlags & FlagOptional )
3176 code += QLatin1String( "optional " );
3177 code += QLatin1String( "layer " );
3178
3179 for ( const int type : mDataTypes )
3180 {
3181 switch ( type )
3182 {
3184 code += QLatin1String( "hasgeometry " );
3185 break;
3186
3188 code += QLatin1String( "point " );
3189 break;
3190
3192 code += QLatin1String( "line " );
3193 break;
3194
3196 code += QLatin1String( "polygon " );
3197 break;
3198
3200 code += QLatin1String( "raster " );
3201 break;
3202
3204 code += QLatin1String( "mesh " );
3205 break;
3206
3208 code += QLatin1String( "plugin " );
3209 break;
3210
3212 code += QLatin1String( "pointcloud " );
3213 break;
3214
3216 code += QLatin1String( "annotation " );
3217 break;
3218 }
3219 }
3220
3221 code += mDefault.toString();
3222 return code.trimmed();
3223}
3224
3225QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3226{
3227 QList< int > types;
3228 QString def = definition;
3229 while ( true )
3230 {
3231 if ( def.startsWith( QLatin1String( "hasgeometry" ), Qt::CaseInsensitive ) )
3232 {
3234 def = def.mid( 12 );
3235 continue;
3236 }
3237 else if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
3238 {
3240 def = def.mid( 6 );
3241 continue;
3242 }
3243 else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
3244 {
3246 def = def.mid( 5 );
3247 continue;
3248 }
3249 else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
3250 {
3252 def = def.mid( 8 );
3253 continue;
3254 }
3255 else if ( def.startsWith( QLatin1String( "raster" ), Qt::CaseInsensitive ) )
3256 {
3258 def = def.mid( 7 );
3259 continue;
3260 }
3261 else if ( def.startsWith( QLatin1String( "mesh" ), Qt::CaseInsensitive ) )
3262 {
3263 types << QgsProcessing::TypeMesh;
3264 def = def.mid( 5 );
3265 continue;
3266 }
3267 else if ( def.startsWith( QLatin1String( "plugin" ), Qt::CaseInsensitive ) )
3268 {
3270 def = def.mid( 7 );
3271 continue;
3272 }
3273 else if ( def.startsWith( QLatin1String( "pointcloud" ), Qt::CaseInsensitive ) )
3274 {
3276 def = def.mid( 11 );
3277 continue;
3278 }
3279 else if ( def.startsWith( QLatin1String( "annotation" ), Qt::CaseInsensitive ) )
3280 {
3282 def = def.mid( 11 );
3283 continue;
3284 }
3285 break;
3286 }
3287
3288 return new QgsProcessingParameterMapLayer( name, description, def, isOptional, types );
3289}
3290
3292{
3293 switch ( outputType )
3294 {
3296 {
3297 QString code = QStringLiteral( "QgsProcessingParameterMapLayer('%1', %2" )
3299 if ( mFlags & FlagOptional )
3300 code += QLatin1String( ", optional=True" );
3301
3303 code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
3304
3305 if ( !mDataTypes.empty() )
3306 {
3307 QStringList options;
3308 options.reserve( mDataTypes.size() );
3309 for ( const int t : mDataTypes )
3310 options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
3311 code += QStringLiteral( ", types=[%1])" ).arg( options.join( ',' ) );
3312 }
3313 else
3314 {
3315 code += QLatin1Char( ')' );
3316 }
3317
3318 return code;
3319 }
3320 }
3321 return QString();
3322}
3323
3325{
3327 QVariantList types;
3328 for ( const int type : mDataTypes )
3329 {
3330 types << type;
3331 }
3332 map.insert( QStringLiteral( "data_types" ), types );
3333 return map;
3334}
3335
3337{
3339 mDataTypes.clear();
3340 const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
3341 for ( const QVariant &val : values )
3342 {
3343 mDataTypes << val.toInt();
3344 }
3345 return true;
3346}
3347
3348QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3349 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3350{
3351
3352}
3353
3355{
3356 return new QgsProcessingParameterExtent( *this );
3357}
3358
3360{
3361 if ( !input.isValid() )
3362 return mFlags & FlagOptional;
3363
3364 if ( input.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
3365 {
3366 return true;
3367 }
3368 else if ( input.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
3369 {
3370 return true;
3371 }
3372
3373 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
3374 {
3375 return true;
3376 }
3377
3378 if ( input.userType() == QMetaType::type( "QgsRectangle" ) )
3379 {
3380 const QgsRectangle r = input.value<QgsRectangle>();
3381 return !r.isNull();
3382 }
3383 if ( input.userType() == QMetaType::type( "QgsGeometry" ) )
3384 {
3385 return true;
3386 }
3387 if ( input.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
3388 {
3389 const QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
3390 return !r.isNull();
3391 }
3392
3393 // direct map layer value
3394 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3395 return true;
3396
3397 if ( input.type() != QVariant::String || input.toString().isEmpty() )
3398 return mFlags & FlagOptional;
3399
3400 if ( !context )
3401 {
3402 // that's as far as we can get without a context
3403 return true;
3404 }
3405
3406 const QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
3407 const QRegularExpressionMatch match = rx.match( input.toString() );
3408 if ( match.hasMatch() )
3409 {
3410 bool xMinOk = false;
3411 ( void )match.captured( 1 ).toDouble( &xMinOk );
3412 bool xMaxOk = false;
3413 ( void )match.captured( 2 ).toDouble( &xMaxOk );
3414 bool yMinOk = false;
3415 ( void )match.captured( 3 ).toDouble( &yMinOk );
3416 bool yMaxOk = false;
3417 ( void )match.captured( 4 ).toDouble( &yMaxOk );
3418 if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
3419 return true;
3420 }
3421
3422 // try as layer extent
3423 return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
3424}
3425
3426QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3427{
3428 if ( !value.isValid() )
3429 return QStringLiteral( "None" );
3430
3431 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
3432 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3433
3434 if ( value.userType() == QMetaType::type( "QgsRectangle" ) )
3435 {
3436 const QgsRectangle r = value.value<QgsRectangle>();
3437 return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
3440 qgsDoubleToString( r.yMaximum() ) );
3441 }
3442 else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
3443 {
3444 const QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
3445 return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
3448 qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
3449 }
3450 else if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
3451 {
3452 const QgsGeometry g = value.value<QgsGeometry>();
3453 if ( !g.isNull() )
3454 {
3455 const QString wkt = g.asWkt();
3456 return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
3457 }
3458 }
3459
3460 QVariantMap p;
3461 p.insert( name(), value );
3462 QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
3463 if ( layer )
3465
3467}
3468
3469QString QgsProcessingParameterExtent::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
3470{
3472}
3473
3474QVariant QgsProcessingParameterExtent::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const
3475{
3477}
3478
3479QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3480{
3481 return new QgsProcessingParameterExtent( name, description, definition, isOptional );
3482}
3483
3484QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3485 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3486{
3487
3488}
3489
3491{
3492 return new QgsProcessingParameterPoint( *this );
3493}
3494
3496{
3497 if ( !input.isValid() )
3498 return mFlags & FlagOptional;
3499
3500 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
3501 {
3502 return true;
3503 }
3504
3505 if ( input.userType() == QMetaType::type( "QgsPointXY" ) )
3506 {
3507 return true;
3508 }
3509 if ( input.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
3510 {
3511 return true;
3512 }
3513 if ( input.userType() == QMetaType::type( "QgsGeometry" ) )
3514 {
3515 return true;
3516 }
3517
3518 if ( input.type() == QVariant::String )
3519 {
3520 if ( input.toString().isEmpty() )
3521 return mFlags & FlagOptional;
3522 }
3523
3524 const QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
3525
3526 const QRegularExpressionMatch match = rx.match( input.toString() );
3527 if ( match.hasMatch() )
3528 {
3529 bool xOk = false;
3530 ( void )match.captured( 1 ).toDouble( &xOk );
3531 bool yOk = false;
3532 ( void )match.captured( 2 ).toDouble( &yOk );
3533 return xOk && yOk;
3534 }
3535 else
3536 return false;
3537}
3538
3539QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
3540{
3541 if ( !value.isValid() )
3542 return QStringLiteral( "None" );
3543
3544 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
3545 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3546
3547 if ( value.userType() == QMetaType::type( "QgsPointXY" ) )
3548 {
3549 const QgsPointXY r = value.value<QgsPointXY>();
3550 return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
3551 qgsDoubleToString( r.y() ) );
3552 }
3553 else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
3554 {
3555 const QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
3556 return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
3557 qgsDoubleToString( r.y() ),
3558 r.crs().authid() );
3559 }
3560 else if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
3561 {
3562 const QgsGeometry g = value.value<QgsGeometry>();
3563 if ( !g.isNull() )
3564 {
3565 const QString wkt = g.asWkt();
3566 return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
3567 }
3568 }
3569
3571}
3572
3573QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3574{
3575 return new QgsProcessingParameterPoint( name, description, definition, isOptional );
3576}
3577
3578QgsProcessingParameterGeometry::QgsProcessingParameterGeometry( const QString &name, const QString &description,
3579 const QVariant &defaultValue, bool optional, const QList<int> &geometryTypes, bool allowMultipart )
3580 : QgsProcessingParameterDefinition( name, description, defaultValue, optional ),
3581 mGeomTypes( geometryTypes ),
3582 mAllowMultipart( allowMultipart )
3583{
3584
3585}
3586
3588{
3589 return new QgsProcessingParameterGeometry( *this );
3590}
3591
3593{
3594 if ( !input.isValid() )
3595 return mFlags & FlagOptional;
3596
3597 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
3598 {
3599 return true;
3600 }
3601
3602 const bool anyTypeAllowed = mGeomTypes.isEmpty() || mGeomTypes.contains( QgsWkbTypes::UnknownGeometry );
3603
3604 if ( input.userType() == QMetaType::type( "QgsGeometry" ) )
3605 {
3606 return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsGeometry>().type() ) ) &&
3607 ( mAllowMultipart || !input.value<QgsGeometry>().isMultipart() );
3608 }
3609
3610 if ( input.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
3611 {
3612 return ( anyTypeAllowed || mGeomTypes.contains( input.value<QgsReferencedGeometry>().type() ) ) &&
3613 ( mAllowMultipart || !input.value<QgsReferencedGeometry>().isMultipart() );
3614 }
3615
3616 if ( input.userType() == QMetaType::type( "QgsPointXY" ) )
3617 {
3618 return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3619 }
3620
3621 if ( input.userType() == QMetaType::type( "QgsRectangle" ) )
3622 {
3623 return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3624 }
3625
3626 if ( input.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
3627 {
3628 return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PointGeometry );
3629 }
3630
3631 if ( input.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
3632 {
3633 return anyTypeAllowed || mGeomTypes.contains( QgsWkbTypes::PolygonGeometry );
3634 }
3635
3636 if ( input.type() == QVariant::String )
3637 {
3638 if ( input.toString().isEmpty() )
3639 return mFlags & FlagOptional;
3640 }
3641
3642 // Match against EWKT
3643 const QRegularExpression rx( QStringLiteral( "^\\s*(?:CRS=(.*);)?(.*?)$" ) );
3644
3645 const QRegularExpressionMatch match = rx.match( input.toString() );
3646 if ( match.hasMatch() )
3647 {
3648 const QgsGeometry g = QgsGeometry::fromWkt( match.captured( 2 ) );
3649 if ( ! g.isNull() )
3650 {
3651 return ( anyTypeAllowed || mGeomTypes.contains( g.type() ) ) && ( mAllowMultipart || !g.isMultipart() );
3652 }
3653 else
3654 {
3655 QgsMessageLog::logMessage( QObject::tr( "Error creating geometry: \"%1\"" ).arg( g.lastError() ), QObject::tr( "Processing" ) );
3656 }
3657 }
3658 return false;
3659}
3660
3662{
3664 {
3665 if ( !crs.isValid() )
3667 else
3668 return QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "CRS=%1;%2" ).arg( crs.authid().isEmpty() ? crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : crs.authid(), g.asWkt() ) );
3669 };
3670
3671 if ( !value.isValid() )
3672 return QStringLiteral( "None" );
3673
3674 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
3675 return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( value.value< QgsProperty >().asExpression() ) );
3676
3677 if ( value.userType() == QMetaType::type( "QgsGeometry" ) )
3678 {
3679 const QgsGeometry g = value.value<QgsGeometry>();
3680 if ( !g.isNull() )
3681 return asPythonString( g );
3682 }
3683
3684 if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
3685 {
3686 const QgsReferencedGeometry g = value.value<QgsReferencedGeometry>();
3687 if ( !g.isNull() )
3688 return asPythonString( g, g.crs() );
3689 }
3690
3691 if ( value.userType() == QMetaType::type( "QgsPointXY" ) )
3692 {
3693 const QgsGeometry g = QgsGeometry::fromPointXY( value.value<QgsPointXY>() );
3694 if ( !g.isNull() )
3695 return asPythonString( g );
3696 }
3697
3698 if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) )
3699 {
3701 if ( !g.isNull() )
3702 return asPythonString( g, g.crs() );
3703 }
3704
3705 if ( value.userType() == QMetaType::type( "QgsRectangle" ) )
3706 {
3707 const QgsGeometry g = QgsGeometry::fromRect( value.value<QgsRectangle>() );
3708 if ( !g.isNull() )
3709 return asPythonString( g );
3710 }
3711
3712 if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) )
3713 {
3715 if ( !g.isNull() )
3716 return asPythonString( g, g.crs() );
3717 }
3718
3720}
3721
3723{
3724 QString code = QStringLiteral( "##%1=" ).arg( mName );
3725 if ( mFlags & FlagOptional )
3726 code += QLatin1String( "optional " );
3727 code += type() + ' ';
3728
3729 for ( const int type : mGeomTypes )
3730 {
3731 switch ( static_cast<QgsWkbTypes::GeometryType>( type ) )
3732 {
3734 code += QLatin1String( "point " );
3735 break;
3736
3738 code += QLatin1String( "line " );
3739 break;
3740
3742 code += QLatin1String( "polygon " );
3743 break;
3744
3745 default:
3746 code += QLatin1String( "unknown " );
3747 break;
3748 }
3749 }
3750
3751 code += mDefault.toString();
3752 return code.trimmed();
3753}
3754
3756{
3757 switch ( outputType )
3758 {
3760 {
3761 QString code = QStringLiteral( "QgsProcessingParameterGeometry('%1', %2" )
3763 if ( mFlags & FlagOptional )
3764 code += QLatin1String( ", optional=True" );
3765
3766 if ( !mGeomTypes.empty() )
3767 {
3768 auto geomTypeToString = []( QgsWkbTypes::GeometryType t ) -> QString
3769 {
3770 switch ( t )
3771 {
3773 return QStringLiteral( "PointGeometry" );
3774
3776 return QStringLiteral( "LineGeometry" );
3777
3779 return QStringLiteral( "PolygonGeometry" );
3780
3782 return QStringLiteral( "UnknownGeometry" );
3783
3785 return QStringLiteral( "NullGeometry" );
3786 }
3787 return QString();
3788 };
3789
3790 QStringList options;
3791 options.reserve( mGeomTypes.size() );
3792 for ( const int type : mGeomTypes )
3793 {
3794 options << QStringLiteral( " QgsWkbTypes.%1" ).arg( geomTypeToString( static_cast<QgsWkbTypes::GeometryType>( type ) ) );
3795 }
3796 code += QStringLiteral( ", geometryTypes=[%1 ]" ).arg( options.join( ',' ) );
3797 }
3798
3799 if ( ! mAllowMultipart )
3800 {
3801 code += QLatin1String( ", allowMultipart=False" );
3802 }
3803
3805 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3806 return code;
3807 }
3808 }
3809 return QString();
3810}
3811
3813{
3815 QVariantList types;
3816 for ( const int type : mGeomTypes )
3817 {
3818 types << type;
3819 }
3820 map.insert( QStringLiteral( "geometrytypes" ), types );
3821 map.insert( QStringLiteral( "multipart" ), mAllowMultipart );
3822 return map;
3823}
3824
3826{
3828 mGeomTypes.clear();
3829 const QVariantList values = map.value( QStringLiteral( "geometrytypes" ) ).toList();
3830 for ( const QVariant &val : values )
3831 {
3832 mGeomTypes << val.toInt();
3833 }
3834 mAllowMultipart = map.value( QStringLiteral( "multipart" ) ).toBool();
3835 return true;
3836}
3837
3838QgsProcessingParameterGeometry *QgsProcessingParameterGeometry::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3839{
3840 return new QgsProcessingParameterGeometry( name, description, definition, isOptional );
3841}
3842
3843QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional, const QString &fileFilter )
3844 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3845 , mBehavior( behavior )
3846 , mExtension( fileFilter.isEmpty() ? extension : QString() )
3847 , mFileFilter( fileFilter.isEmpty() && extension.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
3848{
3849
3850}
3851
3853{
3854 return new QgsProcessingParameterFile( *this );
3855}
3856
3858{
3859 if ( !input.isValid() )
3860 return mFlags & FlagOptional;
3861
3862 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
3863 {
3864 return true;
3865 }
3866
3867 const QString string = input.toString().trimmed();
3868
3869 if ( input.type() != QVariant::String || string.isEmpty() )
3870 return mFlags & FlagOptional;
3871
3872 switch ( mBehavior )
3873 {
3874 case File:
3875 {
3876 if ( !mExtension.isEmpty() )
3877 {
3878 return string.endsWith( mExtension, Qt::CaseInsensitive );
3879 }
3880 else if ( !mFileFilter.isEmpty() )
3881 {
3882 return QgsFileUtils::fileMatchesFilter( string, mFileFilter );
3883 }
3884 else
3885 {
3886 return true;
3887 }
3888 }
3889
3890 case Folder:
3891 return true;
3892 }
3893 return true;
3894}
3895
3897{
3898 QString code = QStringLiteral( "##%1=" ).arg( mName );
3899 if ( mFlags & FlagOptional )
3900 code += QLatin1String( "optional " );
3901 code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
3902 code += mDefault.toString();
3903 return code.trimmed();
3904}
3905
3907{
3908 switch ( outputType )
3909 {
3911 {
3912
3913 QString code = QStringLiteral( "QgsProcessingParameterFile('%1', %2" )
3915 if ( mFlags & FlagOptional )
3916 code += QLatin1String( ", optional=True" );
3917 code += QStringLiteral( ", behavior=%1" ).arg( mBehavior == File ? QStringLiteral( "QgsProcessingParameterFile.File" ) : QStringLiteral( "QgsProcessingParameterFile.Folder" ) );
3918 if ( !mExtension.isEmpty() )
3919 code += QStringLiteral( ", extension='%1'" ).arg( mExtension );
3920 if ( !mFileFilter.isEmpty() )
3921 code += QStringLiteral( ", fileFilter='%1'" ).arg( mFileFilter );
3923 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3924 return code;
3925 }
3926 }
3927 return QString();
3928}
3929
3931{
3932 switch ( mBehavior )
3933 {
3934 case File:
3935 {
3936 if ( !mFileFilter.isEmpty() )
3937 return mFileFilter != QObject::tr( "All files (*.*)" ) ? mFileFilter + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" ) : mFileFilter;
3938 else if ( !mExtension.isEmpty() )
3939 return QObject::tr( "%1 files" ).arg( mExtension.toUpper() ) + QStringLiteral( " (*." ) + mExtension.toLower() + QStringLiteral( ");;" ) + QObject::tr( "All files (*.*)" );
3940 else
3941 return QObject::tr( "All files (*.*)" );
3942 }
3943
3944 case Folder:
3945 return QString();
3946 }
3947 return QString();
3948}
3949
3950void QgsProcessingParameterFile::setExtension( const QString &extension )
3951{
3952 mExtension = extension;
3953 mFileFilter.clear();
3954}
3955
3957{
3958 return mFileFilter;
3959}
3960
3962{
3963 mFileFilter = filter;
3964 mExtension.clear();
3965}
3966
3968{
3970 map.insert( QStringLiteral( "behavior" ), mBehavior );
3971 map.insert( QStringLiteral( "extension" ), mExtension );
3972 map.insert( QStringLiteral( "filefilter" ), mFileFilter );
3973 return map;
3974}
3975
3977{
3979 mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
3980 mExtension = map.value( QStringLiteral( "extension" ) ).toString();
3981 mFileFilter = map.value( QStringLiteral( "filefilter" ) ).toString();
3982 return true;
3983}
3984
3985QgsProcessingParameterFile *QgsProcessingParameterFile::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition, QgsProcessingParameterFile::Behavior behavior )
3986{
3987 return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
3988}
3989
3990QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
3991 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3992 , mHeaders( headers )
3993 , mNumberRows( numberRows )
3994 , mFixedNumberRows( fixedNumberRows )
3995{
3996
3997}
3998
4000{
4001 return new QgsProcessingParameterMatrix( *this );
4002}
4003
4005{
4006 if ( !input.isValid() )
4007 return mFlags & FlagOptional;
4008
4009 if ( input.type() == QVariant::String )
4010 {
4011 if ( input.toString().isEmpty() )
4012 return mFlags & FlagOptional;
4013 return true;
4014 }
4015 else if ( input.type() == QVariant::List )
4016 {
4017 if ( input.toList().isEmpty() )
4018 return mFlags & FlagOptional;
4019 return true;
4020 }
4021 else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
4022 {
4023 return true;
4024 }
4025
4026 return false;
4027}
4028
4029QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
4030{
4031 if ( !value.isValid() )
4032 return QStringLiteral( "None" );
4033
4034 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
4035 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4036
4037 QVariantMap p;
4038 p.insert( name(), value );
4039 const QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
4040
4042}
4043
4045{
4046 switch ( outputType )
4047 {
4049 {
4050 QString code = QStringLiteral( "QgsProcessingParameterMatrix('%1', %2" )
4052 if ( mFlags & FlagOptional )
4053 code += QLatin1String( ", optional=True" );
4054 code += QStringLiteral( ", numberRows=%1" ).arg( mNumberRows );
4055 code += QStringLiteral( ", hasFixedNumberRows=%1" ).arg( mFixedNumberRows ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4056
4057 QStringList headers;
4058 headers.reserve( mHeaders.size() );
4059 for ( const QString &h : mHeaders )
4061 code += QStringLiteral( ", headers=[%1]" ).arg( headers.join( ',' ) );
4062
4064 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4065 return code;
4066 }
4067 }
4068 return QString();
4069}
4070
4072{
4073 return mHeaders;
4074}
4075
4076void QgsProcessingParameterMatrix::setHeaders( const QStringList &headers )
4077{
4078 mHeaders = headers;
4079}
4080
4082{
4083 return mNumberRows;
4084}
4085
4087{
4088 mNumberRows = numberRows;
4089}
4090
4092{
4093 return mFixedNumberRows;
4094}
4095
4097{
4098 mFixedNumberRows = fixedNumberRows;
4099}
4100
4102{
4104 map.insert( QStringLiteral( "headers" ), mHeaders );
4105 map.insert( QStringLiteral( "rows" ), mNumberRows );
4106 map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
4107 return map;
4108}
4109
4111{
4113 mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
4114 mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
4115 mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
4116 return true;
4117}
4118
4119QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4120{
4121 return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
4122}
4123
4124QgsProcessingParameterMultipleLayers::QgsProcessingParameterMultipleLayers( const QString &name, const QString &description, QgsProcessing::SourceType layerType, const QVariant &defaultValue, bool optional )
4125 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4126 , mLayerType( layerType )
4127{
4128
4129}
4130
4132{
4133 return new QgsProcessingParameterMultipleLayers( *this );
4134}
4135
4137{
4138 if ( !input.isValid() )
4139 return mFlags & FlagOptional;
4140
4141 if ( mLayerType != QgsProcessing::TypeFile )
4142 {
4143 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
4144 {
4145 return true;
4146 }
4147 }
4148
4149 if ( input.type() == QVariant::String )
4150 {
4151 if ( input.toString().isEmpty() )
4152 return mFlags & FlagOptional;
4153
4154 if ( mMinimumNumberInputs > 1 )
4155 return false;
4156
4157 if ( !context )
4158 return true;
4159
4160 if ( mLayerType != QgsProcessing::TypeFile )
4161 return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
4162 else
4163 return true;
4164 }
4165 else if ( input.type() == QVariant::List )
4166 {
4167 if ( input.toList().count() < mMinimumNumberInputs )
4168 return mFlags & FlagOptional;
4169
4170 if ( mMinimumNumberInputs > input.toList().count() )
4171 return false;
4172
4173 if ( !context )
4174 return true;
4175
4176 if ( mLayerType != QgsProcessing::TypeFile )
4177 {
4178 const auto constToList = input.toList();
4179 for ( const QVariant &v : constToList )
4180 {
4181 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
4182 continue;
4183
4184 if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
4185 return false;
4186 }
4187 }
4188 return true;
4189 }
4190 else if ( input.type() == QVariant::StringList )
4191 {
4192 if ( input.toStringList().count() < mMinimumNumberInputs )
4193 return mFlags & FlagOptional;
4194
4195 if ( mMinimumNumberInputs > input.toStringList().count() )
4196 return false;
4197
4198 if ( !context )
4199 return true;
4200
4201 if ( mLayerType != QgsProcessing::TypeFile )
4202 {
4203 const auto constToStringList = input.toStringList();
4204 for ( const QString &v : constToStringList )
4205 {
4206 if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
4207 return false;
4208 }
4209 }
4210 return true;
4211 }
4212 return false;
4213}
4214
4216{
4217 if ( !value.isValid() )
4218 return QStringLiteral( "None" );
4219
4220 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
4221 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4222
4223 if ( mLayerType == QgsProcessing::TypeFile )
4224 {
4225 QStringList parts;
4226 if ( value.type() == QVariant::StringList )
4227 {
4228 const QStringList list = value.toStringList();
4229 parts.reserve( list.count() );
4230 for ( const QString &v : list )
4232 }
4233 else if ( value.type() == QVariant::List )
4234 {
4235 const QVariantList list = value.toList();
4236 parts.reserve( list.count() );
4237 for ( const QVariant &v : list )
4238 parts << QgsProcessingUtils::stringToPythonLiteral( v.toString() );
4239 }
4240 if ( !parts.isEmpty() )
4241 return parts.join( ',' ).prepend( '[' ).append( ']' );
4242 }
4243 else
4244 {
4245 QVariantMap p;
4246 p.insert( name(), value );
4247 const QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
4248 if ( !list.isEmpty() )
4249 {
4250 QStringList parts;
4251 parts.reserve( list.count() );
4252 for ( const QgsMapLayer *layer : list )
4253 {
4255 }
4256 return parts.join( ',' ).prepend( '[' ).append( ']' );
4257 }
4258 }
4259
4261}
4262
4263QString QgsProcessingParameterMultipleLayers::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
4264{
4266}
4267
4269{
4271}
4272
4274{
4275 QString code = QStringLiteral( "##%1=" ).arg( mName );
4276 if ( mFlags & FlagOptional )
4277 code += QLatin1String( "optional " );
4278 switch ( mLayerType )
4279 {
4281 code += QLatin1String( "multiple raster" );
4282 break;
4283
4285 code += QLatin1String( "multiple file" );
4286 break;
4287
4288 default:
4289 code += QLatin1String( "multiple vector" );
4290 break;
4291 }
4292 code += ' ';
4293 if ( mDefault.type() == QVariant::List )
4294 {
4295 QStringList parts;
4296 const auto constToList = mDefault.toList();
4297 for ( const QVariant &var : constToList )
4298 {
4299 parts << var.toString();
4300 }
4301 code += parts.join( ',' );
4302 }
4303 else if ( mDefault.type() == QVariant::StringList )
4304 {
4305 code += mDefault.toStringList().join( ',' );
4306 }
4307 else
4308 {
4309 code += mDefault.toString();
4310 }
4311 return code.trimmed();
4312}
4313
4315{
4316 switch ( outputType )
4317 {
4319 {
4320 QString code = QStringLiteral( "QgsProcessingParameterMultipleLayers('%1', %2" )
4322 if ( mFlags & FlagOptional )
4323 code += QLatin1String( ", optional=True" );
4324
4325 const QString layerType = QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mLayerType ) );
4326
4327 code += QStringLiteral( ", layerType=%1" ).arg( layerType );
4329 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4330 return code;
4331 }
4332 }
4333 return QString();
4334}
4335
4337{
4338 const QStringList exts;
4339 switch ( mLayerType )
4340 {
4342 return QObject::tr( "All files (*.*)" );
4343
4345 return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4346
4352 return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4353
4355 return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4356
4358 return QgsProviderRegistry::instance()->filePointCloudFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4359
4364 }
4365 return QString();
4366}
4367
4369{
4370 return mLayerType;
4371}
4372
4374{
4375 mLayerType = type;
4376}
4377
4379{
4380 return mMinimumNumberInputs;
4381}
4382
4384{
4385 if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
4386 mMinimumNumberInputs = minimumNumberInputs;
4387}
4388
4390{
4392 map.insert( QStringLiteral( "layer_type" ), mLayerType );
4393 map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
4394 return map;
4395}
4396
4398{
4400 mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
4401 mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
4402 return true;
4403}
4404
4405QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4406{
4407 QString type = definition;
4408 QString defaultVal;
4409 const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
4410 const QRegularExpressionMatch m = re.match( definition );
4411 if ( m.hasMatch() )
4412 {
4413 type = m.captured( 1 ).toLower().trimmed();
4414 defaultVal = m.captured( 2 );
4415 }
4417 if ( type == QLatin1String( "vector" ) )
4419 else if ( type == QLatin1String( "raster" ) )
4421 else if ( type == QLatin1String( "file" ) )
4423 return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
4424}
4425
4426QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
4427 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4428 , mMin( minValue )
4429 , mMax( maxValue )
4430 , mDataType( type )
4431{
4432 if ( mMin >= mMax )
4433 {
4434 QgsMessageLog::logMessage( QObject::tr( "Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg( name ).arg( mMin ).arg( mMax ), QObject::tr( "Processing" ) );
4435 }
4436}
4437
4439{
4440 return new QgsProcessingParameterNumber( *this );
4441}
4442
4444{
4445 QVariant input = value;
4446 if ( !input.isValid() )
4447 {
4448 if ( !defaultValue().isValid() )
4449 return mFlags & FlagOptional;
4450
4451 input = defaultValue();
4452 }
4453
4454 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
4455 {
4456 return true;
4457 }
4458
4459 bool ok = false;
4460 const double res = input.toDouble( &ok );
4461 if ( !ok )
4462 return mFlags & FlagOptional;
4463
4464 return !( res < mMin || res > mMax );
4465}
4466
4468{
4469 if ( !value.isValid() )
4470 return QStringLiteral( "None" );
4471
4472 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
4473 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4474
4475 return value.toString();
4476}
4477
4479{
4481 QStringList parts;
4482 if ( mMin > std::numeric_limits<double>::lowest() + 1 )
4483 parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
4484 if ( mMax < std::numeric_limits<double>::max() )
4485 parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
4486 if ( mDefault.isValid() )
4487 parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
4488 const QString extra = parts.join( QLatin1String( "<br />" ) );
4489 if ( !extra.isEmpty() )
4490 text += QStringLiteral( "<p>%1</p>" ).arg( extra );
4491 return text;
4492}
4493
4495{
4496 switch ( outputType )
4497 {
4499 {
4500 QString code = QStringLiteral( "QgsProcessingParameterNumber('%1', %2" )
4502 if ( mFlags & FlagOptional )
4503 code += QLatin1String( ", optional=True" );
4504
4505 code += QStringLiteral( ", type=%1" ).arg( mDataType == Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
4506
4507 if ( mMin != std::numeric_limits<double>::lowest() + 1 )
4508 code += QStringLiteral( ", minValue=%1" ).arg( mMin );
4509 if ( mMax != std::numeric_limits<double>::max() )
4510 code += QStringLiteral( ", maxValue=%1" ).arg( mMax );
4512 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4513 return code;
4514 }
4515 }
4516 return QString();
4517}
4518
4520{
4521 return mMin;
4522}
4523
4525{
4526 mMin = min;
4527}
4528
4530{
4531 return mMax;
4532}
4533
4535{
4536 mMax = max;
4537}
4538
4540{
4541 return mDataType;
4542}
4543
4545{
4546 mDataType = dataType;
4547}
4548
4550{
4552 map.insert( QStringLiteral( "min" ), mMin );
4553 map.insert( QStringLiteral( "max" ), mMax );
4554 map.insert( QStringLiteral( "data_type" ), mDataType );
4555 return map;
4556}
4557
4559{
4561 mMin = map.value( QStringLiteral( "min" ) ).toDouble();
4562 mMax = map.value( QStringLiteral( "max" ) ).toDouble();
4563 mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4564 return true;
4565}
4566
4567QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4568{
4569 return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
4570 : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4571}
4572
4573QgsProcessingParameterRange::QgsProcessingParameterRange( const QString &name, const QString &description, QgsProcessingParameterNumber::Type type, const QVariant &defaultValue, bool optional )
4574 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4575 , mDataType( type )
4576{
4577
4578}
4579
4581{
4582 return new QgsProcessingParameterRange( *this );
4583}
4584
4586{
4587 if ( !input.isValid() )
4588 return mFlags & FlagOptional;
4589
4590 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
4591 {
4592 return true;
4593 }
4594
4595 if ( input.type() == QVariant::String )
4596 {
4597 const QStringList list = input.toString().split( ',' );
4598 if ( list.count() != 2 )
4599 return mFlags & FlagOptional;
4600 bool ok = false;
4601 list.at( 0 ).toDouble( &ok );
4602 bool ok2 = false;
4603 list.at( 1 ).toDouble( &ok2 );
4604 if ( !ok || !ok2 )
4605 return mFlags & FlagOptional;
4606 return true;
4607 }
4608 else if ( input.type() == QVariant::List )
4609 {
4610 if ( input.toList().count() != 2 )
4611 return mFlags & FlagOptional;
4612
4613 bool ok = false;
4614 input.toList().at( 0 ).toDouble( &ok );
4615 bool ok2 = false;
4616 input.toList().at( 1 ).toDouble( &ok2 );
4617 if ( !ok || !ok2 )
4618 return mFlags & FlagOptional;
4619 return true;
4620 }
4621
4622 return false;
4623}
4624
4625QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
4626{
4627 if ( !value.isValid() )
4628 return QStringLiteral( "None" );
4629
4630 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
4631 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4632
4633 QVariantMap p;
4634 p.insert( name(), value );
4635 const QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
4636
4637 QStringList stringParts;
4638 const auto constParts = parts;
4639 for ( const double v : constParts )
4640 {
4641 stringParts << QString::number( v );
4642 }
4643 return stringParts.join( ',' ).prepend( '[' ).append( ']' );
4644}
4645
4647{
4648 switch ( outputType )
4649 {
4651 {
4652 QString code = QStringLiteral( "QgsProcessingParameterRange('%1', %2" )
4654 if ( mFlags & FlagOptional )
4655 code += QLatin1String( ", optional=True" );
4656
4657 code += QStringLiteral( ", type=%1" ).arg( mDataType == QgsProcessingParameterNumber::Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
4658
4660 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4661 return code;
4662 }
4663 }
4664 return QString();
4665}
4666
4668{
4669 return mDataType;
4670}
4671
4673{
4674 mDataType = dataType;
4675}
4676
4678{
4680 map.insert( QStringLiteral( "data_type" ), mDataType );
4681 return map;
4682}
4683
4685{
4687 mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4688 return true;
4689}
4690
4691QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4692{
4693 return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant()
4694 : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
4695}
4696
4697QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
4698 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4699{
4700
4701}
4702
4704{
4705 return new QgsProcessingParameterRasterLayer( *this );
4706}
4707
4709{
4710 if ( !input.isValid() )
4711 return mFlags & FlagOptional;
4712
4713 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
4714 {
4715 return true;
4716 }
4717
4718 if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
4719 return true;
4720
4721 if ( input.type() != QVariant::String || input.toString().isEmpty() )
4722 return mFlags & FlagOptional;
4723
4724 if ( !context )
4725 {
4726 // that's as far as we can get without a context
4727 return true;
4728 }
4729
4730 // try to load as layer
4731 if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::LayerHint::Raster ) )
4732 return true;
4733
4734 return false;
4735}
4736
4738{
4739 if ( !val.isValid() )
4740 return QStringLiteral( "None" );
4741
4742 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
4743 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
4744
4745 QVariantMap p;
4746 p.insert( name(), val );
4750}
4751
4752QString QgsProcessingParameterRasterLayer::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
4753{
4755}
4756
4758{
4760}
4761
4763{
4764 return QgsProviderRegistry::instance()->fileRasterFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
4765}
4766
4767QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4768{
4769 return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4770}
4771
4772QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional, bool usesStaticStrings )
4773 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4774 , mOptions( options )
4775 , mAllowMultiple( allowMultiple )
4776 , mUsesStaticStrings( usesStaticStrings )
4777{
4778
4779}
4780
4782{
4783 return new QgsProcessingParameterEnum( *this );
4784}
4785
4787{
4788 QVariant input = value;
4789 if ( !input.isValid() )
4790 {
4791 if ( !defaultValue().isValid() )
4792 return mFlags & FlagOptional;
4793
4794 input = defaultValue();
4795 }
4796
4797 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
4798 {
4799 return true;
4800 }
4801
4802 if ( mUsesStaticStrings )
4803 {
4804 if ( input.type() == QVariant::List )
4805 {
4806 if ( !mAllowMultiple )
4807 return false;
4808
4809 const QVariantList values = input.toList();
4810 if ( values.empty() && !( mFlags & FlagOptional ) )
4811 return false;
4812
4813 for ( const QVariant &val : values )
4814 {
4815 if ( !mOptions.contains( val.toString() ) )
4816 return false;
4817 }
4818
4819 return true;
4820 }
4821 else if ( input.type() == QVariant::StringList )
4822 {
4823 if ( !mAllowMultiple )
4824 return false;
4825
4826 const QStringList values = input.toStringList();
4827
4828 if ( values.empty() && !( mFlags & FlagOptional ) )
4829 return false;
4830
4831 if ( values.count() > 1 && !mAllowMultiple )
4832 return false;
4833
4834 for ( const QString &val : values )
4835 {
4836 if ( !mOptions.contains( val ) )
4837 return false;
4838 }
4839 return true;
4840 }
4841 else if ( input.type() == QVariant::String )
4842 {
4843 const QStringList parts = input.toString().split( ',' );
4844 if ( parts.count() > 1 && !mAllowMultiple )
4845 return false;
4846
4847 const auto constParts = parts;
4848 for ( const QString &part : constParts )
4849 {
4850 if ( !mOptions.contains( part ) )
4851 return false;
4852 }
4853 return true;
4854 }
4855 }
4856 else
4857 {
4858 if ( input.type() == QVariant::List )
4859 {
4860 if ( !mAllowMultiple )
4861 return false;
4862
4863 const QVariantList values = input.toList();
4864 if ( values.empty() && !( mFlags & FlagOptional ) )
4865 return false;
4866
4867 for ( const QVariant &val : values )
4868 {
4869 bool ok = false;
4870 const int res = val.toInt( &ok );
4871 if ( !ok )
4872 return false;
4873 else if ( res < 0 || res >= mOptions.count() )
4874 return false;
4875 }
4876
4877 return true;
4878 }
4879 else if ( input.type() == QVariant::String )
4880 {
4881 const QStringList parts = input.toString().split( ',' );
4882 if ( parts.count() > 1 && !mAllowMultiple )
4883 return false;
4884
4885 const auto constParts = parts;
4886 for ( const QString &part : constParts )
4887 {
4888 bool ok = false;
4889 const int res = part.toInt( &ok );
4890 if ( !ok )
4891 return false;
4892 else if ( res < 0 || res >= mOptions.count() )
4893 return false;
4894 }
4895 return true;
4896 }
4897 else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
4898 {
4899 bool ok = false;
4900 const int res = input.toInt( &ok );
4901 if ( !ok )
4902 return false;
4903 else if ( res >= 0 && res < mOptions.count() )
4904 return true;
4905 }
4906 }
4907
4908 return false;
4909}
4910
4912{
4913 if ( !value.isValid() )
4914 return QStringLiteral( "None" );
4915
4916 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
4917 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4918
4919 if ( mUsesStaticStrings )
4920 {
4921 if ( value.type() == QVariant::StringList )
4922 {
4923 QStringList parts;
4924 const QStringList constList = value.toStringList();
4925 for ( const QString &val : constList )
4926 {
4928 }
4929 return parts.join( ',' ).prepend( '[' ).append( ']' );
4930 }
4931 else if ( value.type() == QVariant::String )
4932 {
4933 QStringList parts;
4934 const QStringList constList = value.toString().split( ',' );
4935 if ( constList.count() > 1 )
4936 {
4937 for ( const QString &val : constList )
4938 {
4940 }
4941 return parts.join( ',' ).prepend( '[' ).append( ']' );
4942 }
4943 }
4944
4945 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4946 }
4947 else
4948 {
4949 if ( value.type() == QVariant::List )
4950 {
4951 QStringList parts;
4952 const auto constToList = value.toList();
4953 for ( const QVariant &val : constToList )
4954 {
4955 parts << QString::number( static_cast< int >( val.toDouble() ) );
4956 }
4957 return parts.join( ',' ).prepend( '[' ).append( ']' );
4958 }
4959 else if ( value.type() == QVariant::String )
4960 {
4961 const QStringList parts = value.toString().split( ',' );
4962 if ( parts.count() > 1 )
4963 {
4964 return parts.join( ',' ).prepend( '[' ).append( ']' );
4965 }
4966 }
4967
4968 return QString::number( static_cast< int >( value.toDouble() ) );
4969 }
4970}
4971
4973{
4974 if ( !value.isValid() )
4975 return QString();
4976
4977 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
4978 return QString();
4979
4980 if ( mUsesStaticStrings )
4981 {
4982 return QString();
4983 }
4984 else
4985 {
4986 if ( value.type() == QVariant::List )
4987 {
4988 QStringList parts;
4989 const QVariantList toList = value.toList();
4990 parts.reserve( toList.size() );
4991 for ( const QVariant &val : toList )
4992 {
4993 parts << mOptions.value( static_cast< int >( val.toDouble() ) );
4994 }
4995 return parts.join( ',' );
4996 }
4997 else if ( value.type() == QVariant::String )
4998 {
4999 const QStringList parts = value.toString().split( ',' );
5000 QStringList comments;
5001 if ( parts.count() > 1 )
5002 {
5003 for ( const QString &part : parts )
5004 {
5005 bool ok = false;
5006 const int val = part.toInt( &ok );
5007 if ( ok )
5008 comments << mOptions.value( val );
5009 }
5010 return comments.join( ',' );
5011 }
5012 }
5013
5014 return mOptions.value( static_cast< int >( value.toDouble() ) );
5015 }
5016}
5017
5019{
5020 QString code = QStringLiteral( "##%1=" ).arg( mName );
5021 if ( mFlags & FlagOptional )
5022 code += QLatin1String( "optional " );
5023 code += QLatin1String( "enum " );
5024
5025 if ( mAllowMultiple )
5026 code += QLatin1String( "multiple " );
5027
5028 if ( mUsesStaticStrings )
5029 code += QLatin1String( "static " );
5030
5031 code += mOptions.join( ';' ) + ' ';
5032
5033 code += mDefault.toString();
5034 return code.trimmed();
5035}
5036
5038{
5039 switch ( outputType )
5040 {
5042 {
5043 QString code = QStringLiteral( "QgsProcessingParameterEnum('%1', %2" )
5045 if ( mFlags & FlagOptional )
5046 code += QLatin1String( ", optional=True" );
5047
5048 QStringList options;
5049 options.reserve( mOptions.size() );
5050 for ( const QString &o : mOptions )
5052 code += QStringLiteral( ", options=[%1]" ).arg( options.join( ',' ) );
5053
5054 code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5055
5056 code += QStringLiteral( ", usesStaticStrings=%1" ).arg( mUsesStaticStrings ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5057
5059 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5060
5061 return code;
5062 }
5063 }
5064 return QString();
5065}
5066
5068{
5069 return mOptions;
5070}
5071
5072void QgsProcessingParameterEnum::setOptions( const QStringList &options )
5073{
5074 mOptions = options;
5075}
5076
5078{
5079 return mAllowMultiple;
5080}
5081
5083{
5084 mAllowMultiple = allowMultiple;
5085}
5086
5088{
5089 return mUsesStaticStrings;
5090}
5091
5093{
5094 mUsesStaticStrings = usesStaticStrings;
5095}
5096
5098{
5100 map.insert( QStringLiteral( "options" ), mOptions );
5101 map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5102 map.insert( QStringLiteral( "uses_static_strings" ), mUsesStaticStrings );
5103 return map;
5104}
5105
5107{
5109 mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
5110 mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5111 mUsesStaticStrings = map.value( QStringLiteral( "uses_static_strings" ) ).toBool();
5112 return true;
5113}
5114
5115QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5116{
5117 QString defaultVal;
5118 QString def = definition;
5119
5120 bool multiple = false;
5121 if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5122 {
5123 multiple = true;
5124 def = def.mid( 9 );
5125 }
5126
5127 bool staticStrings = false;
5128 if ( def.startsWith( QLatin1String( "static" ), Qt::CaseInsensitive ) )
5129 {
5130 staticStrings = true;
5131 def = def.mid( 7 );
5132 }
5133
5134 const QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
5135 const QRegularExpressionMatch m = re.match( def );
5136 QString values = def;
5137 if ( m.hasMatch() )
5138 {
5139 values = m.captured( 1 ).trimmed();
5140 defaultVal = m.captured( 2 );
5141 }
5142
5143 return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional, staticStrings );
5144}
5145
5146QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
5147 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5148 , mMultiLine( multiLine )
5149{
5150
5151}
5152
5154{
5155 return new QgsProcessingParameterString( *this );
5156}
5157
5159{
5160 if ( QgsVariantUtils::isNull( value ) )
5161 return QStringLiteral( "None" );
5162
5163 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
5164 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5165
5166 const QString s = value.toString();
5168}
5169
5171{
5172 QString code = QStringLiteral( "##%1=" ).arg( mName );
5173 if ( mFlags & FlagOptional )
5174 code += QLatin1String( "optional " );
5175 code += QLatin1String( "string " );
5176
5177 if ( mMultiLine )
5178 code += QLatin1String( "long " );
5179
5180 code += mDefault.toString();
5181 return code.trimmed();
5182}
5183
5185{
5186 switch ( outputType )
5187 {
5189 {
5190 QString code = QStringLiteral( "QgsProcessingParameterString('%1', %2" )
5192 if ( mFlags & FlagOptional )
5193 code += QLatin1String( ", optional=True" );
5194 code += QStringLiteral( ", multiLine=%1" ).arg( mMultiLine ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5195
5197 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5198 return code;
5199 }
5200 }
5201 return QString();
5202}
5203
5205{
5206 return mMultiLine;
5207}
5208
5210{
5211 mMultiLine = multiLine;
5212}
5213
5215{
5217 map.insert( QStringLiteral( "multiline" ), mMultiLine );
5218 return map;
5219}
5220
5222{
5224 mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
5225 return true;
5226}
5227
5228QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5229{
5230 QString def = definition;
5231 bool multiLine = false;
5232 if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
5233 {
5234 multiLine = true;
5235 def = def.mid( 5 );
5236 }
5237
5238 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5239 def = def.mid( 1 );
5240 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5241 def.chop( 1 );
5242
5243 QVariant defaultValue = def;
5244 if ( def == QLatin1String( "None" ) )
5245 defaultValue = QVariant();
5246
5248}
5249
5250//
5251// QgsProcessingParameterAuthConfig
5252//
5253
5254QgsProcessingParameterAuthConfig::QgsProcessingParameterAuthConfig( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5255 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5256{
5257
5258}
5259
5261{
5262 return new QgsProcessingParameterAuthConfig( *this );
5263}
5264
5266{
5267 if ( !value.isValid() )
5268 return QStringLiteral( "None" );
5269
5270 const QString s = value.toString();
5272}
5273
5275{
5276 QString code = QStringLiteral( "##%1=" ).arg( mName );
5277 if ( mFlags & FlagOptional )
5278 code += QLatin1String( "optional " );
5279 code += QLatin1String( "authcfg " );
5280
5281 code += mDefault.toString();
5282 return code.trimmed();
5283}
5284
5285QgsProcessingParameterAuthConfig *QgsProcessingParameterAuthConfig::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5286{
5287 QString def = definition;
5288
5289 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5290 def = def.mid( 1 );
5291 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5292 def.chop( 1 );
5293
5294 QVariant defaultValue = def;
5295 if ( def == QLatin1String( "None" ) )
5296 defaultValue = QVariant();
5297
5299}
5300
5301
5302//
5303// QgsProcessingParameterExpression
5304//
5305
5306QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
5307 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5308 , mParentLayerParameterName( parentLayerParameterName )
5309{
5310
5311}
5312
5314{
5315 return new QgsProcessingParameterExpression( *this );
5316}
5317
5319{
5320 if ( !value.isValid() )
5321 return QStringLiteral( "None" );
5322
5323 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
5324 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5325
5326 const QString s = value.toString();
5328}
5329
5331{
5332 QStringList depends;
5333 if ( !mParentLayerParameterName.isEmpty() )
5334 depends << mParentLayerParameterName;
5335 return depends;
5336}
5337
5339{
5340 switch ( outputType )
5341 {
5343 {
5344 QString code = QStringLiteral( "QgsProcessingParameterExpression('%1', %2" )
5346 if ( mFlags & FlagOptional )
5347 code += QLatin1String( ", optional=True" );
5348
5349 code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5350
5352 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5353 return code;
5354 }
5355 }
5356 return QString();
5357}
5358
5360{
5361 return mParentLayerParameterName;
5362}
5363
5364void QgsProcessingParameterExpression::setParentLayerParameterName( const QString &parentLayerParameterName )
5365{
5366 mParentLayerParameterName = parentLayerParameterName;
5367}
5368
5370{
5372 map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5373 return map;
5374}
5375
5377{
5379 mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5380 return true;
5381}
5382
5383QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5384{
5385 return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
5386}
5387
5388QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
5389 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5391{
5392
5393}
5394
5396{
5397 return new QgsProcessingParameterVectorLayer( *this );
5398}
5399
5401{
5402 if ( !v.isValid() )
5403 return mFlags & FlagOptional;
5404
5405 QVariant var = v;
5406
5407 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
5408 {
5409 const QgsProperty p = var.value< QgsProperty >();
5411 {
5412 var = p.staticValue();
5413 }
5414 else
5415 {
5416 return true;
5417 }
5418 }
5419
5420 if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
5421 return true;
5422
5423 if ( var.type() != QVariant::String || var.toString().isEmpty() )
5424 return mFlags & FlagOptional;
5425
5426 if ( !context )
5427 {
5428 // that's as far as we can get without a context
5429 return true;
5430 }
5431
5432 // try to load as layer
5434 return true;
5435
5436 return false;
5437}
5438
5440{
5441 if ( !val.isValid() )
5442 return QStringLiteral( "None" );
5443
5444 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
5445 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
5446
5447 QVariantMap p;
5448 p.insert( name(), val );
5452}
5453
5454QString QgsProcessingParameterVectorLayer::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
5455{
5457}
5458
5460{
5462}
5463
5465{
5466 switch ( outputType )
5467 {
5469 {
5470 QString code = QStringLiteral( "QgsProcessingParameterVectorLayer('%1', %2" )
5472 if ( mFlags & FlagOptional )
5473 code += QLatin1String( ", optional=True" );
5474
5475 if ( !mDataTypes.empty() )
5476 {
5477 QStringList options;
5478 for ( const int t : mDataTypes )
5479 options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
5480 code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
5481 }
5482
5484 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5485 return code;
5486 }
5487 }
5488 return QString();
5489}
5490
5492{
5493 return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5494}
5495
5497{
5498 return mDataTypes;
5499}
5500
5502{
5503 mDataTypes = types;
5504}
5505
5507{
5509 QVariantList types;
5510 for ( const int type : mDataTypes )
5511 {
5512 types << type;
5513 }
5514 map.insert( QStringLiteral( "data_types" ), types );
5515 return map;
5516}
5517
5519{
5521 mDataTypes.clear();
5522 const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
5523 for ( const QVariant &val : values )
5524 {
5525 mDataTypes << val.toInt();
5526 }
5527 return true;
5528}
5529
5530QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5531{
5532 return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
5533}
5534
5535QgsProcessingParameterMeshLayer::QgsProcessingParameterMeshLayer( const QString &name, const QString &description,
5536 const QVariant &defaultValue, bool optional )
5537 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5538{
5539
5540}
5541
5543{
5544 return new QgsProcessingParameterMeshLayer( *this );
5545}
5546
5548{
5549 if ( !v.isValid() )
5550 return mFlags & FlagOptional;
5551
5552 QVariant var = v;
5553
5554 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
5555 {
5556 const QgsProperty p = var.value< QgsProperty >();
5558 {
5559 var = p.staticValue();
5560 }
5561 else
5562 {
5563 return true;
5564 }
5565 }
5566
5567 if ( qobject_cast< QgsMeshLayer * >( qvariant_cast<QObject *>( var ) ) )
5568 return true;
5569
5570 if ( var.type() != QVariant::String || var.toString().isEmpty() )
5571 return mFlags & FlagOptional;
5572
5573 if ( !context )
5574 {
5575 // that's as far as we can get without a context
5576 return true;
5577 }
5578
5579 // try to load as layer
5580 if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Mesh ) )
5581 return true;
5582
5583 return false;
5584}
5585
5587{
5588 if ( !val.isValid() )
5589 return QStringLiteral( "None" );
5590
5591 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
5592 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
5593
5594 QVariantMap p;
5595 p.insert( name(), val );
5599}
5600
5601QString QgsProcessingParameterMeshLayer::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
5602{
5604}
5605
5606QVariant QgsProcessingParameterMeshLayer::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const
5607{
5609}
5610
5612{
5613 return QgsProviderRegistry::instance()->fileMeshFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
5614}
5615
5616QgsProcessingParameterMeshLayer *QgsProcessingParameterMeshLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5617{
5618 return new QgsProcessingParameterMeshLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
5619}
5620
5621QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional, bool defaultToAllFields )
5622 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5623 , mParentLayerParameterName( parentLayerParameterName )
5624 , mDataType( type )
5625 , mAllowMultiple( allowMultiple )
5626 , mDefaultToAllFields( defaultToAllFields )
5627{
5628
5629}
5630
5631
5633{
5634 return new QgsProcessingParameterField( *this );
5635}
5636
5638{
5639 if ( !input.isValid() )
5640 return mFlags & FlagOptional;
5641
5642 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
5643 {
5644 return true;
5645 }
5646
5647 if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
5648 {
5649 if ( !mAllowMultiple )
5650 return false;
5651
5652 if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
5653 return false;
5654 }
5655 else if ( input.type() == QVariant::String )
5656 {
5657 if ( input.toString().isEmpty() )
5658 return mFlags & FlagOptional;
5659
5660 const QStringList parts = input.toString().split( ';' );
5661 if ( parts.count() > 1 && !mAllowMultiple )
5662 return false;
5663 }
5664 else
5665 {
5666 if ( input.toString().isEmpty() )
5667 return mFlags & FlagOptional;
5668 }
5669 return true;
5670}
5671
5673{
5674 if ( !value.isValid() )
5675 return QStringLiteral( "None" );
5676
5677 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
5678 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5679
5680 if ( value.type() == QVariant::List )
5681 {
5682 QStringList parts;
5683 const auto constToList = value.toList();
5684 for ( const QVariant &val : constToList )
5685 {
5686 parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
5687 }
5688 return parts.join( ',' ).prepend( '[' ).append( ']' );
5689 }
5690 else if ( value.type() == QVariant::StringList )
5691 {
5692 QStringList parts;
5693 const auto constToStringList = value.toStringList();
5694 for ( const QString &s : constToStringList )
5695 {
5697 }
5698 return parts.join( ',' ).prepend( '[' ).append( ']' );
5699 }
5700
5701 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
5702}
5703
5705{
5706 QString code = QStringLiteral( "##%1=" ).arg( mName );
5707 if ( mFlags & FlagOptional )
5708 code += QLatin1String( "optional " );
5709 code += QLatin1String( "field " );
5710
5711 switch ( mDataType )
5712 {
5713 case Numeric:
5714 code += QLatin1String( "numeric " );
5715 break;
5716
5717 case String:
5718 code += QLatin1String( "string " );
5719 break;
5720
5721 case DateTime:
5722 code += QLatin1String( "datetime " );
5723 break;
5724
5725 case Any:
5726 break;
5727 }
5728
5729 if ( mAllowMultiple )
5730 code += QLatin1String( "multiple " );
5731
5732 if ( mDefaultToAllFields )
5733 code += QLatin1String( "default_to_all_fields " );
5734
5735 code += mParentLayerParameterName + ' ';
5736
5737 code += mDefault.toString();
5738 return code.trimmed();
5739}
5740
5742{
5743 switch ( outputType )
5744 {
5746 {
5747 QString code = QStringLiteral( "QgsProcessingParameterField('%1', %2" )
5749 if ( mFlags & FlagOptional )
5750 code += QLatin1String( ", optional=True" );
5751
5752 QString dataType;
5753 switch ( mDataType )
5754 {
5755 case Any:
5756 dataType = QStringLiteral( "QgsProcessingParameterField.Any" );
5757 break;
5758
5759 case Numeric:
5760 dataType = QStringLiteral( "QgsProcessingParameterField.Numeric" );
5761 break;
5762
5763 case String:
5764 dataType = QStringLiteral( "QgsProcessingParameterField.String" );
5765 break;
5766
5767 case DateTime:
5768 dataType = QStringLiteral( "QgsProcessingParameterField.DateTime" );
5769 break;
5770 }
5771 code += QStringLiteral( ", type=%1" ).arg( dataType );
5772
5773 code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5774 code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5776 code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
5777
5778 if ( mDefaultToAllFields )
5779 code += QLatin1String( ", defaultToAllFields=True" );
5780
5781 code += ')';
5782
5783 return code;
5784 }
5785 }
5786 return QString();
5787}
5788
5790{
5791 QStringList depends;
5792 if ( !mParentLayerParameterName.isEmpty() )
5793 depends << mParentLayerParameterName;
5794 return depends;
5795}
5796
5798{
5799 return mParentLayerParameterName;
5800}
5801
5802void QgsProcessingParameterField::setParentLayerParameterName( const QString &parentLayerParameterName )
5803{
5804 mParentLayerParameterName = parentLayerParameterName;
5805}
5806
5808{
5809 return mDataType;
5810}
5811
5813{
5814 mDataType = dataType;
5815}
5816
5818{
5819 return mAllowMultiple;
5820}
5821
5823{
5824 mAllowMultiple = allowMultiple;
5825}
5826
5828{
5829 return mDefaultToAllFields;
5830}
5831
5833{
5834 mDefaultToAllFields = enabled;
5835}
5836
5838{
5840 map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5841 map.insert( QStringLiteral( "data_type" ), mDataType );
5842 map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5843 map.insert( QStringLiteral( "default_to_all_fields" ), mDefaultToAllFields );
5844 return map;
5845}
5846
5848{
5850 mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5851 mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5852 mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5853 mDefaultToAllFields = map.value( QStringLiteral( "default_to_all_fields" ) ).toBool();
5854 return true;
5855}
5856
5857QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5858{
5859 QString parent;
5860 DataType type = Any;
5861 bool allowMultiple = false;
5862 bool defaultToAllFields = false;
5863 QString def = definition;
5864
5865 if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
5866 {
5867 type = Numeric;
5868 def = def.mid( 8 );
5869 }
5870 else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
5871 {
5872 type = String;
5873 def = def.mid( 7 );
5874 }
5875 else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
5876 {
5877 type = DateTime;
5878 def = def.mid( 9 );
5879 }
5880
5881 if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5882 {
5883 allowMultiple = true;
5884 def = def.mid( 8 ).trimmed();
5885 }
5886
5887 if ( def.startsWith( QLatin1String( "default_to_all_fields" ), Qt::CaseInsensitive ) )
5888 {
5889 defaultToAllFields = true;
5890 def = def.mid( 21 ).trimmed();
5891 }
5892
5893 const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
5894 const QRegularExpressionMatch m = re.match( def );
5895 if ( m.hasMatch() )
5896 {
5897 parent = m.captured( 1 ).trimmed();
5898 def = m.captured( 2 );
5899 }
5900 else
5901 {
5902 parent = def;
5903 def.clear();
5904 }
5905
5906 return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional, defaultToAllFields );
5907}
5908
5909QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
5910 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5912{
5913
5914}
5915
5917{
5918 return new QgsProcessingParameterFeatureSource( *this );
5919}
5920
5922{
5923 QVariant var = input;
5924 if ( !var.isValid() )
5925 return mFlags & FlagOptional;
5926
5927 if ( var.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
5928 {
5929 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
5930 var = fromVar.source;
5931 }
5932 else if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
5933 {
5934 // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
5935 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
5936 var = fromVar.sink;
5937 }
5938
5939 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
5940 {
5941 const QgsProperty p = var.value< QgsProperty >();
5943 {
5944 var = p.staticValue();
5945 }
5946 else
5947 {
5948 return true;
5949 }
5950 }
5951 if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
5952 {
5953 return true;
5954 }
5955
5956 if ( var.type() != QVariant::String || var.toString().isEmpty() )
5957 return mFlags & FlagOptional;
5958
5959 if ( !context )
5960 {
5961 // that's as far as we can get without a context
5962 return true;
5963 }
5964
5965 // try to load as layer
5967 return true;
5968
5969 return false;
5970}
5971
5973{
5974 if ( !value.isValid() )
5975 return QStringLiteral( "None" );
5976
5977 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
5978 return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( value.value< QgsProperty >().asExpression() ) );
5979
5980 if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) )
5981 {
5982 const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
5983 QString geometryCheckString;
5984 switch ( fromVar.geometryCheck )
5985 {
5987 geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryNoCheck" );
5988 break;
5989
5991 geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometrySkipInvalid" );
5992 break;
5993
5995 geometryCheckString = QStringLiteral( "QgsFeatureRequest.GeometryAbortOnInvalid" );
5996 break;
5997 }
5998
5999 QStringList flags;
6000 QString flagString;
6001 if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck )
6002 flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagOverrideDefaultGeometryCheck" );
6003 if ( fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature )
6004 flags << QStringLiteral( "QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature" );
6005 if ( !flags.empty() )
6006 flagString = flags.join( QLatin1String( " | " ) );
6007
6009 {
6010 QString layerString = fromVar.source.staticValue().toString();
6011 // prefer to use layer source instead of id if possible (since it's persistent)
6012 if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
6013 layerString = layer->source();
6014
6015 if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
6016 {
6017 return QStringLiteral( "QgsProcessingFeatureSourceDefinition(%1, selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" ).arg( QgsProcessingUtils::stringToPythonLiteral( layerString ),
6018 fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
6019 QString::number( fromVar.featureLimit ),
6020 flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
6021 geometryCheckString );
6022 }
6023 else
6024 {
6025 return QgsProcessingUtils::stringToPythonLiteral( layerString );
6026 }
6027 }
6028 else
6029 {
6030 if ( fromVar.selectedFeaturesOnly || fromVar.featureLimit != -1 || fromVar.flags )
6031 {
6032 return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression(%1), selectedFeaturesOnly=%2, featureLimit=%3%4, geometryCheck=%5)" )
6034 fromVar.selectedFeaturesOnly ? QStringLiteral( "True" ) : QStringLiteral( "False" ),
6035 QString::number( fromVar.featureLimit ),
6036 flagString.isEmpty() ? QString() : ( QStringLiteral( ", flags=%1" ).arg( flagString ) ),
6037 geometryCheckString );
6038 }
6039 else
6040 {
6041 return QStringLiteral( "QgsProperty.fromExpression(%1)" ).arg( QgsProcessingUtils::stringToPythonLiteral( fromVar.source.asExpression() ) );
6042 }
6043 }
6044 }
6045 else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
6046 {
6047 return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
6048 }
6049
6050 QString layerString = value.toString();
6051
6052 // prefer to use layer source if possible (since it's persistent)
6053 if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
6054 layerString = layer->providerType() != QLatin1String( "ogr" ) && layer->providerType() != QLatin1String( "gdal" ) && layer->providerType() != QLatin1String( "mdal" ) ? QgsProcessingUtils::encodeProviderKeyAndUri( layer->providerType(), layer->source() ) : layer->source();
6055
6056 return QgsProcessingUtils::stringToPythonLiteral( layerString );
6057}
6058
6059QString QgsProcessingParameterFeatureSource::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
6060{
6062}
6063
6065{
6067}
6068
6070{
6071 QString code = QStringLiteral( "##%1=" ).arg( mName );
6072 if ( mFlags & FlagOptional )
6073 code += QLatin1String( "optional " );
6074 code += QLatin1String( "source " );
6075
6076 for ( const int type : mDataTypes )
6077 {
6078 switch ( type )
6079 {
6081 code += QLatin1String( "point " );
6082 break;
6083
6085 code += QLatin1String( "line " );
6086 break;
6087
6089 code += QLatin1String( "polygon " );
6090 break;
6091
6092 }
6093 }
6094
6095 code += mDefault.toString();
6096 return code.trimmed();
6097}
6098
6100{
6101 switch ( outputType )
6102 {
6104 {
6105 QString code = QStringLiteral( "QgsProcessingParameterFeatureSource('%1', %2" )
6107 if ( mFlags & FlagOptional )
6108 code += QLatin1String( ", optional=True" );
6109
6110 if ( !mDataTypes.empty() )
6111 {
6112 QStringList options;
6113 options.reserve( mDataTypes.size() );
6114 for ( const int t : mDataTypes )
6115 options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
6116 code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
6117 }
6118
6120 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6121 return code;
6122 }
6123 }
6124 return QString();
6125}
6126
6128{
6129 return QgsProviderRegistry::instance()->fileVectorFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6130}
6131
6133 : mDataTypes( types )
6134{
6135
6136}
6137
6139{
6141 QVariantList types;
6142 for ( const int type : mDataTypes )
6143 {
6144 types << type;
6145 }
6146 map.insert( QStringLiteral( "data_types" ), types );
6147 return map;
6148}
6149
6151{
6153 mDataTypes.clear();
6154 const QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
6155 for ( const QVariant &val : values )
6156 {
6157 mDataTypes << val.toInt();
6158 }
6159 return true;
6160}
6161
6162QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6163{
6164 QList< int > types;
6165 QString def = definition;
6166 while ( true )
6167 {
6168 if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
6169 {
6171 def = def.mid( 6 );
6172 continue;
6173 }
6174 else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
6175 {
6177 def = def.mid( 5 );
6178 continue;
6179 }
6180 else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
6181 {
6183 def = def.mid( 8 );
6184 continue;
6185 }
6186 break;
6187 }
6188
6189 return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
6190}
6191
6192QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault, bool supportsAppend )
6193 : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6194 , mDataType( type )
6195 , mSupportsAppend( supportsAppend )
6196{
6197}
6198
6200{
6201 return new QgsProcessingParameterFeatureSink( *this );
6202}
6203
6205{
6206 QVariant var = input;
6207 if ( !var.isValid() )
6208 return mFlags & FlagOptional;
6209
6210 if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6211 {
6212 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6213 var = fromVar.sink;
6214 }
6215
6216 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
6217 {
6218 const QgsProperty p = var.value< QgsProperty >();
6220 {
6221 var = p.staticValue();
6222 }
6223 else
6224 {
6225 return true;
6226 }
6227 }
6228
6229 if ( var.type() != QVariant::String )
6230 return false;
6231
6232 if ( var.toString().isEmpty() )
6233 return mFlags & FlagOptional;
6234
6235 return true;
6236}
6237
6239{
6240 if ( !value.isValid() )
6241 return QStringLiteral( "None" );
6242
6243 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
6244 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6245
6246 if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6247 {
6248 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6250 {
6251 return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6252 }
6253 else
6254 {
6255 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6256 }
6257 }
6258
6259 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6260}
6261
6263{
6264 QString code = QStringLiteral( "##%1=" ).arg( mName );
6265 if ( mFlags & FlagOptional )
6266 code += QLatin1String( "optional " );
6267 code += QLatin1String( "sink " );
6268
6269 switch ( mDataType )
6270 {
6272 code += QLatin1String( "point " );
6273 break;
6274
6276 code += QLatin1String( "line " );
6277 break;
6278
6280 code += QLatin1String( "polygon " );
6281 break;
6282
6284 code += QLatin1String( "table " );
6285 break;
6286
6287 default:
6288 break;
6289 }
6290
6291 code += mDefault.toString();
6292 return code.trimmed();
6293}
6294
6296{
6297 return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
6298}
6299
6301{
6302 if ( auto *lOriginalProvider = originalProvider() )
6303 {
6304 return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
6305 }
6306 else if ( QgsProcessingProvider *p = provider() )
6307 {
6308 return p->defaultVectorFileExtension( hasGeometry() );
6309 }
6310 else
6311 {
6312 if ( hasGeometry() )
6313 {
6315 }
6316 else
6317 {
6318 return QStringLiteral( "dbf" );
6319 }
6320 }
6321}
6322
6324{
6325 switch ( outputType )
6326 {
6328 {
6329 QString code = QStringLiteral( "QgsProcessingParameterFeatureSink('%1', %2" )
6331 if ( mFlags & FlagOptional )
6332 code += QLatin1String( ", optional=True" );
6333
6334 code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
6335
6336 code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6337 if ( mSupportsAppend )
6338 code += QLatin1String( ", supportsAppend=True" );
6339
6341 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6342 return code;
6343 }
6344 }
6345 return QString();
6346}
6347
6349{
6350 const QStringList exts = supportedOutputVectorLayerExtensions();
6351 QStringList filters;
6352 for ( const QString &ext : exts )
6353 {
6354 filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6355 }
6356 return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6357
6358}
6359
6361{
6362 if ( auto *lOriginalProvider = originalProvider() )
6363 {
6364 if ( hasGeometry() )
6365 return lOriginalProvider->supportedOutputVectorLayerExtensions();
6366 else
6367 return lOriginalProvider->supportedOutputTableExtensions();
6368 }
6369 else if ( QgsProcessingProvider *p = provider() )
6370 {
6371 if ( hasGeometry() )
6372 return p->supportedOutputVectorLayerExtensions();
6373 else
6374 return p->supportedOutputTableExtensions();
6375 }
6376 else
6377 {
6379 }
6380}
6381
6383{
6384 return mDataType;
6385}
6386
6388{
6389 switch ( mDataType )
6390 {
6396 return true;
6397
6405 return false;
6406 }
6407 return true;
6408}
6409
6411{
6412 mDataType = type;
6413}
6414
6416{
6418 map.insert( QStringLiteral( "data_type" ), mDataType );
6419 map.insert( QStringLiteral( "supports_append" ), mSupportsAppend );
6420 return map;
6421}
6422
6424{
6426 mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
6427 mSupportsAppend = map.value( QStringLiteral( "supports_append" ), false ).toBool();
6428 return true;
6429}
6430
6432{
6434 return QStringLiteral( "memory:%1" ).arg( description() );
6435 else
6437}
6438
6439QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6440{
6442 QString def = definition;
6443 if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
6444 {
6446 def = def.mid( 6 );
6447 }
6448 else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
6449 {
6451 def = def.mid( 5 );
6452 }
6453 else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
6454 {
6456 def = def.mid( 8 );
6457 }
6458 else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
6459 {
6461 def = def.mid( 6 );
6462 }
6463
6464 return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
6465}
6466
6468{
6469 return mSupportsAppend;
6470}
6471
6473{
6474 mSupportsAppend = supportsAppend;
6475}
6476
6477QgsProcessingParameterRasterDestination::QgsProcessingParameterRasterDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6478 : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6479{
6480}
6481
6483{
6484 return new QgsProcessingParameterRasterDestination( *this );
6485}
6486
6488{
6489 QVariant var = input;
6490 if ( !var.isValid() )
6491 return mFlags & FlagOptional;
6492
6493 if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6494 {
6495 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6496 var = fromVar.sink;
6497 }
6498
6499 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
6500 {
6501 const QgsProperty p = var.value< QgsProperty >();
6503 {
6504 var = p.staticValue();
6505 }
6506 else
6507 {
6508 return true;
6509 }
6510 }
6511
6512 if ( var.type() != QVariant::String )
6513 return false;
6514
6515 if ( var.toString().isEmpty() )
6516 return mFlags & FlagOptional;
6517
6518 return true;
6519}
6520
6522{
6523 if ( !value.isValid() )
6524 return QStringLiteral( "None" );
6525
6526 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
6527 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6528
6529 if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6530 {
6531 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6533 {
6534 return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6535 }
6536 else
6537 {
6538 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6539 }
6540 }
6541
6542 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6543}
6544
6546{
6548}
6549
6551{
6552 if ( auto *lOriginalProvider = originalProvider() )
6553 {
6554 return lOriginalProvider->defaultRasterFileExtension();
6555 }
6556 else if ( QgsProcessingProvider *p = provider() )
6557 {
6558 return p->defaultRasterFileExtension();
6559 }
6560 else
6561 {
6563 }
6564}
6565
6567{
6568 const QStringList exts = supportedOutputRasterLayerExtensions();
6569 QStringList filters;
6570 for ( const QString &ext : exts )
6571 {
6572 filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
6573 }
6574 return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
6575}
6576
6578{
6579 if ( auto *lOriginalProvider = originalProvider() )
6580 {
6581 return lOriginalProvider->supportedOutputRasterLayerExtensions();
6582 }
6583 else if ( QgsProcessingProvider *p = provider() )
6584 {
6585 return p->supportedOutputRasterLayerExtensions();
6586 }
6587 else
6588 {
6590 }
6591}
6592
6593QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6594{
6595 return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6596}
6597
6598
6599QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
6600 : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6601 , mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
6602{
6603
6604}
6605
6607{
6608 return new QgsProcessingParameterFileDestination( *this );
6609}
6610
6612{
6613 QVariant var = input;
6614 if ( !var.isValid() )
6615 return mFlags & FlagOptional;
6616
6617 if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6618 {
6619 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6620 var = fromVar.sink;
6621 }
6622
6623 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
6624 {
6625 const QgsProperty p = var.value< QgsProperty >();
6627 {
6628 var = p.staticValue();
6629 }
6630 else
6631 {
6632 return true;
6633 }
6634 }
6635
6636 if ( var.type() != QVariant::String )
6637 return false;
6638
6639 if ( var.toString().isEmpty() )
6640 return mFlags & FlagOptional;
6641
6642 // possible enhancement - check that value is compatible with file filter?
6643
6644 return true;
6645}
6646
6648{
6649 if ( !value.isValid() )
6650 return QStringLiteral( "None" );
6651
6652 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
6653 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6654
6655 if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6656 {
6657 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6659 {
6660 return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6661 }
6662 else
6663 {
6664 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6665 }
6666 }
6667
6668 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6669}
6670
6672{
6673 if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
6674 {
6675 return new QgsProcessingOutputHtml( name(), description() );
6676 }
6677 else
6678 {
6679 return new QgsProcessingOutputFile( name(), description() );
6680 }
6681}
6682
6684{
6685 if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
6686 return QStringLiteral( "file" );
6687
6688 // get first extension from filter
6689 const QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
6690 const QRegularExpressionMatch match = rx.match( mFileFilter );
6691 if ( !match.hasMatch() )
6692 return QStringLiteral( "file" );
6693
6694 return match.captured( 1 );
6695}
6696
6698{
6699 switch ( outputType )
6700 {
6702 {
6703 QString code = QStringLiteral( "QgsProcessingParameterFileDestination('%1', %2" )
6705 if ( mFlags & FlagOptional )
6706 code += QLatin1String( ", optional=True" );
6707
6708 code += QStringLiteral( ", fileFilter=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mFileFilter ) );
6709
6710 code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6711
6713 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6714 return code;
6715 }
6716 }
6717 return QString();
6718}
6719
6721{
6722 return ( fileFilter().isEmpty() ? QString() : fileFilter() + QStringLiteral( ";;" ) ) + QObject::tr( "All files (*.*)" );
6723}
6724
6726{
6727 return mFileFilter;
6728}
6729
6731{
6732 mFileFilter = fileFilter;
6733}
6734
6736{
6738 map.insert( QStringLiteral( "file_filter" ), mFileFilter );
6739 return map;
6740}
6741
6743{
6745 mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
6746 return true;
6747
6748}
6749
6750QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6751{
6752 return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
6753}
6754
6755QgsProcessingParameterFolderDestination::QgsProcessingParameterFolderDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6756 : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6757{}
6758
6760{
6761 return new QgsProcessingParameterFolderDestination( *this );
6762}
6763
6765{
6766 QVariant var = input;
6767 if ( !var.isValid() )
6768 return mFlags & FlagOptional;
6769
6770 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
6771 {
6772 const QgsProperty p = var.value< QgsProperty >();
6774 {
6775 var = p.staticValue();
6776 }
6777 else
6778 {
6779 return true;
6780 }
6781 }
6782
6783 if ( var.type() != QVariant::String )
6784 return false;
6785
6786 if ( var.toString().isEmpty() )
6787 return mFlags & FlagOptional;
6788
6789 return true;
6790}
6791
6793{
6794 return new QgsProcessingOutputFolder( name(), description() );
6795}
6796
6798{
6799 return QString();
6800}
6801
6802QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
6803{
6804 return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
6805}
6806
6807QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
6808 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
6809 , mCreateByDefault( createByDefault )
6810{
6811
6812}
6813
6815{
6817 map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
6818 map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
6819 return map;
6820}
6821
6823{
6825 mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
6826 mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
6827 return true;
6828}
6829
6831{
6832 switch ( outputType )
6833 {
6835 {
6836 // base class method is probably not much use
6838 {
6839 QString code = t->className() + QStringLiteral( "('%1', %2" )
6841 if ( mFlags & FlagOptional )
6842 code += QLatin1String( ", optional=True" );
6843
6844 code += QStringLiteral( ", createByDefault=%1" ).arg( mCreateByDefault ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
6845
6847 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
6848 return code;
6849 }
6850 break;
6851 }
6852 }
6853 // oh well, we tried
6854 return QString();
6855}
6856
6858{
6859 return QObject::tr( "Default extension" ) + QStringLiteral( " (*." ) + defaultFileExtension() + ')';
6860}
6861
6863{
6864 // sanitize name to avoid multiple . in the filename. E.g. when name() contain
6865 // backend command name having a "." inside as in case of grass commands
6866 const QRegularExpression rx( QStringLiteral( "[.]" ) );
6867 QString sanitizedName = name();
6868 sanitizedName.replace( rx, QStringLiteral( "_" ) );
6869
6870 if ( defaultFileExtension().isEmpty() )
6871 {
6872 return QgsProcessingUtils::generateTempFilename( sanitizedName );
6873 }
6874 else
6875 {
6876 return QgsProcessingUtils::generateTempFilename( sanitizedName + '.' + defaultFileExtension() );
6877 }
6878}
6879
6880bool QgsProcessingDestinationParameter::isSupportedOutputValue( const QVariant &value, QgsProcessingContext &context, QString &error ) const
6881{
6882 if ( auto *lOriginalProvider = originalProvider() )
6883 return lOriginalProvider->isSupportedOutputValue( value, this, context, error );
6884 else if ( provider() )
6885 return provider()->isSupportedOutputValue( value, this, context, error );
6886
6887 return true;
6888}
6889
6891{
6892 return mCreateByDefault;
6893}
6894
6896{
6897 mCreateByDefault = createByDefault;
6898}
6899
6900QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
6901 : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
6902 , mDataType( type )
6903{
6904
6905}
6906
6908{
6909 return new QgsProcessingParameterVectorDestination( *this );
6910}
6911
6913{
6914 QVariant var = input;
6915 if ( !var.isValid() )
6916 return mFlags & FlagOptional;
6917
6918 if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6919 {
6920 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
6921 var = fromVar.sink;
6922 }
6923
6924 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
6925 {
6926 const QgsProperty p = var.value< QgsProperty >();
6928 {
6929 var = p.staticValue();
6930 }
6931 else
6932 {
6933 return true;
6934 }
6935 }
6936
6937 if ( var.type() != QVariant::String )
6938 return false;
6939
6940 if ( var.toString().isEmpty() )
6941 return mFlags & FlagOptional;
6942
6943 return true;
6944}
6945
6947{
6948 if ( !value.isValid() )
6949 return QStringLiteral( "None" );
6950
6951 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
6952 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
6953
6954 if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
6955 {
6956 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
6958 {
6959 return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
6960 }
6961 else
6962 {
6963 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
6964 }
6965 }
6966
6967 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
6968}
6969
6971{
6972 QString code = QStringLiteral( "##%1=" ).arg( mName );
6973 if ( mFlags & FlagOptional )
6974 code += QLatin1String( "optional " );
6975 code += QLatin1String( "vectorDestination " );
6976
6977 switch ( mDataType )
6978 {
6980 code += QLatin1String( "point " );
6981 break;
6982
6984 code += QLatin1String( "line " );
6985 break;
6986
6988 code += QLatin1String( "polygon " );
6989 break;
6990
6991 default:
6992 break;
6993 }
6994
6995 code += mDefault.toString();
6996 return code.trimmed();
6997}
6998
7000{
7001 return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
7002}
7003
7005{
7006 if ( auto *lOriginalProvider = originalProvider() )
7007 {
7008 return lOriginalProvider->defaultVectorFileExtension( hasGeometry() );
7009 }
7010 else if ( QgsProcessingProvider *p = provider() )
7011 {
7012 return p->defaultVectorFileExtension( hasGeometry() );
7013 }
7014 else
7015 {
7016 if ( hasGeometry() )
7017 {
7019 }
7020 else
7021 {
7022 return QStringLiteral( "dbf" );
7023 }
7024 }
7025}
7026
7028{
7029 switch ( outputType )
7030 {
7032 {
7033 QString code = QStringLiteral( "QgsProcessingParameterVectorDestination('%1', %2" )
7035 if ( mFlags & FlagOptional )
7036 code += QLatin1String( ", optional=True" );
7037
7038 code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
7039
7040 code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7041
7043 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7044 return code;
7045 }
7046 }
7047 return QString();
7048}
7049
7051{
7052 const QStringList exts = supportedOutputVectorLayerExtensions();
7053 QStringList filters;
7054 for ( const QString &ext : exts )
7055 {
7056 filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
7057 }
7058 return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
7059}
7060
7062{
7063 if ( auto *lOriginalProvider = originalProvider() )
7064 {
7065 if ( hasGeometry() )
7066 return lOriginalProvider->supportedOutputVectorLayerExtensions();
7067 else
7068 return lOriginalProvider->supportedOutputTableExtensions();
7069 }
7070 else if ( QgsProcessingProvider *p = provider() )
7071 {
7072 if ( hasGeometry() )
7073 return p->supportedOutputVectorLayerExtensions();
7074 else
7075 return p->supportedOutputTableExtensions();
7076 }
7077 else
7078 {
7080 }
7081}
7082
7084{
7085 return mDataType;
7086}
7087
7089{
7090 switch ( mDataType )
7091 {
7097 return true;
7098
7106 return false;
7107 }
7108 return true;
7109}
7110
7112{
7113 mDataType = type;
7114}
7115
7117{
7119 map.insert( QStringLiteral( "data_type" ), mDataType );
7120 return map;
7121}
7122
7124{
7126 mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
7127 return true;
7128}
7129
7130QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7131{
7133 QString def = definition;
7134 if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
7135 {
7137 def = def.mid( 6 );
7138 }
7139 else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
7140 {
7142 def = def.mid( 5 );
7143 }
7144 else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
7145 {
7147 def = def.mid( 8 );
7148 }
7149
7150 return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
7151}
7152
7153QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
7154 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7155 , mParentLayerParameterName( parentLayerParameterName )
7156 , mAllowMultiple( allowMultiple )
7157{
7158
7159}
7160
7162{
7163 return new QgsProcessingParameterBand( *this );
7164}
7165
7167{
7168 if ( !input.isValid() )
7169 return mFlags & FlagOptional;
7170
7171 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
7172 {
7173 return true;
7174 }
7175
7176 if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
7177 {
7178 if ( !mAllowMultiple )
7179 return false;
7180
7181 if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
7182 return false;
7183 }
7184 else
7185 {
7186 bool ok = false;
7187 const double res = input.toInt( &ok );
7188 Q_UNUSED( res )
7189 if ( !ok )
7190 return mFlags & FlagOptional;
7191 }
7192 return true;
7193}
7194
7196{
7197 return mAllowMultiple;
7198}
7199
7201{
7202 mAllowMultiple = allowMultiple;
7203}
7204
7206{
7207 if ( !value.isValid() )
7208 return QStringLiteral( "None" );
7209
7210 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
7211 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7212
7213 if ( value.type() == QVariant::List )
7214 {
7215 QStringList parts;
7216 const QVariantList values = value.toList();
7217 for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
7218 {
7219 parts << QString::number( static_cast< int >( it->toDouble() ) );
7220 }
7221 return parts.join( ',' ).prepend( '[' ).append( ']' );
7222 }
7223 else if ( value.type() == QVariant::StringList )
7224 {
7225 QStringList parts;
7226 const QStringList values = value.toStringList();
7227 for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
7228 {
7229 parts << QString::number( static_cast< int >( it->toDouble() ) );
7230 }
7231 return parts.join( ',' ).prepend( '[' ).append( ']' );
7232 }
7233
7234 return value.toString();
7235}
7236
7238{
7239 QString code = QStringLiteral( "##%1=" ).arg( mName );
7240 if ( mFlags & FlagOptional )
7241 code += QLatin1String( "optional " );
7242 code += QLatin1String( "band " );
7243
7244 if ( mAllowMultiple )
7245 code += QLatin1String( "multiple " );
7246
7247 code += mParentLayerParameterName + ' ';
7248
7249 code += mDefault.toString();
7250 return code.trimmed();
7251}
7252
7254{
7255 QStringList depends;
7256 if ( !mParentLayerParameterName.isEmpty() )
7257 depends << mParentLayerParameterName;
7258 return depends;
7259}
7260
7262{
7263 switch ( outputType )
7264 {
7266 {
7267 QString code = QStringLiteral( "QgsProcessingParameterBand('%1', %2" )
7269 if ( mFlags & FlagOptional )
7270 code += QLatin1String( ", optional=True" );
7271
7272 code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
7273 code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7274
7276 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7277 return code;
7278 }
7279 }
7280 return QString();
7281}
7282
7284{
7285 return mParentLayerParameterName;
7286}
7287
7288void QgsProcessingParameterBand::setParentLayerParameterName( const QString &parentLayerParameterName )
7289{
7290 mParentLayerParameterName = parentLayerParameterName;
7291}
7292
7294{
7296 map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
7297 map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
7298 return map;
7299}
7300
7302{
7304 mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
7305 mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
7306 return true;
7307}
7308
7309QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7310{
7311 QString parent;
7312 QString def = definition;
7313 bool allowMultiple = false;
7314
7315 if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
7316 {
7317 allowMultiple = true;
7318 def = def.mid( 8 ).trimmed();
7319 }
7320
7321 const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
7322 const QRegularExpressionMatch m = re.match( def );
7323 if ( m.hasMatch() )
7324 {
7325 parent = m.captured( 1 ).trimmed();
7326 def = m.captured( 2 );
7327 }
7328 else
7329 {
7330 parent = def;
7331 def.clear();
7332 }
7333
7334 return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
7335}
7336
7337//
7338// QgsProcessingParameterDistance
7339//
7340
7341QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
7342 : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
7343 , mParentParameterName( parentParameterName )
7344{
7345
7346}
7347
7349{
7350 return new QgsProcessingParameterDistance( *this );
7351}
7352
7354{
7355 return typeName();
7356}
7357
7359{
7360 QStringList depends;
7361 if ( !mParentParameterName.isEmpty() )
7362 depends << mParentParameterName;
7363 return depends;
7364}
7365
7367{
7368 switch ( outputType )
7369 {
7371 {
7372 QString code = QStringLiteral( "QgsProcessingParameterDistance('%1', %2" )
7374 if ( mFlags & FlagOptional )
7375 code += QLatin1String( ", optional=True" );
7376
7377 code += QStringLiteral( ", parentParameterName='%1'" ).arg( mParentParameterName );
7378
7379 if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
7380 code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
7381 if ( maximum() != std::numeric_limits<double>::max() )
7382 code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
7384 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7385 return code;
7386 }
7387 }
7388 return QString();
7389}
7390
7392{
7393 return mParentParameterName;
7394}
7395
7396void QgsProcessingParameterDistance::setParentParameterName( const QString &parentParameterName )
7397{
7398 mParentParameterName = parentParameterName;
7399}
7400
7402{
7404 map.insert( QStringLiteral( "parent" ), mParentParameterName );
7405 map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
7406 return map;
7407}
7408
7410{
7412 mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
7413 mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
7414 return true;
7415}
7416
7417
7418//
7419// QgsProcessingParameterDuration
7420//
7421
7422QgsProcessingParameterDuration::QgsProcessingParameterDuration( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
7423 : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
7424{
7425}
7426
7428{
7429 return new QgsProcessingParameterDuration( *this );
7430}
7431
7433{
7434 return typeName();
7435}
7436
7438{
7439 switch ( outputType )
7440 {
7442 {
7443 QString code = QStringLiteral( "QgsProcessingParameterDuration('%1', %2" )
7445 if ( mFlags & FlagOptional )
7446 code += QLatin1String( ", optional=True" );
7447
7448 if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
7449 code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
7450 if ( maximum() != std::numeric_limits<double>::max() )
7451 code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
7453 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7454 return code;
7455 }
7456 }
7457 return QString();
7458}
7459
7461{
7463 map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
7464 return map;
7465}
7466
7468{
7470 mDefaultUnit = static_cast< QgsUnitTypes::TemporalUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::TemporalDays ).toInt() );
7471 return true;
7472}
7473
7474
7475//
7476// QgsProcessingParameterScale
7477//
7478
7479QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7480 : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
7481{
7482
7483}
7484
7486{
7487 return new QgsProcessingParameterScale( *this );
7488}
7489
7491{
7492 return typeName();
7493}
7494
7496{
7497 switch ( outputType )
7498 {
7500 {
7501 QString code = QStringLiteral( "QgsProcessingParameterScale('%1', %2" )
7503 if ( mFlags & FlagOptional )
7504 code += QLatin1String( ", optional=True" );
7506 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7507 return code;
7508 }
7509 }
7510 return QString();
7511}
7512
7513QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7514{
7515 return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
7516 : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
7517}
7518
7519
7520//
7521// QgsProcessingParameterLayout
7522//
7523
7524QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
7525 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7526{}
7527
7529{
7530 return new QgsProcessingParameterLayout( *this );
7531}
7532
7534{
7535 if ( QgsVariantUtils::isNull( value ) )
7536 return QStringLiteral( "None" );
7537
7538 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
7539 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7540
7541 const QString s = value.toString();
7543}
7544
7546{
7547 QString code = QStringLiteral( "##%1=" ).arg( mName );
7548 if ( mFlags & FlagOptional )
7549 code += QLatin1String( "optional " );
7550 code += QLatin1String( "layout " );
7551
7552 code += mDefault.toString();
7553 return code.trimmed();
7554}
7555
7557{
7558 switch ( outputType )
7559 {
7561 {
7562 QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', %2" )
7564 if ( mFlags & FlagOptional )
7565 code += QLatin1String( ", optional=True" );
7567 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7568 return code;
7569 }
7570 }
7571 return QString();
7572}
7573
7574QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7575{
7576 QString def = definition;
7577
7578 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7579 def = def.mid( 1 );
7580 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7581 def.chop( 1 );
7582
7583 QVariant defaultValue = def;
7584 if ( def == QLatin1String( "None" ) )
7585 defaultValue = QVariant();
7586
7587 return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
7588}
7589
7590
7591//
7592// QString mParentLayerParameterName;
7593//
7594
7595QgsProcessingParameterLayoutItem::QgsProcessingParameterLayoutItem( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayoutParameterName, int itemType, bool optional )
7596 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7597 , mParentLayoutParameterName( parentLayoutParameterName )
7598 , mItemType( itemType )
7599{
7600
7601}
7602
7604{
7605 return new QgsProcessingParameterLayoutItem( *this );
7606}
7607
7609{
7610 if ( QgsVariantUtils::isNull( value ) )
7611 return QStringLiteral( "None" );
7612
7613 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
7614 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7615
7616 const QString s = value.toString();
7618}
7619
7621{
7622 QString code = QStringLiteral( "##%1=" ).arg( mName );
7623 if ( mFlags & FlagOptional )
7624 code += QLatin1String( "optional " );
7625 code += QLatin1String( "layoutitem " );
7626 if ( mItemType >= 0 )
7627 code += QString::number( mItemType ) + ' ';
7628
7629 code += mParentLayoutParameterName + ' ';
7630
7631 code += mDefault.toString();
7632 return code.trimmed();
7633}
7634
7636{
7637 switch ( outputType )
7638 {
7640 {
7641 QString code = QStringLiteral( "QgsProcessingParameterLayoutItem('%1', %2" )
7643 if ( mFlags & FlagOptional )
7644 code += QLatin1String( ", optional=True" );
7645
7646 if ( mItemType >= 0 )
7647 code += QStringLiteral( ", itemType=%1" ).arg( mItemType );
7648
7649 code += QStringLiteral( ", parentLayoutParameterName='%1'" ).arg( mParentLayoutParameterName );
7650
7652 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7653 return code;
7654 }
7655 }
7656 return QString();
7657}
7658
7660{
7662 map.insert( QStringLiteral( "parent_layout" ), mParentLayoutParameterName );
7663 map.insert( QStringLiteral( "item_type" ), mItemType );
7664 return map;
7665}
7666
7668{
7670 mParentLayoutParameterName = map.value( QStringLiteral( "parent_layout" ) ).toString();
7671 mItemType = map.value( QStringLiteral( "item_type" ) ).toInt();
7672 return true;
7673}
7674
7676{
7677 QStringList depends;
7678 if ( !mParentLayoutParameterName.isEmpty() )
7679 depends << mParentLayoutParameterName;
7680 return depends;
7681}
7682
7683QgsProcessingParameterLayoutItem *QgsProcessingParameterLayoutItem::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7684{
7685 QString parent;
7686 QString def = definition;
7687 int itemType = -1;
7688 const QRegularExpression re( QStringLiteral( "(\\d+)?\\s*(.*?)\\s+(.*)$" ) );
7689 const QRegularExpressionMatch m = re.match( def );
7690 if ( m.hasMatch() )
7691 {
7692 itemType = m.captured( 1 ).trimmed().isEmpty() ? -1 : m.captured( 1 ).trimmed().toInt();
7693 parent = m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ).trimmed() : m.captured( 2 ).trimmed();
7694 def = !m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ) : QString();
7695 }
7696 else
7697 {
7698 parent = def;
7699 def.clear();
7700 }
7701
7702 return new QgsProcessingParameterLayoutItem( name, description, def.isEmpty() ? QVariant() : def, parent, itemType, isOptional );
7703}
7704
7706{
7707 return mParentLayoutParameterName;
7708}
7709
7711{
7712 mParentLayoutParameterName = name;
7713}
7714
7716{
7717 return mItemType;
7718}
7719
7721{
7722 mItemType = type;
7723}
7724
7725//
7726// QgsProcessingParameterColor
7727//
7728
7729QgsProcessingParameterColor::QgsProcessingParameterColor( const QString &name, const QString &description, const QVariant &defaultValue, bool opacityEnabled, bool optional )
7730 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7731 , mAllowOpacity( opacityEnabled )
7732{
7733
7734}
7735
7737{
7738 return new QgsProcessingParameterColor( *this );
7739}
7740
7742{
7743 if ( QgsVariantUtils::isNull( value ) )
7744 return QStringLiteral( "None" );
7745
7746 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
7747 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7748
7749 if ( value.canConvert< QColor >() && !value.value< QColor >().isValid() )
7750 return QStringLiteral( "QColor()" );
7751
7752 if ( value.canConvert< QColor >() )
7753 {
7754 const QColor c = value.value< QColor >();
7755 if ( !mAllowOpacity || c.alpha() == 255 )
7756 return QStringLiteral( "QColor(%1, %2, %3)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() );
7757 else
7758 return QStringLiteral( "QColor(%1, %2, %3, %4)" ).arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
7759 }
7760
7761 const QString s = value.toString();
7763}
7764
7766{
7767 QString code = QStringLiteral( "##%1=" ).arg( mName );
7768 if ( mFlags & FlagOptional )
7769 code += QLatin1String( "optional " );
7770 code += QLatin1String( "color " );
7771
7772 if ( mAllowOpacity )
7773 code += QLatin1String( "withopacity " );
7774
7775 code += mDefault.toString();
7776 return code.trimmed();
7777}
7778
7780{
7781 switch ( outputType )
7782 {
7784 {
7785 QString code = QStringLiteral( "QgsProcessingParameterColor('%1', %2" )
7787 if ( mFlags & FlagOptional )
7788 code += QLatin1String( ", optional=True" );
7789
7790 code += QStringLiteral( ", opacityEnabled=%1" ).arg( mAllowOpacity ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
7791
7793 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7794 return code;
7795 }
7796 }
7797 return QString();
7798}
7799
7801{
7802 if ( !input.isValid() && ( mDefault.isValid() && ( !mDefault.toString().isEmpty() || mDefault.value< QColor >().isValid() ) ) )
7803 return true;
7804
7805 if ( !input.isValid() )
7806 return mFlags & FlagOptional;
7807
7808 if ( input.type() == QVariant::Color )
7809 {
7810 return true;
7811 }
7812 else if ( input.userType() == QMetaType::type( "QgsProperty" ) )
7813 {
7814 return true;
7815 }
7816
7817 if ( input.type() != QVariant::String || input.toString().isEmpty() )
7818 return mFlags & FlagOptional;
7819
7820 bool containsAlpha = false;
7821 return QgsSymbolLayerUtils::parseColorWithAlpha( input.toString(), containsAlpha ).isValid();
7822}
7823
7825{
7827 map.insert( QStringLiteral( "opacityEnabled" ), mAllowOpacity );
7828 return map;
7829}
7830
7832{
7834 mAllowOpacity = map.value( QStringLiteral( "opacityEnabled" ) ).toBool();
7835 return true;
7836}
7837
7839{
7840 return mAllowOpacity;
7841}
7842
7844{
7845 mAllowOpacity = enabled;
7846}
7847
7848QgsProcessingParameterColor *QgsProcessingParameterColor::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7849{
7850 QString def = definition;
7851
7852 bool allowOpacity = false;
7853 if ( def.startsWith( QLatin1String( "withopacity" ), Qt::CaseInsensitive ) )
7854 {
7855 allowOpacity = true;
7856 def = def.mid( 12 );
7857 }
7858
7859 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7860 def = def.mid( 1 );
7861 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7862 def.chop( 1 );
7863
7864 QVariant defaultValue = def;
7865 if ( def == QLatin1String( "None" ) )
7866 defaultValue = QVariant();
7867
7868 return new QgsProcessingParameterColor( name, description, defaultValue, allowOpacity, isOptional );
7869}
7870
7871//
7872// QgsProcessingParameterCoordinateOperation
7873//
7874QgsProcessingParameterCoordinateOperation::QgsProcessingParameterCoordinateOperation( const QString &name, const QString &description, const QVariant &defaultValue, const QString &sourceCrsParameterName, const QString &destinationCrsParameterName, const QVariant &staticSourceCrs, const QVariant &staticDestinationCrs, bool optional )
7875 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
7876 , mSourceParameterName( sourceCrsParameterName )
7877 , mDestParameterName( destinationCrsParameterName )
7878 , mSourceCrs( staticSourceCrs )
7879 , mDestCrs( staticDestinationCrs )
7880{
7881
7882}
7883
7885{
7886 return new QgsProcessingParameterCoordinateOperation( * this );
7887}
7888
7890{
7891 if ( QgsVariantUtils::isNull( value ) )
7892 return QStringLiteral( "None" );
7893
7894 if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) )
7895 {
7896 if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
7897 return QStringLiteral( "QgsCoordinateReferenceSystem()" );
7898 else
7899 return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
7900 }
7901
7902 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
7903 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
7904
7905 QVariantMap p;
7906 p.insert( name(), value );
7907 QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
7908 if ( layer )
7910
7911 const QString s = value.toString();
7913}
7914
7916{
7917 QString code = QStringLiteral( "##%1=" ).arg( mName );
7918 if ( mFlags & FlagOptional )
7919 code += QLatin1String( "optional " );
7920 code += QLatin1String( "coordinateoperation " );
7921
7922 code += mDefault.toString();
7923 return code.trimmed();
7924}
7925
7927{
7928 switch ( outputType )
7929 {
7931 {
7933 QString code = QStringLiteral( "QgsProcessingParameterCoordinateOperation('%1', %2" )
7935 if ( mFlags & FlagOptional )
7936 code += QLatin1String( ", optional=True" );
7937 if ( !mSourceParameterName.isEmpty() )
7938 code += QStringLiteral( ", sourceCrsParameterName=%1" ).arg( valueAsPythonString( mSourceParameterName, c ) );
7939 if ( !mDestParameterName.isEmpty() )
7940 code += QStringLiteral( ", destinationCrsParameterName=%1" ).arg( valueAsPythonString( mDestParameterName, c ) );
7941
7942 if ( mSourceCrs.isValid() )
7943 code += QStringLiteral( ", staticSourceCrs=%1" ).arg( valueAsPythonString( mSourceCrs, c ) );
7944 if ( mDestCrs.isValid() )
7945 code += QStringLiteral( ", staticDestinationCrs=%1" ).arg( valueAsPythonString( mDestCrs, c ) );
7946
7947 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
7948 return code;
7949 }
7950 }
7951 return QString();
7952}
7953
7955{
7956 QStringList res;
7957 if ( !mSourceParameterName.isEmpty() )
7958 res << mSourceParameterName;
7959 if ( !mDestParameterName.isEmpty() )
7960 res << mDestParameterName;
7961 return res;
7962}
7963
7965{
7967 map.insert( QStringLiteral( "source_crs_parameter_name" ), mSourceParameterName );
7968 map.insert( QStringLiteral( "dest_crs_parameter_name" ), mDestParameterName );
7969 map.insert( QStringLiteral( "static_source_crs" ), mSourceCrs );
7970 map.insert( QStringLiteral( "static_dest_crs" ), mDestCrs );
7971 return map;
7972}
7973
7975{
7977 mSourceParameterName = map.value( QStringLiteral( "source_crs_parameter_name" ) ).toString();
7978 mDestParameterName = map.value( QStringLiteral( "dest_crs_parameter_name" ) ).toString();
7979 mSourceCrs = map.value( QStringLiteral( "static_source_crs" ) );
7980 mDestCrs = map.value( QStringLiteral( "static_dest_crs" ) );
7981 return true;
7982}
7983
7984QgsProcessingParameterCoordinateOperation *QgsProcessingParameterCoordinateOperation::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
7985{
7986 QString def = definition;
7987
7988 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
7989 def = def.mid( 1 );
7990 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
7991 def.chop( 1 );
7992
7993 QVariant defaultValue = def;
7994 if ( def == QLatin1String( "None" ) )
7995 defaultValue = QVariant();
7996
7997 return new QgsProcessingParameterCoordinateOperation( name, description, defaultValue, QString(), QString(), QVariant(), QVariant(), isOptional );
7998}
7999
8000
8001//
8002// QgsProcessingParameterMapTheme
8003//
8004
8005QgsProcessingParameterMapTheme::QgsProcessingParameterMapTheme( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
8006 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8007{
8008
8009}
8010
8011
8013{
8014 return new QgsProcessingParameterMapTheme( *this );
8015}
8016
8018{
8019 if ( !input.isValid() && !mDefault.isValid() )
8020 return mFlags & FlagOptional;
8021
8022 if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8023 || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8024 return mFlags & FlagOptional;
8025
8026 return true;
8027}
8028
8030{
8031 if ( !value.isValid() )
8032 return QStringLiteral( "None" );
8033
8034 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
8035 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8036
8037 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8038}
8039
8041{
8042 QString code = QStringLiteral( "##%1=" ).arg( mName );
8043 if ( mFlags & FlagOptional )
8044 code += QLatin1String( "optional " );
8045 code += QLatin1String( "maptheme " );
8046
8047 code += mDefault.toString();
8048 return code.trimmed();
8049}
8050
8052{
8053 switch ( outputType )
8054 {
8056 {
8057 QString code = QStringLiteral( "QgsProcessingParameterMapTheme('%1', %2" )
8059 if ( mFlags & FlagOptional )
8060 code += QLatin1String( ", optional=True" );
8061
8063 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
8064
8065 return code;
8066 }
8067 }
8068 return QString();
8069}
8070
8072{
8074 return map;
8075}
8076
8078{
8080 return true;
8081}
8082
8083QgsProcessingParameterMapTheme *QgsProcessingParameterMapTheme::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8084{
8085 QString def = definition;
8086 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
8087 def = def.mid( 1 );
8088 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
8089 def.chop( 1 );
8090
8091 QVariant defaultValue = def;
8092
8093 if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
8094 defaultValue = QVariant();
8095
8096 return new QgsProcessingParameterMapTheme( name, description, defaultValue, isOptional );
8097}
8098
8099
8100//
8101// QgsProcessingParameterDateTime
8102//
8103
8104QgsProcessingParameterDateTime::QgsProcessingParameterDateTime( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, const QDateTime &minValue, const QDateTime &maxValue )
8105 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8106 , mMin( minValue )
8107 , mMax( maxValue )
8108 , mDataType( type )
8109{
8110 if ( mMin.isValid() && mMax.isValid() && mMin >= mMax )
8111 {
8112 QgsMessageLog::logMessage( QObject::tr( "Invalid datetime parameter \"%1\": min value %2 is >= max value %3!" ).arg( name, mMin.toString(), mMax.toString() ), QObject::tr( "Processing" ) );
8113 }
8114}
8115
8117{
8118 return new QgsProcessingParameterDateTime( *this );
8119}
8120
8122{
8123 QVariant input = value;
8124 if ( !input.isValid() )
8125 {
8126 if ( !defaultValue().isValid() )
8127 return mFlags & FlagOptional;
8128
8129 input = defaultValue();
8130 }
8131
8132 if ( input.userType() == QMetaType::type( "QgsProperty" ) )
8133 {
8134 return true;
8135 }
8136
8137 if ( input.type() != QVariant::DateTime && input.type() != QVariant::Date && input.type() != QVariant::Time && input.type() != QVariant::String )
8138 return false;
8139
8140 if ( ( input.type() == QVariant::DateTime || input.type() == QVariant::Date ) && mDataType == Time )
8141 return false;
8142
8143 if ( input.type() == QVariant::String )
8144 {
8145 const QString s = input.toString();
8146 if ( s.isEmpty() )
8147 return mFlags & FlagOptional;
8148
8149 input = QDateTime::fromString( s, Qt::ISODate );
8150 if ( mDataType == Time )
8151 {
8152 if ( !input.toDateTime().isValid() )
8153 input = QTime::fromString( s );
8154 else
8155 input = input.toDateTime().time();
8156 }
8157 }
8158
8159 if ( mDataType != Time )
8160 {
8161 const QDateTime res = input.toDateTime();
8162 return res.isValid() && ( res >= mMin || !mMin.isValid() ) && ( res <= mMax || !mMax.isValid() );
8163 }
8164 else
8165 {
8166 const QTime res = input.toTime();
8167 return res.isValid() && ( res >= mMin.time() || !mMin.isValid() ) && ( res <= mMax.time() || !mMax.isValid() );
8168 }
8169}
8170
8172{
8173 if ( !value.isValid() )
8174 return QStringLiteral( "None" );
8175
8176 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
8177 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8178
8179 if ( value.type() == QVariant::DateTime )
8180 {
8181 const QDateTime dt = value.toDateTime();
8182 if ( !dt.isValid() )
8183 return QStringLiteral( "QDateTime()" );
8184 else
8185 return QStringLiteral( "QDateTime(QDate(%1, %2, %3), QTime(%4, %5, %6))" ).arg( dt.date().year() )
8186 .arg( dt.date().month() )
8187 .arg( dt.date().day() )
8188 .arg( dt.time().hour() )
8189 .arg( dt.time().minute() )
8190 .arg( dt.time().second() );
8191 }
8192 else if ( value.type() == QVariant::Date )
8193 {
8194 const QDate dt = value.toDate();
8195 if ( !dt.isValid() )
8196 return QStringLiteral( "QDate()" );
8197 else
8198 return QStringLiteral( "QDate(%1, %2, %3)" ).arg( dt.year() )
8199 .arg( dt.month() )
8200 .arg( dt.day() );
8201 }
8202 else if ( value.type() == QVariant::Time )
8203 {
8204 const QTime dt = value.toTime();
8205 if ( !dt.isValid() )
8206 return QStringLiteral( "QTime()" );
8207 else
8208 return QStringLiteral( "QTime(%4, %5, %6)" )
8209 .arg( dt.hour() )
8210 .arg( dt.minute() )
8211 .arg( dt.second() );
8212 }
8213 return value.toString();
8214}
8215
8217{
8219 QStringList parts;
8220 if ( mMin.isValid() )
8221 parts << QObject::tr( "Minimum value: %1" ).arg( mMin.toString( Qt::ISODate ) );
8222 if ( mMax.isValid() )
8223 parts << QObject::tr( "Maximum value: %1" ).arg( mMax.toString( Qt::ISODate ) );
8224 if ( mDefault.isValid() )
8225 parts << QObject::tr( "Default value: %1" ).arg( mDataType == DateTime ? mDefault.toDateTime().toString( Qt::ISODate ) :
8226 ( mDataType == Date ? mDefault.toDate().toString( Qt::ISODate ) : mDefault.toTime( ).toString() ) );
8227 const QString extra = parts.join( QLatin1String( "<br />" ) );
8228 if ( !extra.isEmpty() )
8229 text += QStringLiteral( "<p>%1</p>" ).arg( extra );
8230 return text;
8231}
8232
8234{
8235 switch ( outputType )
8236 {
8238 {
8239 QString code = QStringLiteral( "QgsProcessingParameterDateTime('%1', %2" )
8241 if ( mFlags & FlagOptional )
8242 code += QLatin1String( ", optional=True" );
8243
8244 code += QStringLiteral( ", type=%1" ).arg( mDataType == DateTime ? QStringLiteral( "QgsProcessingParameterDateTime.DateTime" )
8245 : mDataType == Date ? QStringLiteral( "QgsProcessingParameterDateTime.Date" )
8246 : QStringLiteral( "QgsProcessingParameterDateTime.Time" ) );
8247
8249 if ( mMin.isValid() )
8250 code += QStringLiteral( ", minValue=%1" ).arg( valueAsPythonString( mMin, c ) );
8251 if ( mMax.isValid() )
8252 code += QStringLiteral( ", maxValue=%1" ).arg( valueAsPythonString( mMax, c ) );
8253 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
8254 return code;
8255 }
8256 }
8257 return QString();
8258}
8259
8261{
8262 return mMin;
8263}
8264
8266{
8267 mMin = min;
8268}
8269
8271{
8272 return mMax;
8273}
8274
8276{
8277 mMax = max;
8278}
8279
8281{
8282 return mDataType;
8283}
8284
8286{
8287 mDataType = dataType;
8288}
8289
8291{
8293 map.insert( QStringLiteral( "min" ), mMin );
8294 map.insert( QStringLiteral( "max" ), mMax );
8295 map.insert( QStringLiteral( "data_type" ), mDataType );
8296 return map;
8297}
8298
8300{
8302 mMin = map.value( QStringLiteral( "min" ) ).toDateTime();
8303 mMax = map.value( QStringLiteral( "max" ) ).toDateTime();
8304 mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
8305 return true;
8306}
8307
8308QgsProcessingParameterDateTime *QgsProcessingParameterDateTime::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8309{
8310 return new QgsProcessingParameterDateTime( name, description, DateTime, definition.isEmpty() ? QVariant()
8311 : ( definition.toLower().trimmed() == QLatin1String( "none" ) ? QVariant() : definition ), isOptional );
8312}
8313
8314
8315
8316//
8317// QgsProcessingParameterProviderConnection
8318//
8319
8320QgsProcessingParameterProviderConnection::QgsProcessingParameterProviderConnection( const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue, bool optional )
8321 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8322 , mProviderId( provider )
8323{
8324
8325}
8326
8327
8329{
8330 return new QgsProcessingParameterProviderConnection( *this );
8331}
8332
8334{
8335 if ( !input.isValid() && !mDefault.isValid() )
8336 return mFlags & FlagOptional;
8337
8338 if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8339 || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8340 return mFlags & FlagOptional;
8341
8342 return true;
8343}
8344
8346{
8347 if ( !value.isValid() )
8348 return QStringLiteral( "None" );
8349
8350 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
8351 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8352
8353 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8354}
8355
8357{
8358 QString code = QStringLiteral( "##%1=" ).arg( mName );
8359 if ( mFlags & FlagOptional )
8360 code += QLatin1String( "optional " );
8361 code += QLatin1String( "providerconnection " );
8362 code += mProviderId + ' ';
8363
8364 code += mDefault.toString();
8365 return code.trimmed();
8366}
8367
8369{
8370 switch ( outputType )
8371 {
8373 {
8374 QString code = QStringLiteral( "QgsProcessingParameterProviderConnection('%1', %2, '%3'" )
8375 .arg( name(), QgsProcessingUtils::stringToPythonLiteral( description() ), mProviderId );
8376 if ( mFlags & FlagOptional )
8377 code += QLatin1String( ", optional=True" );
8378
8380 code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
8381
8382 return code;
8383 }
8384 }
8385 return QString();
8386}
8387
8389{
8391 map.insert( QStringLiteral( "provider" ), mProviderId );
8392 return map;
8393}
8394
8396{
8398 mProviderId = map.value( QStringLiteral( "provider" ) ).toString();
8399 return true;
8400}
8401
8402QgsProcessingParameterProviderConnection *QgsProcessingParameterProviderConnection::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8403{
8404 QString def = definition;
8405 QString provider;
8406 if ( def.contains( ' ' ) )
8407 {
8408 provider = def.left( def.indexOf( ' ' ) );
8409 def = def.mid( def.indexOf( ' ' ) + 1 );
8410 }
8411 else
8412 {
8413 provider = def;
8414 def.clear();
8415 }
8416
8417 if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
8418 def = def.mid( 1 );
8419 if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
8420 def.chop( 1 );
8421
8422 QVariant defaultValue = def;
8423
8424 if ( defaultValue == QLatin1String( "None" ) || defaultValue.toString().isEmpty() )
8425 defaultValue = QVariant();
8426
8428}
8429
8430
8431//
8432// QgsProcessingParameterDatabaseSchema
8433//
8434
8435QgsProcessingParameterDatabaseSchema::QgsProcessingParameterDatabaseSchema( const QString &name, const QString &description, const QString &parentLayerParameterName, const QVariant &defaultValue, bool optional )
8436 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8437 , mParentConnectionParameterName( parentLayerParameterName )
8438{
8439
8440}
8441
8442
8444{
8445 return new QgsProcessingParameterDatabaseSchema( *this );
8446}
8447
8449{
8450 if ( !input.isValid() && !mDefault.isValid() )
8451 return mFlags & FlagOptional;
8452
8453 if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8454 || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8455 return mFlags & FlagOptional;
8456
8457 return true;
8458}
8459
8461{
8462 if ( !value.isValid() )
8463 return QStringLiteral( "None" );
8464
8465 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
8466 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8467
8468 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8469}
8470
8472{
8473 QString code = QStringLiteral( "##%1=" ).arg( mName );
8474 if ( mFlags & FlagOptional )
8475 code += QLatin1String( "optional " );
8476 code += QLatin1String( "databaseschema " );
8477
8478 code += mParentConnectionParameterName + ' ';
8479
8480 code += mDefault.toString();
8481 return code.trimmed();
8482}
8483
8485{
8486 switch ( outputType )
8487 {
8489 {
8490 QString code = QStringLiteral( "QgsProcessingParameterDatabaseSchema('%1', %2" )
8492 if ( mFlags & FlagOptional )
8493 code += QLatin1String( ", optional=True" );
8494
8495 code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
8497 code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
8498
8499 code += ')';
8500
8501 return code;
8502 }
8503 }
8504 return QString();
8505}
8506
8508{
8509 QStringList depends;
8510 if ( !mParentConnectionParameterName.isEmpty() )
8511 depends << mParentConnectionParameterName;
8512 return depends;
8513}
8514
8516{
8517 return mParentConnectionParameterName;
8518}
8519
8521{
8522 mParentConnectionParameterName = name;
8523}
8524
8526{
8528 map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
8529 return map;
8530}
8531
8533{
8535 mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
8536 return true;
8537}
8538
8539QgsProcessingParameterDatabaseSchema *QgsProcessingParameterDatabaseSchema::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8540{
8541 QString parent;
8542 QString def = definition;
8543
8544 const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
8545 const QRegularExpressionMatch m = re.match( def );
8546 if ( m.hasMatch() )
8547 {
8548 parent = m.captured( 1 ).trimmed();
8549 def = m.captured( 2 );
8550 }
8551 else
8552 {
8553 parent = def;
8554 def.clear();
8555 }
8556
8557 return new QgsProcessingParameterDatabaseSchema( name, description, parent, def.isEmpty() ? QVariant() : def, isOptional );
8558}
8559
8560//
8561// QgsProcessingParameterDatabaseTable
8562//
8563
8565 const QString &connectionParameterName,
8566 const QString &schemaParameterName,
8567 const QVariant &defaultValue, bool optional, bool allowNewTableNames )
8568 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8569 , mParentConnectionParameterName( connectionParameterName )
8570 , mParentSchemaParameterName( schemaParameterName )
8571 , mAllowNewTableNames( allowNewTableNames )
8572{
8573
8574}
8575
8576
8578{
8579 return new QgsProcessingParameterDatabaseTable( *this );
8580}
8581
8583{
8584 if ( !input.isValid() && !mDefault.isValid() )
8585 return mFlags & FlagOptional;
8586
8587 if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
8588 || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
8589 return mFlags & FlagOptional;
8590
8591 return true;
8592}
8593
8595{
8596 if ( !value.isValid() )
8597 return QStringLiteral( "None" );
8598
8599 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
8600 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8601
8602 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8603}
8604
8606{
8607 QString code = QStringLiteral( "##%1=" ).arg( mName );
8608 if ( mFlags & FlagOptional )
8609 code += QLatin1String( "optional " );
8610 code += QLatin1String( "databasetable " );
8611
8612 code += ( mParentConnectionParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentConnectionParameterName ) + ' ';
8613 code += ( mParentSchemaParameterName.isEmpty() ? QStringLiteral( "none" ) : mParentSchemaParameterName ) + ' ';
8614
8615 code += mDefault.toString();
8616 return code.trimmed();
8617}
8618
8620{
8621 switch ( outputType )
8622 {
8624 {
8625 QString code = QStringLiteral( "QgsProcessingParameterDatabaseTable('%1', %2" )
8627 if ( mFlags & FlagOptional )
8628 code += QLatin1String( ", optional=True" );
8629
8630 if ( mAllowNewTableNames )
8631 code += QLatin1String( ", allowNewTableNames=True" );
8632
8633 code += QStringLiteral( ", connectionParameterName='%1'" ).arg( mParentConnectionParameterName );
8634 code += QStringLiteral( ", schemaParameterName='%1'" ).arg( mParentSchemaParameterName );
8636 code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );
8637
8638 code += ')';
8639
8640 return code;
8641 }
8642 }
8643 return QString();
8644}
8645
8647{
8648 QStringList depends;
8649 if ( !mParentConnectionParameterName.isEmpty() )
8650 depends << mParentConnectionParameterName;
8651 if ( !mParentSchemaParameterName.isEmpty() )
8652 depends << mParentSchemaParameterName;
8653 return depends;
8654}
8655
8657{
8658 return mParentConnectionParameterName;
8659}
8660
8662{
8663 mParentConnectionParameterName = name;
8664}
8665
8667{
8668 return mParentSchemaParameterName;
8669}
8670
8672{
8673 mParentSchemaParameterName = name;
8674}
8675
8677{
8679 map.insert( QStringLiteral( "mParentConnectionParameterName" ), mParentConnectionParameterName );
8680 map.insert( QStringLiteral( "mParentSchemaParameterName" ), mParentSchemaParameterName );
8681 map.insert( QStringLiteral( "mAllowNewTableNames" ), mAllowNewTableNames );
8682 return map;
8683}
8684
8686{
8688 mParentConnectionParameterName = map.value( QStringLiteral( "mParentConnectionParameterName" ) ).toString();
8689 mParentSchemaParameterName = map.value( QStringLiteral( "mParentSchemaParameterName" ) ).toString();
8690 mAllowNewTableNames = map.value( QStringLiteral( "mAllowNewTableNames" ), false ).toBool();
8691 return true;
8692}
8693
8694QgsProcessingParameterDatabaseTable *QgsProcessingParameterDatabaseTable::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8695{
8696 QString connection;
8697 QString schema;
8698 QString def = definition;
8699
8700 const QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*+)\\b\\s*(.*)$" ) );
8701 const QRegularExpressionMatch m = re.match( def );
8702 if ( m.hasMatch() )
8703 {
8704 connection = m.captured( 1 ).trimmed();
8705 if ( connection == QLatin1String( "none" ) )
8706 connection.clear();
8707 schema = m.captured( 2 ).trimmed();
8708 if ( schema == QLatin1String( "none" ) )
8709 schema.clear();
8710 def = m.captured( 3 );
8711 }
8712
8713 return new QgsProcessingParameterDatabaseTable( name, description, connection, schema, def.isEmpty() ? QVariant() : def, isOptional );
8714}
8715
8717{
8718 return mAllowNewTableNames;
8719}
8720
8722{
8723 mAllowNewTableNames = allowNewTableNames;
8724}
8725
8726//
8727// QgsProcessingParameterPointCloudLayer
8728//
8729
8731 const QVariant &defaultValue, bool optional )
8732 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8733{
8734}
8735
8737{
8738 return new QgsProcessingParameterPointCloudLayer( *this );
8739}
8740
8742{
8743 if ( !v.isValid() )
8744 return mFlags & FlagOptional;
8745
8746 QVariant var = v;
8747
8748 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
8749 {
8750 const QgsProperty p = var.value< QgsProperty >();
8752 {
8753 var = p.staticValue();
8754 }
8755 else
8756 {
8757 return true;
8758 }
8759 }
8760
8761 if ( qobject_cast< QgsPointCloudLayer * >( qvariant_cast<QObject *>( var ) ) )
8762 return true;
8763
8764 if ( var.type() != QVariant::String || var.toString().isEmpty() )
8765 return mFlags & FlagOptional;
8766
8767 if ( !context )
8768 {
8769 // that's as far as we can get without a context
8770 return true;
8771 }
8772
8773 // try to load as layer
8775 return true;
8776
8777 return false;
8778}
8779
8781{
8782 if ( !val.isValid() )
8783 return QStringLiteral( "None" );
8784
8785 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
8786 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
8787
8788 QVariantMap p;
8789 p.insert( name(), val );
8793}
8794
8795QString QgsProcessingParameterPointCloudLayer::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
8796{
8798}
8799
8801{
8803}
8804
8806{
8807 return QgsProviderRegistry::instance()->filePointCloudFilters() + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
8808}
8809
8810QgsProcessingParameterPointCloudLayer *QgsProcessingParameterPointCloudLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8811{
8812 return new QgsProcessingParameterPointCloudLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
8813}
8814
8815//
8816// QgsProcessingParameterAnnotationLayer
8817//
8818
8820 const QVariant &defaultValue, bool optional )
8821 : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
8822{
8823}
8824
8826{
8827 return new QgsProcessingParameterAnnotationLayer( *this );
8828}
8829
8831{
8832 if ( !v.isValid() )
8833 return mFlags & FlagOptional;
8834
8835 QVariant var = v;
8836
8837 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
8838 {
8839 const QgsProperty p = var.value< QgsProperty >();
8841 {
8842 var = p.staticValue();
8843 }
8844 else
8845 {
8846 return true;
8847 }
8848 }
8849
8850 if ( qobject_cast< QgsAnnotationLayer * >( qvariant_cast<QObject *>( var ) ) )
8851 return true;
8852
8853 if ( var.type() != QVariant::String || var.toString().isEmpty() )
8854 return mFlags & FlagOptional;
8855
8856 if ( !context )
8857 {
8858 // that's as far as we can get without a context
8859 return true;
8860 }
8861
8862 // try to load as layer
8864 return true;
8865
8866 return false;
8867}
8868
8870{
8871 if ( !val.isValid() )
8872 return QStringLiteral( "None" );
8873
8874 if ( val.userType() == QMetaType::type( "QgsProperty" ) )
8875 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
8876
8877 QVariantMap p;
8878 p.insert( name(), val );
8880 return layer ? QgsProcessingUtils::stringToPythonLiteral( layer == context.project()->mainAnnotationLayer() ? QStringLiteral( "main" ) : layer->id() )
8882}
8883
8884QString QgsProcessingParameterAnnotationLayer::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const
8885{
8887}
8888
8890{
8892}
8893
8894QgsProcessingParameterAnnotationLayer *QgsProcessingParameterAnnotationLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
8895{
8896 return new QgsProcessingParameterAnnotationLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
8897}
8898
8899QgsProcessingParameterPointCloudDestination::QgsProcessingParameterPointCloudDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
8900 : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
8901{
8902}
8903
8905{
8907}
8908
8910{
8911 QVariant var = input;
8912 if ( !var.isValid() )
8913 return mFlags & FlagOptional;
8914
8915 if ( var.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
8916 {
8917 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
8918 var = fromVar.sink;
8919 }
8920
8921 if ( var.userType() == QMetaType::type( "QgsProperty" ) )
8922 {
8923 const QgsProperty p = var.value< QgsProperty >();
8925 {
8926 var = p.staticValue();
8927 }
8928 else
8929 {
8930 return true;
8931 }
8932 }
8933
8934 if ( var.type() != QVariant::String )
8935 return false;
8936
8937 if ( var.toString().isEmpty() )
8938 return mFlags & FlagOptional;
8939
8940 return true;
8941}
8942
8944{
8945 if ( !value.isValid() )
8946 return QStringLiteral( "None" );
8947
8948 if ( value.userType() == QMetaType::type( "QgsProperty" ) )
8949 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
8950
8951 if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) )
8952 {
8953 const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
8955 {
8956 return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
8957 }
8958 else
8959 {
8960 return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
8961 }
8962 }
8963
8964 return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
8965}
8966
8968{
8970}
8971
8973{
8974 if ( auto *lOriginalProvider = originalProvider() )
8975 {
8976 return lOriginalProvider->defaultPointCloudFileExtension();
8977 }
8978 else if ( QgsProcessingProvider *p = provider() )
8979 {
8980 return p->defaultPointCloudFileExtension();
8981 }
8982 else
8983 {
8985 }
8986}
8987
8989{
8990 const QStringList exts = supportedOutputPointCloudLayerExtensions();
8991 QStringList filters;
8992 for ( const QString &ext : exts )
8993 {
8994 filters << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
8995 }
8996 return filters.join( QLatin1String( ";;" ) ) + QStringLiteral( ";;" ) + QObject::tr( "All files (*.*)" );
8997}
8998
9000{
9001 if ( auto *lOriginalProvider = originalProvider() )
9002 {
9003 return lOriginalProvider->supportedOutputPointCloudLayerExtensions();
9004 }
9005 else if ( QgsProcessingProvider *p = provider() )
9006 {
9007 return p->supportedOutputPointCloudLayerExtensions();
9008 }
9009 else
9010 {
9012 return QStringList() << QObject::tr( "%1 files (*.%2)" ).arg( ext.toUpper(), ext.toLower() );
9013 }
9014}
9015
9016QgsProcessingParameterPointCloudDestination *QgsProcessingParameterPointCloudDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
9017{
9018 return new QgsProcessingParameterPointCloudDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
9019}
Represents a map layer containing a set of georeferenced annotations, e.g.
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Class for doing transforms between two map coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
QgsPointXY transform(const QgsPointXY &point, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Class for parsing and evaluation of expressions (formerly called "search strings").
bool isValid() const
Checks if this expression is valid.
InvalidGeometryCheck
Handling of features with invalid geometries.
@ GeometryNoCheck
No invalid geometry checking.
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
An interface for objects which accept features via addFeature(s) methods.
Container of fields for a vector layer.
Definition: qgsfields.h:45
static bool fileMatchesFilter(const QString &fileName, const QString &filter)
Returns true if the given fileName matches a file filter string.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Q_GADGET bool isNull
Definition: qgsgeometry.h:166
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:167
QgsGeometry centroid() const
Returns the center of mass of a geometry.
QString lastError() const SIP_HOLDGIL
Returns an error string referring to the last error encountered either when this geometry was created...
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
QString asWkt(int precision=17) const
Exports the geometry to WKT.
Base class for graphical items within a QgsLayout.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
QgsLayoutItem * itemById(const QString &id) const
Returns a layout item given its id.
Definition: qgslayout.cpp:266
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
Definition: qgslayout.cpp:238
Base class for all map layer types.
Definition: qgsmaplayer.h:73
virtual QgsRectangle extent() const
Returns the extent of the layer.
QString source() const
Returns the source for the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Interface for master layout type objects, such as print layouts and reports.
virtual QgsMasterLayoutInterface::Type layoutType() const =0
Returns the master layout type.
@ PrintLayout
Individual print layout (QgsPrintLayout)
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:100
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Represents a map layer supporting display of point clouds.
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Print layout, a QgsLayout subclass for static or atlas-based layouts.
Abstract base class for processing algorithms.
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
Details for layers to load into projects.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
void addLayerToLoadOnCompletion(const QString &layer, const QgsProcessingContext::LayerDetails &details)
Adds a layer to load (by ID or datasource) into the canvas upon completion of the algorithm or model.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Base class for all parameter definitions which represent file or layer destinations,...
virtual QString defaultFileExtension() const =0
Returns the default file extension for destination file paths associated with this parameter.
void setCreateByDefault(bool createByDefault)
Sets whether the destination should be created by default.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
virtual QString generateTemporaryDestination() const
Generates a temporary destination value for this parameter.
bool supportsNonFileBasedOutput() const
Returns true if the destination parameter supports non filed-based outputs, such as memory layers or ...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
bool createByDefault() const
Returns true if the destination should be created by default.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
virtual bool isSupportedOutputValue(const QVariant &value, QgsProcessingContext &context, QString &error) const
Tests whether a value is a supported value for this parameter.
QgsProcessingProvider * originalProvider() const
Original (source) provider which this parameter has been derived from.
QgsProcessingDestinationParameter(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingDestinationParameter.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Encapsulates settings relating to a feature source input to a processing algorithm.
bool loadVariant(const QVariantMap &map)
Loads this source definition from a QVariantMap, wrapped in a QVariant.
Flags flags
Flags which dictate source behavior.
bool selectedFeaturesOnly
true if only selected features in the source should be used by algorithms.
QgsFeatureRequest::InvalidGeometryCheck geometryCheck
Geometry check method to apply to this source.
long long featureLimit
If set to a value > 0, places a limit on the maximum number of features which will be read from the s...
QVariant toVariant() const
Saves this source definition to a QVariantMap, wrapped in a QVariant.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
Base class for providing feedback from a processing algorithm.
Base class for the definition of processing outputs.
A file output for processing algorithms.
A folder output for processing algorithms.
A HTML file output for processing algorithms.
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm.
bool loadVariant(const QVariantMap &map)
Loads this output layer definition from a QVariantMap, wrapped in a QVariant.
bool operator!=(const QgsProcessingOutputLayerDefinition &other) const
QgsProject * destinationProject
Destination project.
bool operator==(const QgsProcessingOutputLayerDefinition &other) const
QgsProperty sink
Sink/layer definition.
bool useRemapping() const
Returns true if the output uses a remapping definition.
QgsRemappingSinkDefinition remappingDefinition() const
Returns the output remapping definition, if useRemapping() is true.
QVariant toVariant() const
Saves this output layer definition to a QVariantMap, wrapped in a QVariant.
QString destinationName
Name to use for sink if it's to be loaded into a destination project.
QVariantMap createOptions
Map of optional sink/layer creation options, which are passed to the underlying provider when creatin...
void setRemappingDefinition(const QgsRemappingSinkDefinition &definition)
Sets the remapping definition to use when adding features to the output layer.
A pointcloud layer output for processing algorithms.
A raster layer output for processing algorithms.
A vector layer output for processing algorithms.
An annotation layer parameter for processing algorithms.
QgsProcessingParameterAnnotationLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterAnnotationLayer.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterAnnotationLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
static QString typeName()
Returns the type name for the parameter class.
A string parameter for authentication configuration ID values.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterAuthConfig(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterAuthConfig.
static QString typeName()
Returns the type name for the parameter class.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterAuthConfig * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A raster band parameter for Processing algorithms.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setAllowMultiple(bool allowMultiple)
Sets whether multiple band selections are permitted.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
QgsProcessingParameterBand(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), bool optional=false, bool allowMultiple=false)
Constructor for QgsProcessingParameterBand.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterBand * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
static QString typeName()
Returns the type name for the parameter class.
bool allowMultiple() const
Returns whether multiple band selections are permitted.
A boolean parameter for processing algorithms.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString type() const override
Unique parameter type name.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterBoolean * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterBoolean(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterBoolean.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
A color parameter for processing algorithms.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterColor * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool opacityEnabled() const
Returns true if the parameter allows opacity control.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setOpacityEnabled(bool enabled)
Sets whether the parameter allows opacity control.
QgsProcessingParameterColor(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool opacityEnabled=true, bool optional=false)
Constructor for QgsProcessingParameterColor.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A coordinate operation parameter for processing algorithms, for selection between available coordinat...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterCoordinateOperation * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterCoordinateOperation(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &sourceCrsParameterName=QString(), const QString &destinationCrsParameterName=QString(), const QVariant &staticSourceCrs=QVariant(), const QVariant &staticDestinationCrs=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterCoordinateOperation.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A coordinate reference system parameter for processing algorithms.
QgsProcessingParameterCrs(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterCrs.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterCrs * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
A database schema parameter for processing algorithms, allowing users to select from existing schemas...
void setParentConnectionParameterName(const QString &name)
Sets the name of the parent connection parameter.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterDatabaseSchema(const QString &name, const QString &description, const QString &connectionParameterName=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterDatabaseSchema.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterDatabaseSchema * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString parentConnectionParameterName() const
Returns the name of the parent connection parameter, or an empty string if this is not set.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
A database table name parameter for processing algorithms, allowing users to select from existing dat...
QgsProcessingParameterDatabaseTable(const QString &name, const QString &description, const QString &connectionParameterName=QString(), const QString &schemaParameterName=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool allowNewTableNames=false)
Constructor for QgsProcessingParameterDatabaseTable.
void setParentSchemaParameterName(const QString &name)
Sets the name of the parent schema parameter.
QString parentConnectionParameterName() const
Returns the name of the parent connection parameter, or an empty string if this is not set.
QString parentSchemaParameterName() const
Returns the name of the parent schema parameter, or an empty string if this is not set.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterDatabaseTable * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool allowNewTableNames() const
Returns true if the parameter allows users to enter names for a new (non-existing) tables.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
void setAllowNewTableNames(bool allowed)
Sets whether the parameter allows users to enter names for a new (non-existing) tables.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setParentConnectionParameterName(const QString &name)
Sets the name of the parent connection parameter.
A datetime (or pure date or time) parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMaximum(const QDateTime &maximum)
Sets the maximum value acceptable by the parameter.
static QgsProcessingParameterDateTime * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QDateTime minimum() const
Returns the minimum value acceptable by the parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString toolTip() const override
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
void setMinimum(const QDateTime &minimum)
Sets the minimum value acceptable by the parameter.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QDateTime maximum() const
Returns the maximum value acceptable by the parameter.
QgsProcessingParameterDateTime(const QString &name, const QString &description=QString(), Type type=DateTime, const QVariant &defaultValue=QVariant(), bool optional=false, const QDateTime &minValue=QDateTime(), const QDateTime &maxValue=QDateTime())
Constructor for QgsProcessingParameterDateTime.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Type dataType() const
Returns the acceptable data type for the parameter.
void setDataType(Type type)
Sets the acceptable data type for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
Base class for the definition of processing parameters.
QgsProcessingAlgorithm * mAlgorithm
Pointer to algorithm which owns this parameter.
virtual QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QVariant defaultValue() const
Returns the default value for the parameter.
QString valueAsStringPrivate(const QVariant &value, QgsProcessingContext &context, bool &ok, ValueAsStringFlags flags) const
Internal method for evaluating values as string.
QString help() const
Returns the help for the parameter.
virtual QString asScriptCode() const
Returns the parameter definition encoded in a string which can be used within a Processing script.
virtual QString toolTip() const
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
virtual QStringList valueAsStringList(const QVariant &value, QgsProcessingContext &context, bool &ok) const
Returns a string list version of the parameter input value (if possible).
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
QgsProcessingProvider * provider() const
Returns a pointer to the provider for the algorithm which owns this parameter.
@ AllowMapLayerValues
Enable map layer value handling.
virtual QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString description() const
Returns the description for the parameter.
QgsProcessingParameterDefinition(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QString &help=QString())
Constructor for QgsProcessingParameterDefinition.
virtual QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const
Returns a string version of the parameter input value (if possible).
QVariantMap mMetadata
Freeform metadata for parameter. Mostly used by widget wrappers to customize their appearance and beh...
QString mDescription
Parameter description.
virtual QString type() const =0
Unique parameter type name.
Flags flags() const
Returns any flags associated with the parameter.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QString name() const
Returns the name of the parameter.
QVariant mDefault
Default value for parameter.
QVariant mGuiDefault
Default value for parameter in GUI.
virtual QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
virtual bool fromVariantMap(const QVariantMap &map)
Restores this parameter to a QVariantMap.
virtual QString valueAsPythonComment(const QVariant &value, QgsProcessingContext &context) const
Returns a Python comment explaining a parameter value, or an empty string if no comment is required.
QVariant valueAsJsonObjectPrivate(const QVariant &value, QgsProcessingContext &context, ValueAsStringFlags flags) const
Internal method for evaluating values as JSON objects.
A double numeric parameter for distance values.
void setParentParameterName(const QString &parentParameterName)
Sets the name of the parent layer parameter.
static QString typeName()
Returns the type name for the parameter class.
QString parentParameterName() const
Returns the name of the parent parameter, or an empty string if this is not set.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDistance * clone() const override
Creates a clone of the parameter definition.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString type() const override
Unique parameter type name.
QgsProcessingParameterDistance(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentParameterName=QString(), bool optional=false, double minValue=std::numeric_limits< double >::lowest()+1, double maxValue=std::numeric_limits< double >::max())
Constructor for QgsProcessingParameterDistance.
A double numeric parameter for duration values.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDuration * clone() const override
Creates a clone of the parameter definition.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QString type() const override
Unique parameter type name.
QgsProcessingParameterDuration(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, double minValue=std::numeric_limits< double >::lowest()+1, double maxValue=std::numeric_limits< double >::max())
Constructor for QgsProcessingParameterDuration.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
void setUsesStaticStrings(bool usesStaticStrings)
Sets whether the parameter uses static (non-translated) string values for its enumeration choice list...
static QgsProcessingParameterEnum * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
bool allowMultiple() const
Returns true if the parameter allows multiple selected values.
QStringList options() const
Returns the list of acceptable options for the parameter.
QgsProcessingParameterEnum(const QString &name, const QString &description=QString(), const QStringList &options=QStringList(), bool allowMultiple=false, const QVariant &defaultValue=QVariant(), bool optional=false, bool usesStaticStrings=false)
Constructor for QgsProcessingParameterEnum.
void setOptions(const QStringList &options)
Sets the list of acceptable options for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool usesStaticStrings() const
Returns true if the parameter uses static (non-translated) string values for its enumeration choice l...
QString valueAsPythonComment(const QVariant &value, QgsProcessingContext &context) const override
Returns a Python comment explaining a parameter value, or an empty string if no comment is required.
void setAllowMultiple(bool allowMultiple)
Sets whether the parameter allows multiple selected values.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
An expression parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterExpression * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QgsProcessingParameterExpression(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), bool optional=false)
Constructor for QgsProcessingParameterExpression.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
static QString typeName()
Returns the type name for the parameter class.
A rectangular map extent parameter for processing algorithms.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterExtent(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterExtent.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterExtent * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
A feature sink output for processing algorithms.
QString generateTemporaryDestination() const override
Generates a temporary destination value for this parameter.
static QgsProcessingParameterFeatureSink * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
bool hasGeometry() const
Returns true if sink is likely to include geometries.
QString type() const override
Unique parameter type name.
QgsProcessing::SourceType dataType() const
Returns the layer type for sinks associated with the parameter.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
void setSupportsAppend(bool supportsAppend)
Sets whether the sink supports appending features to an existing table.
QgsProcessingParameterFeatureSink(const QString &name, const QString &description=QString(), QgsProcessing::SourceType type=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true, bool supportsAppend=false)
Constructor for QgsProcessingParameterFeatureSink.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the sinks associated with the parameter.
bool supportsAppend() const
Returns true if the sink supports appending features to an existing table.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
An input feature source (such as vector layers) parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterFeatureSource(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterFeatureSource.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
static QString typeName()
Returns the type name for the parameter class.
QString type() const override
Unique parameter type name.
static QgsProcessingParameterFeatureSource * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
A vector layer or feature source field parameter for processing algorithms.
QgsProcessingParameterField(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), DataType type=Any, bool allowMultiple=false, bool optional=false, bool defaultToAllFields=false)
Constructor for QgsProcessingParameterField.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set.
void setDataType(DataType type)
Sets the acceptable data type for the field.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
bool allowMultiple() const
Returns whether multiple field selections are permitted.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString type() const override
Unique parameter type name.
bool defaultToAllFields() const
Returns whether a parameter which allows multiple selections (see allowMultiple()) should automatical...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
void setAllowMultiple(bool allowMultiple)
Sets whether multiple field selections are permitted.
@ DateTime
Accepts datetime fields.
@ Numeric
Accepts numeric fields.
DataType dataType() const
Returns the acceptable data type for the field.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
void setDefaultToAllFields(bool enabled)
Sets whether a parameter which allows multiple selections (see allowMultiple()) should automatically ...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterField * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
static QgsProcessingParameterFileDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterFileDestination(const QString &name, const QString &description=QString(), const QString &fileFilter=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFileDestination.
static QString typeName()
Returns the type name for the parameter class.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString fileFilter() const
Returns the file filter string for file destinations compatible with this parameter.
void setFileFilter(const QString &filter)
Sets the file filter string for file destinations compatible with this parameter.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
An input file or folder parameter for processing algorithms.
QString extension() const
Returns any specified file extension for the parameter.
void setExtension(const QString &extension)
Sets a file extension for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
void setFileFilter(const QString &filter)
Sets the file filter string for file destinations compatible with this parameter.
static QgsProcessingParameterFile * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition, Behavior behavior=File)
Creates a new parameter using the definition from a script code.
@ File
Parameter is a single file.
Behavior behavior() const
Returns the parameter behavior (e.g.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString fileFilter() const
Returns the file filter string for file destinations compatible with this parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingParameterFile(const QString &name, const QString &description=QString(), Behavior behavior=File, const QString &extension=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QString &fileFilter=QString())
Constructor for QgsProcessingParameterFile.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
A folder destination parameter, for specifying the destination path for a folder created by the algor...
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
static QgsProcessingParameterFolderDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterFolderDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFolderDestination.
A geometry parameter for processing algorithms.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString type() const override
Unique parameter type name.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterGeometry(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QList< int > &geometryTypes=QList< int >(), bool allowMultipart=true)
Constructor for QgsProcessingParameterGeometry.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingParameterGeometry * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A print layout item parameter, allowing users to select a particular item from a print layout.
QString type() const override
Unique parameter type name.
static QgsProcessingParameterLayoutItem * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterLayoutItem(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayoutParameterName=QString(), int itemType=-1, bool optional=false)
Constructor for QgsProcessingParameterLayoutItem.
void setParentLayoutParameterName(const QString &name)
Sets the name of the parent layout parameter.
QString parentLayoutParameterName() const
Returns the name of the parent layout parameter, or an empty string if this is not set.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
int itemType() const
Returns the acceptable item type, or -1 if any item type is allowed.
void setItemType(int type)
Sets the acceptable item type, or -1 if any item type is allowed.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A print layout parameter, allowing users to select a print layout.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QgsProcessingParameterLayout * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterLayout(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterLayout.
static QString typeName()
Returns the type name for the parameter class.
Can be inherited by parameters which require limits to their acceptable data types.
void setDataTypes(const QList< int > &types)
Sets the geometry types for sources acceptable by the parameter.
QgsProcessingParameterLimitedDataTypes(const QList< int > &types=QList< int >())
Constructor for QgsProcessingParameterLimitedDataTypes, with a list of acceptable data types.
QList< int > mDataTypes
List of acceptable data types for the parameter.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
A map layer parameter for processing algorithms.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterMapLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString type() const override
Unique parameter type name.
QgsProcessingParameterMapLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, const QList< int > &types=QList< int >())
Constructor for QgsProcessingParameterMapLayer.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
A map theme parameter for processing algorithms, allowing users to select an existing map theme from ...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterMapTheme * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterMapTheme(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMapTheme.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
A table (matrix) parameter for processing algorithms.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QStringList headers() const
Returns a list of column headers (if set).
void setHeaders(const QStringList &headers)
Sets the list of column headers.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
void setHasFixedNumberRows(bool hasFixedNumberRows)
Sets whether the table has a fixed number of rows.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
void setNumberRows(int rows)
Sets the fixed number of rows in the table.
int numberRows() const
Returns the fixed number of rows in the table.
static QgsProcessingParameterMatrix * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QString typeName()
Returns the type name for the parameter class.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterMatrix(const QString &name, const QString &description=QString(), int numberRows=3, bool hasFixedNumberRows=false, const QStringList &headers=QStringList(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMatrix.
bool hasFixedNumberRows() const
Returns whether the table has a fixed number of rows.
A mesh layer parameter for processing algorithms.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
QgsProcessingParameterMeshLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMeshLayer.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QgsProcessingParameterMeshLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
static QString typeName()
Returns the type name for the parameter class.
A parameter for processing algorithms which accepts multiple map layers.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
void setMinimumNumberInputs(int minimum)
Sets the minimum number of layers required for the parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QgsProcessingParameterMultipleLayers(const QString &name, const QString &description=QString(), QgsProcessing::SourceType layerType=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMultipleLayers.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setLayerType(QgsProcessing::SourceType type)
Sets the layer type for layers acceptable by the parameter.
static QgsProcessingParameterMultipleLayers * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessing::SourceType layerType() const
Returns the layer type for layers acceptable by the parameter.
QString type() const override
Unique parameter type name.
int minimumNumberInputs() const
Returns the minimum number of layers required for the parameter.
A numeric parameter for processing algorithms.
double minimum() const
Returns the minimum value acceptable by the parameter.
static QgsProcessingParameterNumber * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
void setMinimum(double minimum)
Sets the minimum value acceptable by the parameter.
void setMaximum(double maximum)
Sets the maximum value acceptable by the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
double maximum() const
Returns the maximum value acceptable by the parameter.
QgsProcessingParameterNumber(const QString &name, const QString &description=QString(), Type type=Integer, const QVariant &defaultValue=QVariant(), bool optional=false, double minValue=std::numeric_limits< double >::lowest()+1, double maxValue=std::numeric_limits< double >::max())
Constructor for QgsProcessingParameterNumber.
void setDataType(Type type)
Sets the acceptable data type for the parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
Type dataType() const
Returns the acceptable data type for the parameter.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString toolTip() const override
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
A point cloud layer destination parameter, for specifying the destination path for a point cloud laye...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterPointCloudDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
virtual QStringList supportedOutputPointCloudLayerExtensions() const
Returns a list of the point cloud format file extensions supported for this parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterPointCloudDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterPointCloudDestination.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
A point cloud layer parameter for processing algorithms.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
static QgsProcessingParameterPointCloudLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterPointCloudLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterPointCloudLayer.
A point parameter for processing algorithms.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterPoint * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterPoint(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterPoint.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
A data provider connection parameter for processing algorithms, allowing users to select from availab...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterProviderConnection(const QString &name, const QString &description, const QString &provider, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterProviderConnection, for the specified provider type.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
static QgsProcessingParameterProviderConnection * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A numeric range parameter for processing algorithms.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterNumber::Type dataType() const
Returns the acceptable data type for the range.
static QString typeName()
Returns the type name for the parameter class.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
void setDataType(QgsProcessingParameterNumber::Type dataType)
Sets the acceptable data type for the range.
QgsProcessingParameterRange(const QString &name, const QString &description=QString(), QgsProcessingParameterNumber::Type type=QgsProcessingParameterNumber::Integer, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRange.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterRange * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QgsProcessingParameterRasterDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterRasterDestination.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QgsProcessingParameterRasterDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
virtual QStringList supportedOutputRasterLayerExtensions() const
Returns a list of the raster format file extensions supported for this parameter.
static QString typeName()
Returns the type name for the parameter class.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
A raster layer parameter for processing algorithms.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
static QgsProcessingParameterRasterLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterRasterLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRasterLayer.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
A double numeric parameter for map scale values.
QString type() const override
Unique parameter type name.
static QString typeName()
Returns the type name for the parameter class.
static QgsProcessingParameterScale * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterScale * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterScale(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterScale.
A string parameter for processing algorithms.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMultiLine(bool multiLine)
Sets whether the parameter allows multiline strings.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
static QgsProcessingParameterString * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool multiLine() const
Returns true if the parameter allows multiline strings.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingParameterString(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool multiLine=false, bool optional=false)
Constructor for QgsProcessingParameterString.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
Makes metadata of processing parameters available.
virtual QgsProcessingParameterDefinition * create(const QString &name) const =0
Creates a new parameter of this type.
A vector layer destination parameter, for specifying the destination path for a vector layer created ...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QgsProcessing::SourceType dataType() const
Returns the layer type for this created vector layer.
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QString type() const override
Unique parameter type name.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the created vector layer.
QgsProcessingParameterVectorDestination(const QString &name, const QString &description=QString(), QgsProcessing::SourceType type=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterVectorDestination.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
bool hasGeometry() const
Returns true if the created layer is likely to include geometries.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
static QgsProcessingParameterVectorDestination * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
A vector layer (with or without geometry) parameter for processing algorithms.
static QgsProcessingParameterVectorLayer * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QString valueAsString(const QVariant &value, QgsProcessingContext &context, bool &ok) const override
Returns a string version of the parameter input value (if possible).
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QString type() const override
Unique parameter type name.
QString createFileFilter() const override
This method needs to be reimplemented in all classes which implement this interface and return a file...
QString asPythonString(QgsProcessing::PythonOutputType outputType=QgsProcessing::PythonQgsProcessingAlgorithmSubclass) const override
Returns the parameter definition as a Python command which can be used within a Python Processing scr...
QgsProcessingParameterVectorLayer(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterVectorLayer.
static QString typeName()
Returns the type name for the parameter class.
QVariant valueAsJsonObject(const QVariant &value, QgsProcessingContext &context) const override
Returns a version of the parameter input value, which is suitable for use in a JSON object.
QString valueAsPythonString(const QVariant &value, QgsProcessingContext &context) const override
Returns a string version of the parameter input value, which is suitable for use as an input paramete...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QList< QgsMapLayer * > parameterAsLayerList(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of map layers.
static QString descriptionFromName(const QString &name)
Creates an autogenerated parameter description from a parameter name.
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
static double parameterAsDouble(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static double value.
static QgsPointXY parameterAsPoint(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a point.
static QString parameterAsOutputLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a output layer destination.
static QgsPrintLayout * parameterAsLayout(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a print layout.
static QTime parameterAsTime(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static time value.
static QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map.
static QgsRectangle parameterAsExtent(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a rectangular extent.
static QgsCoordinateReferenceSystem parameterAsGeometryCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with a geometry parameter value.
static QgsAnnotationLayer * parameterAsAnnotationLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to an annotation layer.
static QString parameterAsEnumString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static enum string.
static QList< double > parameterAsRange(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a range of values.
static QgsMapLayer * parameterAsLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingUtils::LayerHint layerHint=QgsProcessingUtils::LayerHint::UnknownType)
Evaluates the parameter with matching definition to a map layer.
static QList< int > parameterAsInts(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of integer values.
static QString parameterAsConnectionName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a connection name string.
static QgsProcessingFeatureSource * parameterAsSource(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a feature source.
static QString parameterAsFileOutput(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file based output destination.
static QgsFeatureSink * parameterAsSink(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), const QVariantMap &createOptions=QVariantMap(), const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList())
Evaluates the parameter with matching definition to a feature sink.
static bool parameterAsBoolean(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
static QgsCoordinateReferenceSystem parameterAsPointCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an point parameter value.
static QgsLayoutItem * parameterAsLayoutItem(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, QgsPrintLayout *layout)
Evaluates the parameter with matching definition to a print layout item, taken from the specified lay...
static bool parameterAsBool(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
static QString parameterAsCompatibleSourceLayerPathAndLayerName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat=QString("shp"), QgsProcessingFeedback *feedback=nullptr, QString *layerName=nullptr)
Evaluates the parameter with matching definition to a source vector layer file path and layer name of...
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
static QString parameterAsCompatibleSourceLayerPath(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat=QString("shp"), QgsProcessingFeedback *feedback=nullptr)
Evaluates the parameter with matching definition to a source vector layer file path of compatible for...
static QgsProcessingParameterDefinition * parameterFromScriptCode(const QString &code)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied script code st...
static QColor parameterAsColor(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the color associated with an point parameter value, or an invalid color if the parameter was ...
static QgsVectorLayer * parameterAsVectorLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a vector layer.
static QgsPointCloudLayer * parameterAsPointCloudLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a point cloud layer.
static int parameterAsInt(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static integer value.
static QString parameterAsDatabaseTableName(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a database table name.
static QString parameterAsSchema(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a database schema name.
static QgsGeometry parameterAsGeometry(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a geometry.
static QString parameterAsExpression(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to an expression.
static QString parameterAsString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static string value.
static QgsRasterLayer * parameterAsRasterLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a raster layer.
static QList< int > parameterAsEnums(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to list of enum values.
static QStringList parameterAsEnumStrings(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to list of static enum strings.
static QgsGeometry parameterAsExtentGeometry(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a rectangular extent, and returns a geometry cove...
static QStringList parameterAsFileList(const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of files (for QgsProcessingParameterMultip...
static bool isDynamic(const QVariantMap &parameters, const QString &name)
Returns true if the parameter with matching name is a dynamic parameter, and must be evaluated once f...
static QStringList parameterAsFields(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of fields.
static QgsCoordinateReferenceSystem parameterAsExtentCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an extent parameter value.
static QDateTime parameterAsDateTime(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static datetime value.
static QString parameterAsFile(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file/folder name.
static QDate parameterAsDate(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static date value.
static QVariantList parameterAsMatrix(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a matrix/table of values.
static QgsCoordinateReferenceSystem parameterAsCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a coordinate reference system.
Abstract base class for processing providers.
virtual bool isSupportedOutputValue(const QVariant &outputValue, const QgsProcessingDestinationParameter *parameter, QgsProcessingContext &context, QString &error) const
Returns true if the specified outputValue is of a supported file format for the given destination par...
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
static QString convertToCompatibleFormat(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, long long featureLimit=-1)
Converts a source vector layer to a file path of a vector layer of compatible format.
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
static QString defaultVectorExtension()
Returns the default vector extension to use, in the absence of all other constraints (e....
static QString normalizeLayerSource(const QString &source)
Normalizes a layer source string for safe comparison across different operating system environments.
static QgsFeatureSink * createFeatureSink(QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions=QVariantMap(), const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), QgsRemappingSinkDefinition *remappingDefinition=nullptr)
Creates a feature sink ready for adding features.
static QString encodeProviderKeyAndUri(const QString &providerKey, const QString &uri)
Encodes a provider key and layer uri to a single string, for use with decodeProviderKeyAndUri()
LayerHint
Layer type hints.
@ Annotation
Annotation layer type, since QGIS 3.22.
@ Vector
Vector layer type.
@ Mesh
Mesh layer type, since QGIS 3.6.
@ Raster
Raster layer type.
@ UnknownType
Unknown layer type.
@ PointCloud
Point cloud layer type, since QGIS 3.22.
static QString generateTempFilename(const QString &basename)
Returns a temporary filename for a given file, putting it into a temporary folder (creating that fold...
static QgsProcessingFeatureSource * variantToSource(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a new feature source.
static QString convertToCompatibleFormatAndLayerName(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString &layerName, long long featureLimit=-1)
Converts a source vector layer to a file path and layer name of a vector layer of compatible format.
static QString variantToPythonLiteral(const QVariant &value)
Converts a variant to a Python literal.
static QgsCoordinateReferenceSystem variantToCrs(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a coordinate reference system.
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers=true, QgsProcessingUtils::LayerHint typeHint=QgsProcessingUtils::LayerHint::UnknownType)
Interprets a string as a map layer within the supplied context.
static QString defaultRasterExtension()
Returns the default raster extension to use, in the absence of all other constraints (e....
static QString defaultPointCloudExtension()
Returns the default point cloud extension to use, in the absence of all other constraints (e....
static const QString TEMPORARY_OUTPUT
Constant used to indicate that a Processing algorithm output should be a temporary layer/file.
PythonOutputType
Available Python output types.
Definition: qgsprocessing.h:63
@ PythonQgsProcessingAlgorithmSubclass
Full Python QgsProcessingAlgorithm subclass.
Definition: qgsprocessing.h:64
SourceType
Data source types enum.
Definition: qgsprocessing.h:46
@ TypePlugin
Plugin layers.
Definition: qgsprocessing.h:56
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:50
@ TypeMapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer)
Definition: qgsprocessing.h:47
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:51
@ TypeFile
Files (i.e. non map layer sources, such as text files)
Definition: qgsprocessing.h:53
@ TypeAnnotation
Annotation layers.
Definition: qgsprocessing.h:58
@ TypePointCloud
Point cloud layers.
Definition: qgsprocessing.h:57
@ TypeMesh
Mesh layers.
Definition: qgsprocessing.h:55
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:54
@ TypeRaster
Raster layers.
Definition: qgsprocessing.h:52
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:49
@ TypeVectorAnyGeometry
Any vector layer with geometry.
Definition: qgsprocessing.h:48
static QString sourceTypeToString(SourceType type)
Converts a source type to a string representation.
Definition: qgsprocessing.h:72
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:104
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
A store for object properties.
Definition: qgsproperty.h:230
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:239
@ StaticProperty
Static property (QgsStaticProperty)
Definition: qgsproperty.h:237
@ FieldBasedProperty
Field based property (QgsFieldBasedProperty)
Definition: qgsproperty.h:238
@ InvalidProperty
Invalid (not set) property.
Definition: qgsproperty.h:236
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
QString valueAsString(const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a string.
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
QVariant toVariant() const
Saves this property to a QVariantMap, wrapped in a QVariant.
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
QVariant staticValue() const
Returns the current static value for the property.
Type propertyType() const
Returns the property type.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString fileVectorFilters() const
Returns a file filter string for supported vector files.
QString fileRasterFilters() const
Returns a file filter string for supported raster files.
QString fileMeshFilters() const
Returns a file filter string for supported mesh files.
QString filePointCloudFilters() const
Returns a file filter string for supported point clouds.
static QStringList supportedFormatExtensions(RasterFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats.
Represents a raster layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsGeometry with associated coordinate reference system.
static QgsReferencedGeometry fromReferencedPointXY(const QgsReferencedPointXY &point)
Construct a new QgsReferencedGeometry from referenced point.
static QgsReferencedGeometry fromReferencedRect(const QgsReferencedRectangle &rectangle)
Construct a new QgsReferencedGeometry from referenced rectangle.
A QgsPointXY with associated coordinate reference system.
A QgsRectangle with associated coordinate reference system.
Defines the parameters used to remap features when creating a QgsRemappingProxyFeatureSink.
static QColor parseColorWithAlpha(const QString &colorStr, bool &containsAlpha, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes,...
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
TemporalUnit
Temporal units.
Definition: qgsunittypes.h:150
@ TemporalDays
Days.
Definition: qgsunittypes.h:155
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
Represents a vector layer which manages a vector based data sets.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:2466
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QString parameterAsCompatibleSourceLayerPathInternal(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback, QString *layerName)
QString createAllMapLayerFileFilter()
const QgsCoordinateReferenceSystem & crs
const QString & typeName