QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 
19 #include "qgsprocessingprovider.h"
20 #include "qgsprocessingcontext.h"
21 #include "qgsprocessingutils.h"
22 #include "qgsprocessingalgorithm.h"
24 #include "qgsprocessingoutputs.h"
25 #include "qgssettings.h"
26 #include "qgsvectorfilewriter.h"
27 #include "qgsreferencedgeometry.h"
28 #include "qgsprocessingregistry.h"
30 #include "qgsrasterfilewriter.h"
31 #include "qgsvectorlayer.h"
32 #include "qgsmeshlayer.h"
33 #include "qgsapplication.h"
34 #include "qgslayoutmanager.h"
35 #include "qgsprintlayout.h"
36 #include <functional>
37 
38 
40 {
41  QVariantMap map;
42  map.insert( QStringLiteral( "sink" ), sink.toVariant() );
43  map.insert( QStringLiteral( "create_options" ), createOptions );
44  return map;
45 }
46 
48 {
49  sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
50  createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
51  return true;
52 }
53 
54 bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
55 {
56  QVariant val = parameters.value( name );
57  if ( val.canConvert<QgsProperty>() )
58  return val.value< QgsProperty >().propertyType() != QgsProperty::StaticProperty;
59  else
60  return false;
61 }
62 
63 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
64 {
65  if ( !definition )
66  return QString();
67 
68  return parameterAsString( definition, parameters.value( definition->name() ), context );
69 }
70 
71 QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
72 {
73  if ( !definition )
74  return QString();
75 
76  QVariant val = value;
77  if ( val.canConvert<QgsProperty>() )
78  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
79 
80  if ( !val.isValid() )
81  {
82  // fall back to default
83  val = definition->defaultValue();
84  }
85 
87  {
88  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
89  return destParam->generateTemporaryDestination();
90  }
91 
92  return val.toString();
93 }
94 
95 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
96 {
97  if ( !definition )
98  return QString();
99 
100  return parameterAsExpression( definition, parameters.value( definition->name() ), context );
101 }
102 
103 QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
104 {
105  if ( !definition )
106  return QString();
107 
108  QVariant val = value;
109  if ( val.canConvert<QgsProperty>() )
110  return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
111 
112  if ( val.isValid() && !val.toString().isEmpty() )
113  {
114  QgsExpression e( val.toString() );
115  if ( e.isValid() )
116  return val.toString();
117  }
118 
119  // fall back to default
120  return definition->defaultValue().toString();
121 }
122 
123 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
124 {
125  if ( !definition )
126  return 0;
127 
128  return parameterAsDouble( definition, parameters.value( definition->name() ), context );
129 }
130 
131 double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
132 {
133  if ( !definition )
134  return 0;
135 
136  QVariant val = value;
137  if ( val.canConvert<QgsProperty>() )
138  return val.value< QgsProperty >().valueAsDouble( context.expressionContext(), definition->defaultValue().toDouble() );
139 
140  bool ok = false;
141  double res = val.toDouble( &ok );
142  if ( ok )
143  return res;
144 
145  // fall back to default
146  val = definition->defaultValue();
147  return val.toDouble();
148 }
149 
150 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
151 {
152  if ( !definition )
153  return 0;
154 
155  return parameterAsInt( definition, parameters.value( definition->name() ), context );
156 }
157 
158 int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
159 {
160  if ( !definition )
161  return 0;
162 
163  QVariant val = value;
164  if ( val.canConvert<QgsProperty>() )
165  return val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
166 
167  bool ok = false;
168  double dbl = val.toDouble( &ok );
169  if ( !ok )
170  {
171  // fall back to default
172  val = definition->defaultValue();
173  dbl = val.toDouble( &ok );
174  }
175 
176  //String representations of doubles in QVariant will not convert to int
177  //work around this by first converting to double, and then checking whether the double is convertible to int
178  if ( ok )
179  {
180  double round = std::round( dbl );
181  if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
182  {
183  //double too large to fit in int
184  return 0;
185  }
186  return static_cast< int >( std::round( dbl ) );
187  }
188 
189  return val.toInt();
190 }
191 
192 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
193 {
194  if ( !definition )
195  return QList< int >();
196 
197  return parameterAsInts( definition, parameters.value( definition->name() ), context );
198 }
199 
200 QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
201 {
202  if ( !definition )
203  return QList< int >();
204 
205  QList< int > resultList;
206  QVariant val = value;
207  if ( val.isValid() )
208  {
209  if ( val.canConvert<QgsProperty>() )
210  resultList << val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
211  else if ( val.type() == QVariant::List )
212  {
213  QVariantList list = val.toList();
214  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
215  resultList << it->toInt();
216  }
217  else
218  {
219  QStringList parts = val.toString().split( ';' );
220  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
221  resultList << it->toInt();
222  }
223  }
224 
225  if ( ( resultList.isEmpty() || resultList.at( 0 ) == 0 ) )
226  {
227  resultList.clear();
228  // check default
229  if ( definition->defaultValue().isValid() )
230  {
231  if ( definition->defaultValue().type() == QVariant::List )
232  {
233  QVariantList list = definition->defaultValue().toList();
234  for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
235  resultList << it->toInt();
236  }
237  else
238  {
239  QStringList parts = definition->defaultValue().toString().split( ';' );
240  for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
241  resultList << it->toInt();
242  }
243  }
244  }
245 
246  return resultList;
247 }
248 
249 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
250 {
251  if ( !definition )
252  return 0;
253 
254  return parameterAsEnum( definition, parameters.value( definition->name() ), context );
255 }
256 
257 int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
258 {
259  if ( !definition )
260  return 0;
261 
262  int val = parameterAsInt( definition, value, context );
263  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
264  if ( enumDef && val >= enumDef->options().size() )
265  {
266  return enumDef->defaultValue().toInt();
267  }
268  return val;
269 }
270 
271 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
272 {
273  if ( !definition )
274  return QList<int>();
275 
276  return parameterAsEnums( definition, parameters.value( definition->name() ), context );
277 }
278 
279 QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
280 {
281  if ( !definition )
282  return QList<int>();
283 
284  QVariantList resultList;
285  QVariant val = value;
286  if ( val.canConvert<QgsProperty>() )
287  resultList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
288  else if ( val.type() == QVariant::List )
289  {
290  const auto constToList = val.toList();
291  for ( const QVariant &var : constToList )
292  resultList << var;
293  }
294  else if ( val.type() == QVariant::String )
295  {
296  const auto constSplit = val.toString().split( ',' );
297  for ( const QString &var : constSplit )
298  resultList << var;
299  }
300  else
301  resultList << val;
302 
303  if ( resultList.isEmpty() )
304  return QList< int >();
305 
306  if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
307  {
308  resultList.clear();
309  // check default
310  if ( definition->defaultValue().type() == QVariant::List )
311  {
312  const auto constToList = definition->defaultValue().toList();
313  for ( const QVariant &var : constToList )
314  resultList << var;
315  }
316  else if ( definition->defaultValue().type() == QVariant::String )
317  {
318  const auto constSplit = definition->defaultValue().toString().split( ',' );
319  for ( const QString &var : constSplit )
320  resultList << var;
321  }
322  else
323  resultList << definition->defaultValue();
324  }
325 
326  QList< int > result;
327  const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
328  const auto constResultList = resultList;
329  for ( const QVariant &var : constResultList )
330  {
331  int resInt = var.toInt();
332  if ( !enumDef || resInt < enumDef->options().size() )
333  {
334  result << resInt;
335  }
336  }
337  return result;
338 }
339 
340 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
341 {
342  if ( !definition )
343  return false;
344 
345  return parameterAsBool( definition, parameters.value( definition->name() ), context );
346 }
347 
348 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
349 {
350  if ( !definition )
351  return false;
352 
353  return parameterAsBoolean( definition, parameters.value( definition->name() ), context );
354 }
355 
356 bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
357 {
358  if ( !definition )
359  return false;
360 
361  QVariant def = definition->defaultValue();
362 
363  QVariant val = value;
364  if ( val.canConvert<QgsProperty>() )
365  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
366  else if ( val.isValid() )
367  return val.toBool();
368  else
369  return def.toBool();
370 }
371 
372 bool QgsProcessingParameters::parameterAsBoolean( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
373 {
374  if ( !definition )
375  return false;
376 
377  QVariant def = definition->defaultValue();
378 
379  QVariant val = value;
380  if ( val.canConvert<QgsProperty>() )
381  return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
382  else if ( val.isValid() )
383  return val.toBool();
384  else
385  return def.toBool();
386 }
387 
388 QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
390  QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags )
391 {
392  QVariant val;
393  if ( definition )
394  {
395  val = parameters.value( definition->name() );
396  }
397 
398  return parameterAsSink( definition, val, fields, geometryType, crs, context, destinationIdentifier, sinkFlags );
399 }
400 
401 QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags )
402 {
403  QVariant val = value;
404 
405  QgsProject *destinationProject = nullptr;
406  QString destName;
407  QVariantMap createOptions;
408  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
409  {
410  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
412  destinationProject = fromVar.destinationProject;
413  createOptions = fromVar.createOptions;
414 
415  val = fromVar.sink;
416  destName = fromVar.destinationName;
417  }
418 
419  QString dest;
420  if ( val.canConvert<QgsProperty>() )
421  {
422  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
423  }
424  else if ( !val.isValid() || val.toString().isEmpty() )
425  {
426  if ( definition && definition->flags() & QgsProcessingParameterDefinition::FlagOptional && !definition->defaultValue().isValid() )
427  {
428  // unset, optional sink, no default => no sink
429  return nullptr;
430  }
431  // fall back to default
432  dest = definition->defaultValue().toString();
433  }
434  else
435  {
436  dest = val.toString();
437  }
438  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
439  {
440  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
441  dest = destParam->generateTemporaryDestination();
442  }
443 
444  if ( dest.isEmpty() )
445  return nullptr;
446 
447  std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, createOptions, sinkFlags ) );
448  destinationIdentifier = dest;
449 
450  if ( destinationProject )
451  {
452  if ( destName.isEmpty() && definition )
453  {
454  destName = definition->description();
455  }
456  QString outputName;
457  if ( definition )
458  outputName = definition->name();
459  context.addLayerToLoadOnCompletion( destinationIdentifier, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, QgsProcessingUtils::LayerHint::Vector ) );
460  }
461 
462  return sink.release();
463 }
464 
466 {
467  if ( !definition )
468  return nullptr;
469 
470  return parameterAsSource( definition, parameters.value( definition->name() ), context );
471 }
472 
474 {
475  if ( !definition )
476  return nullptr;
477 
478  return QgsProcessingUtils::variantToSource( value, context, definition->defaultValue() );
479 }
480 
481 QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback )
482 {
483  if ( !definition )
484  return QString();
485 
486  QVariant val = parameters.value( definition->name() );
487 
488  bool selectedFeaturesOnly = false;
489  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
490  {
491  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
493  selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
494  val = fromVar.source;
495  }
496  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
497  {
498  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
500  val = fromVar.sink;
501  }
502 
503  if ( val.canConvert<QgsProperty>() )
504  {
505  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
506  }
507 
508  QgsVectorLayer *vl = nullptr;
509  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
510 
511  if ( !vl )
512  {
513  QString layerRef;
514  if ( val.canConvert<QgsProperty>() )
515  {
516  layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
517  }
518  else if ( !val.isValid() || val.toString().isEmpty() )
519  {
520  // fall back to default
521  val = definition->defaultValue();
522 
523  // default value may be a vector layer
524  vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
525  if ( !vl )
526  layerRef = definition->defaultValue().toString();
527  }
528  else
529  {
530  layerRef = val.toString();
531  }
532 
533  if ( !vl )
534  {
535  if ( layerRef.isEmpty() )
536  return QString();
537 
538  vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, QgsProcessingUtils::LayerHint::Vector ) );
539  }
540  }
541 
542  if ( !vl )
543  return QString();
544 
545  return QgsProcessingUtils::convertToCompatibleFormat( vl, selectedFeaturesOnly, definition->name(),
546  compatibleFormats, preferredFormat, context, feedback );
547 }
548 
549 
551 {
552  if ( !definition )
553  return nullptr;
554 
555  return parameterAsLayer( definition, parameters.value( definition->name() ), context );
556 }
557 
559 {
560  if ( !definition )
561  return nullptr;
562 
563  QVariant val = value;
564  if ( val.canConvert<QgsProperty>() )
565  {
566  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
567  }
568 
569  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
570  {
571  return layer;
572  }
573 
574  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
575  {
576  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
578  val = fromVar.sink;
579  }
580 
581  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
582  {
583  val = val.value< QgsProperty >().staticValue();
584  }
585 
586  if ( !val.isValid() || val.toString().isEmpty() )
587  {
588  // fall back to default
589  val = definition->defaultValue();
590  }
591 
592  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
593  {
594  return layer;
595  }
596 
597  QString layerRef = val.toString();
598  if ( layerRef.isEmpty() )
599  layerRef = definition->defaultValue().toString();
600 
601  if ( layerRef.isEmpty() )
602  return nullptr;
603 
604  return QgsProcessingUtils::mapLayerFromString( layerRef, context );
605 }
606 
608 {
609  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, parameters, context ) );
610 }
611 
613 {
614  return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, value, context ) );
615 }
616 
618 {
619  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, parameters, context ) );
620 }
621 
623 {
624  return qobject_cast< QgsMeshLayer *>( parameterAsLayer( definition, value, context ) );
625 }
626 
627 QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
628 {
629  QVariant val;
630  if ( definition )
631  {
632  val = parameters.value( definition->name() );
633  }
634  return parameterAsOutputLayer( definition, val, context );
635 }
636 
638 {
639  QVariant val = value;
640 
641  QgsProject *destinationProject = nullptr;
642  QVariantMap createOptions;
643  QString destName;
644  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
645  {
646  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
648  destinationProject = fromVar.destinationProject;
649  createOptions = fromVar.createOptions;
650  val = fromVar.sink;
651  destName = fromVar.destinationName;
652  }
653 
654  QString dest;
655  if ( val.canConvert<QgsProperty>() )
656  {
657  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
658  }
659  else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
660  {
661  // fall back to default
662  dest = definition->defaultValue().toString();
663  }
664  else
665  {
666  dest = val.toString();
667  }
668  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
669  {
670  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
671  dest = destParam->generateTemporaryDestination();
672  }
673 
674  if ( destinationProject )
675  {
676  QString outputName;
677  if ( destName.isEmpty() && definition )
678  {
679  destName = definition->description();
680  }
681  if ( definition )
682  outputName = definition->name();
683 
687  else if ( definition->type() == QgsProcessingParameterRasterDestination::typeName() )
689 
690  context.addLayerToLoadOnCompletion( dest, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, layerTypeHint ) );
691  }
692 
693  return dest;
694 }
695 
696 QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
697 {
698  QVariant val;
699  if ( definition )
700  {
701  val = parameters.value( definition->name() );
702  }
703  return parameterAsFileOutput( definition, val, context );
704 }
705 
707 {
708  QVariant val = value;
709 
710  if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
711  {
712  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
714  val = fromVar.sink;
715  }
716 
717  QString dest;
718  if ( val.canConvert<QgsProperty>() )
719  {
720  dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
721  }
722  else if ( !val.isValid() || val.toString().isEmpty() )
723  {
724  // fall back to default
725  dest = definition->defaultValue().toString();
726  }
727  else
728  {
729  dest = val.toString();
730  }
731  if ( dest == QgsProcessing::TEMPORARY_OUTPUT )
732  {
733  if ( const QgsProcessingDestinationParameter *destParam = dynamic_cast< const QgsProcessingDestinationParameter * >( definition ) )
734  dest = destParam->generateTemporaryDestination();
735  }
736  return dest;
737 }
738 
740 {
741  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, parameters, context ) );
742 }
743 
745 {
746  return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, value, context ) );
747 }
748 
750 {
751  if ( !definition )
753 
754  return parameterAsCrs( definition, parameters.value( definition->name() ), context );
755 }
756 
758 {
759  if ( !definition )
761 
762  QVariant val = value;
763 
764  if ( val.canConvert<QgsCoordinateReferenceSystem>() )
765  {
766  // input is a QgsCoordinateReferenceSystem - done!
767  return val.value< QgsCoordinateReferenceSystem >();
768  }
769  else if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
770  {
771  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
773  val = fromVar.source;
774  }
775  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
776  {
777  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
779  val = fromVar.sink;
780  }
781 
782  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
783  {
784  val = val.value< QgsProperty >().staticValue();
785  }
786 
787  // maybe a map layer
788  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
789  return layer->crs();
790 
791  if ( val.canConvert<QgsProperty>() )
792  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
793 
794  if ( !val.isValid() )
795  {
796  // fall back to default
797  val = definition->defaultValue();
798  }
799 
800  QString crsText = val.toString();
801  if ( crsText.isEmpty() )
802  crsText = definition->defaultValue().toString();
803 
804  if ( crsText.isEmpty() )
806 
807  // maybe special string
808  if ( context.project() && crsText.compare( QLatin1String( "ProjectCrs" ), Qt::CaseInsensitive ) == 0 )
809  return context.project()->crs();
810 
811  // maybe a map layer reference
812  if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( crsText, context ) )
813  return layer->crs();
814 
815  // else CRS from string
817  crs.createFromString( crsText );
818  return crs;
819 }
820 
823 {
824  if ( !definition )
825  return QgsRectangle();
826 
827  return parameterAsExtent( definition, parameters.value( definition->name() ), context, crs );
828 }
829 
831 {
832  if ( !definition )
833  return QgsRectangle();
834 
835  QVariant val = value;
836 
837  if ( val.canConvert< QgsRectangle >() )
838  {
839  return val.value<QgsRectangle>();
840  }
841  if ( val.canConvert< QgsReferencedRectangle >() )
842  {
844  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
845  {
846  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
847  try
848  {
849  return ct.transformBoundingBox( rr );
850  }
851  catch ( QgsCsException & )
852  {
853  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
854  }
855  }
856  return rr;
857  }
858 
859  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
860  {
861  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
863  val = fromVar.source;
864  }
865  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
866  {
867  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
869  val = fromVar.sink;
870  }
871 
872  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
873  {
874  val = val.value< QgsProperty >().staticValue();
875  }
876 
877  // maybe parameter is a direct layer value?
878  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
879 
880  QString rectText;
881  if ( val.canConvert<QgsProperty>() )
882  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
883  else
884  rectText = val.toString();
885 
886  if ( rectText.isEmpty() && !layer )
887  return QgsRectangle();
888 
889  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
890  QRegularExpressionMatch match = rx.match( rectText );
891  if ( match.hasMatch() )
892  {
893  bool xMinOk = false;
894  double xMin = match.captured( 1 ).toDouble( &xMinOk );
895  bool xMaxOk = false;
896  double xMax = match.captured( 2 ).toDouble( &xMaxOk );
897  bool yMinOk = false;
898  double yMin = match.captured( 3 ).toDouble( &yMinOk );
899  bool yMaxOk = false;
900  double yMax = match.captured( 4 ).toDouble( &yMaxOk );
901  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
902  {
903  QgsRectangle rect( xMin, yMin, xMax, yMax );
904  QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
905  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
906  {
907  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
908  try
909  {
910  return ct.transformBoundingBox( rect );
911  }
912  catch ( QgsCsException & )
913  {
914  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
915  }
916  }
917  return rect;
918  }
919  }
920 
921  // try as layer extent
922  if ( !layer )
923  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
924 
925  if ( layer )
926  {
927  QgsRectangle rect = layer->extent();
928  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
929  {
930  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
931  try
932  {
933  return ct.transformBoundingBox( rect );
934  }
935  catch ( QgsCsException & )
936  {
937  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
938  }
939  }
940  return rect;
941  }
942  return QgsRectangle();
943 }
944 
946 {
947  if ( !definition )
948  return QgsGeometry();
949 
950  QVariant val = parameters.value( definition->name() );
951 
952  if ( val.canConvert< QgsReferencedRectangle >() )
953  {
956  if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
957  {
958  g = g.densifyByCount( 20 );
959  QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
960  try
961  {
962  g.transform( ct );
963  }
964  catch ( QgsCsException & )
965  {
966  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
967  }
968  return g;
969  }
970  }
971 
972  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
973  {
974  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
976  val = fromVar.source;
977  }
978  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
979  {
980  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
982  val = fromVar.sink;
983  }
984 
985  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
986  {
987  val = val.value< QgsProperty >().staticValue();
988  }
989 
990  QString rectText;
991  if ( val.canConvert<QgsProperty>() )
992  rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
993  else
994  rectText = val.toString();
995 
996  if ( !rectText.isEmpty() )
997  {
998  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
999  QRegularExpressionMatch match = rx.match( rectText );
1000  if ( match.hasMatch() )
1001  {
1002  bool xMinOk = false;
1003  double xMin = match.captured( 1 ).toDouble( &xMinOk );
1004  bool xMaxOk = false;
1005  double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1006  bool yMinOk = false;
1007  double yMin = match.captured( 3 ).toDouble( &yMinOk );
1008  bool yMaxOk = false;
1009  double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1010  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1011  {
1012  QgsRectangle rect( xMin, yMin, xMax, yMax );
1013  QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
1014  QgsGeometry g = QgsGeometry::fromRect( rect );
1015  if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
1016  {
1017  g = g.densifyByCount( 20 );
1018  QgsCoordinateTransform ct( rectCrs, crs, context.project() );
1019  try
1020  {
1021  g.transform( ct );
1022  }
1023  catch ( QgsCsException & )
1024  {
1025  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1026  }
1027  return g;
1028  }
1029  }
1030  }
1031  }
1032 
1033  // try as layer extent
1034 
1035  // maybe parameter is a direct layer value?
1036  QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1037  if ( !layer )
1038  layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
1039 
1040  if ( layer )
1041  {
1042  QgsRectangle rect = layer->extent();
1043  QgsGeometry g = QgsGeometry::fromRect( rect );
1044  if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
1045  {
1046  g = g.densifyByCount( 20 );
1047  QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
1048  try
1049  {
1050  g.transform( ct );
1051  }
1052  catch ( QgsCsException & )
1053  {
1054  QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
1055  }
1056  }
1057  return g;
1058  }
1059 
1060  return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
1061 }
1062 
1064 {
1065  QVariant val = parameters.value( definition->name() );
1066 
1067  if ( val.canConvert< QgsReferencedRectangle >() )
1068  {
1070  if ( rr.crs().isValid() )
1071  {
1072  return rr.crs();
1073  }
1074  }
1075 
1076  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1077  {
1078  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1080  val = fromVar.source;
1081  }
1082  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1083  {
1084  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1086  val = fromVar.sink;
1087  }
1088 
1089  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1090  {
1091  val = val.value< QgsProperty >().staticValue();
1092  }
1093 
1094  QString valueAsString;
1095  if ( val.canConvert<QgsProperty>() )
1096  valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1097  else
1098  valueAsString = val.toString();
1099 
1100  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1101 
1102  QRegularExpressionMatch match = rx.match( valueAsString );
1103  if ( match.hasMatch() )
1104  {
1105  QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
1106  if ( crs.isValid() )
1107  return crs;
1108  }
1109 
1110  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
1111  {
1112  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
1114  val = fromVar.source;
1115  }
1116  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
1117  {
1118  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1120  val = fromVar.sink;
1121  }
1122 
1123  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
1124  {
1125  val = val.value< QgsProperty >().staticValue();
1126  }
1127 
1128  // try as layer crs
1129  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1130  return layer->crs();
1131  else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( valueAsString, context ) )
1132  return layer->crs();
1133 
1134  if ( context.project() )
1135  return context.project()->crs();
1136  else
1138 }
1139 
1141 {
1142  if ( !definition )
1143  return QgsPointXY();
1144 
1145  return parameterAsPoint( definition, parameters.value( definition->name() ), context, crs );
1146 }
1147 
1149 {
1150  if ( !definition )
1151  return QgsPointXY();
1152 
1153  QVariant val = value;
1154  if ( val.canConvert< QgsPointXY >() )
1155  {
1156  return val.value<QgsPointXY>();
1157  }
1158  if ( val.canConvert< QgsGeometry >() )
1159  {
1160  const QgsGeometry geom = val.value<QgsGeometry>();
1161  if ( !geom.isNull() )
1162  return geom.centroid().asPoint();
1163  }
1164  if ( val.canConvert< QgsReferencedPointXY >() )
1165  {
1166  QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
1167  if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
1168  {
1169  QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
1170  try
1171  {
1172  return ct.transform( rp );
1173  }
1174  catch ( QgsCsException & )
1175  {
1176  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1177  }
1178  }
1179  return rp;
1180  }
1181 
1182  QString pointText = parameterAsString( definition, value, context );
1183  if ( pointText.isEmpty() )
1184  pointText = definition->defaultValue().toString();
1185 
1186  if ( pointText.isEmpty() )
1187  return QgsPointXY();
1188 
1189  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1190 
1191  QString valueAsString = parameterAsString( definition, value, context );
1192  QRegularExpressionMatch match = rx.match( valueAsString );
1193  if ( match.hasMatch() )
1194  {
1195  bool xOk = false;
1196  double x = match.captured( 1 ).toDouble( &xOk );
1197  bool yOk = false;
1198  double y = match.captured( 2 ).toDouble( &yOk );
1199 
1200  if ( xOk && yOk )
1201  {
1202  QgsPointXY pt( x, y );
1203 
1204  QgsCoordinateReferenceSystem pointCrs( match.captured( 3 ) );
1205  if ( crs.isValid() && pointCrs.isValid() && crs != pointCrs )
1206  {
1207  QgsCoordinateTransform ct( pointCrs, crs, context.project() );
1208  try
1209  {
1210  return ct.transform( pt );
1211  }
1212  catch ( QgsCsException & )
1213  {
1214  QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
1215  }
1216  }
1217  return pt;
1218  }
1219  }
1220 
1221  return QgsPointXY();
1222 }
1223 
1225 {
1226  QVariant val = parameters.value( definition->name() );
1227  return parameterAsPointCrs( definition, val, context );
1228 }
1229 
1231 {
1232  if ( value.canConvert< QgsReferencedPointXY >() )
1233  {
1234  QgsReferencedPointXY rr = value.value<QgsReferencedPointXY>();
1235  if ( rr.crs().isValid() )
1236  {
1237  return rr.crs();
1238  }
1239  }
1240 
1241  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1242 
1243  QString valueAsString = parameterAsString( definition, value, context );
1244  QRegularExpressionMatch match = rx.match( valueAsString );
1245  if ( match.hasMatch() )
1246  {
1247  QgsCoordinateReferenceSystem crs( match.captured( 3 ) );
1248  if ( crs.isValid() )
1249  return crs;
1250  }
1251 
1252  if ( context.project() )
1253  return context.project()->crs();
1254  else
1256 }
1257 
1258 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1259 {
1260  if ( !definition )
1261  return QString();
1262 
1263  QString fileText = parameterAsString( definition, parameters, context );
1264  if ( fileText.isEmpty() )
1265  fileText = definition->defaultValue().toString();
1266  return fileText;
1267 }
1268 
1269 QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1270 {
1271  if ( !definition )
1272  return QString();
1273 
1274  QString fileText = parameterAsString( definition, value, context );
1275  if ( fileText.isEmpty() )
1276  fileText = definition->defaultValue().toString();
1277  return fileText;
1278 }
1279 
1280 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1281 {
1282  if ( !definition )
1283  return QVariantList();
1284 
1285  return parameterAsMatrix( definition, parameters.value( definition->name() ), context );
1286 }
1287 
1288 QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1289 {
1290  if ( !definition )
1291  return QVariantList();
1292 
1293  QString resultString;
1294  QVariant val = value;
1295  if ( val.canConvert<QgsProperty>() )
1296  resultString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1297  else if ( val.type() == QVariant::List )
1298  return val.toList();
1299  else
1300  resultString = val.toString();
1301 
1302  if ( resultString.isEmpty() )
1303  {
1304  // check default
1305  if ( definition->defaultValue().type() == QVariant::List )
1306  return definition->defaultValue().toList();
1307  else
1308  resultString = definition->defaultValue().toString();
1309  }
1310 
1311  QVariantList result;
1312  const auto constSplit = resultString.split( ',' );
1313  for ( const QString &s : constSplit )
1314  result << s;
1315 
1316  return result;
1317 }
1318 
1319 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1320 {
1321  if ( !definition )
1322  return QList<QgsMapLayer *>();
1323 
1324  return parameterAsLayerList( definition, parameters.value( definition->name() ), context );
1325 }
1326 
1327 QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1328 {
1329  if ( !definition )
1330  return QList<QgsMapLayer *>();
1331 
1332  QVariant val = value;
1333  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1334  {
1335  return QList<QgsMapLayer *>() << layer;
1336  }
1337 
1338  QList<QgsMapLayer *> layers;
1339 
1340  std::function< void( const QVariant &var ) > processVariant;
1341  processVariant = [ &layers, &context, &definition, &processVariant ]( const QVariant & var )
1342  {
1343  if ( var.type() == QVariant::List )
1344  {
1345  const auto constToList = var.toList();
1346  for ( const QVariant &listVar : constToList )
1347  {
1348  processVariant( listVar );
1349  }
1350  }
1351  else if ( var.type() == QVariant::StringList )
1352  {
1353  const auto constToStringList = var.toStringList();
1354  for ( const QString &s : constToStringList )
1355  {
1356  processVariant( s );
1357  }
1358  }
1359  else if ( var.canConvert<QgsProperty>() )
1360  processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1361  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
1362  {
1363  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
1365  QVariant sink = fromVar.sink;
1366  if ( sink.canConvert<QgsProperty>() )
1367  {
1368  processVariant( sink.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
1369  }
1370  }
1371  else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1372  {
1373  layers << layer;
1374  }
1375  else
1376  {
1377  QgsMapLayer *alayer = QgsProcessingUtils::mapLayerFromString( var.toString(), context );
1378  if ( alayer )
1379  layers << alayer;
1380  }
1381  };
1382 
1383  processVariant( val );
1384 
1385  if ( layers.isEmpty() )
1386  {
1387  // check default
1388  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->defaultValue() ) ) )
1389  {
1390  layers << layer;
1391  }
1392  else if ( definition->defaultValue().type() == QVariant::List )
1393  {
1394  const auto constToList = definition->defaultValue().toList();
1395  for ( const QVariant &var : constToList )
1396  {
1397  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1398  {
1399  layers << layer;
1400  }
1401  else
1402  {
1403  processVariant( var );
1404  }
1405  }
1406  }
1407  else
1408  processVariant( definition->defaultValue() );
1409  }
1410 
1411  return layers;
1412 }
1413 
1414 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1415 {
1416  if ( !definition )
1417  return QList<double>();
1418 
1419  return parameterAsRange( definition, parameters.value( definition->name() ), context );
1420 }
1421 
1422 QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1423 {
1424  if ( !definition )
1425  return QList<double>();
1426 
1427  QStringList resultStringList;
1428  QVariant val = value;
1429  if ( val.canConvert<QgsProperty>() )
1430  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1431  else if ( val.type() == QVariant::List )
1432  {
1433  const auto constToList = val.toList();
1434  for ( const QVariant &var : constToList )
1435  resultStringList << var.toString();
1436  }
1437  else
1438  resultStringList << val.toString();
1439 
1440  if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
1441  {
1442  resultStringList.clear();
1443  // check default
1444  if ( definition->defaultValue().type() == QVariant::List )
1445  {
1446  const auto constToList = definition->defaultValue().toList();
1447  for ( const QVariant &var : constToList )
1448  resultStringList << var.toString();
1449  }
1450  else
1451  resultStringList << definition->defaultValue().toString();
1452  }
1453 
1454  if ( resultStringList.size() == 1 )
1455  {
1456  resultStringList = resultStringList.at( 0 ).split( ',' );
1457  }
1458 
1459  if ( resultStringList.size() < 2 )
1460  return QList< double >() << 0.0 << 0.0;
1461 
1462  return QList< double >() << resultStringList.at( 0 ).toDouble() << resultStringList.at( 1 ).toDouble();
1463 }
1464 
1465 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
1466 {
1467  if ( !definition )
1468  return QStringList();
1469 
1470  QStringList resultStringList;
1471  return parameterAsFields( definition, parameters.value( definition->name() ), context );
1472 }
1473 
1474 QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
1475 {
1476  if ( !definition )
1477  return QStringList();
1478 
1479  QStringList resultStringList;
1480  QVariant val = value;
1481  if ( val.isValid() )
1482  {
1483  if ( val.canConvert<QgsProperty>() )
1484  resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
1485  else if ( val.type() == QVariant::List )
1486  {
1487  const auto constToList = val.toList();
1488  for ( const QVariant &var : constToList )
1489  resultStringList << var.toString();
1490  }
1491  else
1492  resultStringList.append( val.toString().split( ';' ) );
1493  }
1494 
1495  if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
1496  {
1497  resultStringList.clear();
1498  // check default
1499  if ( definition->defaultValue().isValid() )
1500  {
1501  if ( definition->defaultValue().type() == QVariant::List )
1502  {
1503  const auto constToList = definition->defaultValue().toList();
1504  for ( const QVariant &var : constToList )
1505  resultStringList << var.toString();
1506  }
1507  else
1508  resultStringList.append( definition->defaultValue().toString().split( ';' ) );
1509  }
1510  }
1511 
1512  return resultStringList;
1513 }
1514 
1516 {
1517  if ( !definition )
1518  return nullptr;
1519 
1520  return parameterAsLayout( definition, parameters.value( definition->name() ), context );
1521 }
1522 
1524 {
1525  const QString layoutName = parameterAsString( definition, value, context );
1526  if ( layoutName.isEmpty() )
1527  return nullptr;
1528 
1529  if ( !context.project() )
1530  return nullptr;
1531 
1532  QgsMasterLayoutInterface *l = context.project()->layoutManager()->layoutByName( layoutName );
1534  return static_cast< QgsPrintLayout * >( l );
1535  else
1536  return nullptr;
1537 }
1538 
1540 {
1541  if ( !definition )
1542  return nullptr;
1543 
1544  return parameterAsLayoutItem( definition, parameters.value( definition->name() ), context, layout );
1545 }
1546 
1548 {
1549  if ( !layout )
1550  return nullptr;
1551 
1552  const QString id = parameterAsString( definition, value, context );
1553  if ( id.isEmpty() )
1554  return nullptr;
1555 
1556  // prefer matching by uuid, since it's guaranteed to be unique.
1557  if ( QgsLayoutItem *item = layout->itemByUuid( id ) )
1558  return item;
1559  else if ( QgsLayoutItem *item = layout->itemById( id ) )
1560  return item;
1561  else
1562  return nullptr;
1563 }
1564 
1566 {
1567  QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
1568  QString name = map.value( QStringLiteral( "name" ) ).toString();
1569  std::unique_ptr< QgsProcessingParameterDefinition > def;
1571  def.reset( new QgsProcessingParameterBoolean( name ) );
1572  else if ( type == QgsProcessingParameterCrs::typeName() )
1573  def.reset( new QgsProcessingParameterCrs( name ) );
1574  else if ( type == QgsProcessingParameterMapLayer::typeName() )
1575  def.reset( new QgsProcessingParameterMapLayer( name ) );
1576  else if ( type == QgsProcessingParameterExtent::typeName() )
1577  def.reset( new QgsProcessingParameterExtent( name ) );
1578  else if ( type == QgsProcessingParameterPoint::typeName() )
1579  def.reset( new QgsProcessingParameterPoint( name ) );
1580  else if ( type == QgsProcessingParameterFile::typeName() )
1581  def.reset( new QgsProcessingParameterFile( name ) );
1582  else if ( type == QgsProcessingParameterMatrix::typeName() )
1583  def.reset( new QgsProcessingParameterMatrix( name ) );
1585  def.reset( new QgsProcessingParameterMultipleLayers( name ) );
1586  else if ( type == QgsProcessingParameterNumber::typeName() )
1587  def.reset( new QgsProcessingParameterNumber( name ) );
1588  else if ( type == QgsProcessingParameterRange::typeName() )
1589  def.reset( new QgsProcessingParameterRange( name ) );
1590  else if ( type == QgsProcessingParameterRasterLayer::typeName() )
1591  def.reset( new QgsProcessingParameterRasterLayer( name ) );
1592  else if ( type == QgsProcessingParameterEnum::typeName() )
1593  def.reset( new QgsProcessingParameterEnum( name ) );
1594  else if ( type == QgsProcessingParameterString::typeName() )
1595  def.reset( new QgsProcessingParameterString( name ) );
1596  else if ( type == QgsProcessingParameterAuthConfig::typeName() )
1597  def.reset( new QgsProcessingParameterAuthConfig( name ) );
1598  else if ( type == QgsProcessingParameterExpression::typeName() )
1599  def.reset( new QgsProcessingParameterExpression( name ) );
1600  else if ( type == QgsProcessingParameterVectorLayer::typeName() )
1601  def.reset( new QgsProcessingParameterVectorLayer( name ) );
1602  else if ( type == QgsProcessingParameterField::typeName() )
1603  def.reset( new QgsProcessingParameterField( name ) );
1604  else if ( type == QgsProcessingParameterFeatureSource::typeName() )
1605  def.reset( new QgsProcessingParameterFeatureSource( name ) );
1606  else if ( type == QgsProcessingParameterFeatureSink::typeName() )
1607  def.reset( new QgsProcessingParameterFeatureSink( name ) );
1609  def.reset( new QgsProcessingParameterVectorDestination( name ) );
1611  def.reset( new QgsProcessingParameterRasterDestination( name ) );
1613  def.reset( new QgsProcessingParameterFileDestination( name ) );
1615  def.reset( new QgsProcessingParameterFolderDestination( name ) );
1616  else if ( type == QgsProcessingParameterBand::typeName() )
1617  def.reset( new QgsProcessingParameterBand( name ) );
1618  else if ( type == QgsProcessingParameterMeshLayer::typeName() )
1619  def.reset( new QgsProcessingParameterMeshLayer( name ) );
1620  else if ( type == QgsProcessingParameterLayout::typeName() )
1621  def.reset( new QgsProcessingParameterLayout( name ) );
1622  else if ( type == QgsProcessingParameterLayoutItem::typeName() )
1623  def.reset( new QgsProcessingParameterLayoutItem( name ) );
1624  else
1625  {
1627  if ( paramType )
1628  def.reset( paramType->create( name ) );
1629  }
1630 
1631  if ( !def )
1632  return nullptr;
1633 
1634  def->fromVariantMap( map );
1635  return def.release();
1636 }
1637 
1638 QString QgsProcessingParameters::descriptionFromName( const QString &name )
1639 {
1640  QString desc = name;
1641  desc.replace( '_', ' ' );
1642  return desc;
1643 }
1644 
1646 {
1647  bool isOptional = false;
1648  QString name;
1649  QString definition;
1650  QString type;
1651  if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
1652  return nullptr;
1653 
1654  QString description = descriptionFromName( name );
1655 
1656  if ( type == QStringLiteral( "boolean" ) )
1657  return QgsProcessingParameterBoolean::fromScriptCode( name, description, isOptional, definition );
1658  else if ( type == QStringLiteral( "crs" ) )
1659  return QgsProcessingParameterCrs::fromScriptCode( name, description, isOptional, definition );
1660  else if ( type == QStringLiteral( "layer" ) )
1661  return QgsProcessingParameterMapLayer::fromScriptCode( name, description, isOptional, definition );
1662  else if ( type == QStringLiteral( "extent" ) )
1663  return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
1664  else if ( type == QStringLiteral( "point" ) )
1665  return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
1666  else if ( type == QStringLiteral( "file" ) )
1667  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
1668  else if ( type == QStringLiteral( "folder" ) )
1669  return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::Folder );
1670  else if ( type == QStringLiteral( "matrix" ) )
1671  return QgsProcessingParameterMatrix::fromScriptCode( name, description, isOptional, definition );
1672  else if ( type == QStringLiteral( "multiple" ) )
1673  return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
1674  else if ( type == QStringLiteral( "number" ) )
1675  return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
1676  else if ( type == QStringLiteral( "distance" ) )
1677  return QgsProcessingParameterDistance::fromScriptCode( name, description, isOptional, definition );
1678  else if ( type == QStringLiteral( "scale" ) )
1679  return QgsProcessingParameterScale::fromScriptCode( name, description, isOptional, definition );
1680  else if ( type == QStringLiteral( "range" ) )
1681  return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
1682  else if ( type == QStringLiteral( "raster" ) )
1683  return QgsProcessingParameterRasterLayer::fromScriptCode( name, description, isOptional, definition );
1684  else if ( type == QStringLiteral( "enum" ) )
1685  return QgsProcessingParameterEnum::fromScriptCode( name, description, isOptional, definition );
1686  else if ( type == QStringLiteral( "string" ) )
1687  return QgsProcessingParameterString::fromScriptCode( name, description, isOptional, definition );
1688  else if ( type == QStringLiteral( "authcfg" ) )
1689  return QgsProcessingParameterAuthConfig::fromScriptCode( name, description, isOptional, definition );
1690  else if ( type == QStringLiteral( "expression" ) )
1691  return QgsProcessingParameterExpression::fromScriptCode( name, description, isOptional, definition );
1692  else if ( type == QStringLiteral( "field" ) )
1693  return QgsProcessingParameterField::fromScriptCode( name, description, isOptional, definition );
1694  else if ( type == QStringLiteral( "vector" ) )
1695  return QgsProcessingParameterVectorLayer::fromScriptCode( name, description, isOptional, definition );
1696  else if ( type == QStringLiteral( "source" ) )
1697  return QgsProcessingParameterFeatureSource::fromScriptCode( name, description, isOptional, definition );
1698  else if ( type == QStringLiteral( "sink" ) )
1699  return QgsProcessingParameterFeatureSink::fromScriptCode( name, description, isOptional, definition );
1700  else if ( type == QStringLiteral( "vectordestination" ) )
1701  return QgsProcessingParameterVectorDestination::fromScriptCode( name, description, isOptional, definition );
1702  else if ( type == QStringLiteral( "rasterdestination" ) )
1703  return QgsProcessingParameterRasterDestination::fromScriptCode( name, description, isOptional, definition );
1704  else if ( type == QStringLiteral( "filedestination" ) )
1705  return QgsProcessingParameterFileDestination::fromScriptCode( name, description, isOptional, definition );
1706  else if ( type == QStringLiteral( "folderdestination" ) )
1707  return QgsProcessingParameterFolderDestination::fromScriptCode( name, description, isOptional, definition );
1708  else if ( type == QStringLiteral( "band" ) )
1709  return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
1710  else if ( type == QStringLiteral( "mesh" ) )
1711  return QgsProcessingParameterMeshLayer::fromScriptCode( name, description, isOptional, definition );
1712  else if ( type == QStringLiteral( "layout" ) )
1713  return QgsProcessingParameterLayout::fromScriptCode( name, description, isOptional, definition );
1714  else if ( type == QStringLiteral( "layoutitem" ) )
1715  return QgsProcessingParameterLayoutItem::fromScriptCode( name, description, isOptional, definition );
1716 
1717  return nullptr;
1718 }
1719 
1720 bool QgsProcessingParameters::parseScriptCodeParameterOptions( const QString &code, bool &isOptional, QString &name, QString &type, QString &definition )
1721 {
1722  QRegularExpression re( QStringLiteral( "(?:#*)(.*?)=\\s*(.*)" ) );
1723  QRegularExpressionMatch m = re.match( code );
1724  if ( !m.hasMatch() )
1725  return false;
1726 
1727  name = m.captured( 1 );
1728  QString tokens = m.captured( 2 );
1729  if ( tokens.startsWith( QLatin1String( "optional" ), Qt::CaseInsensitive ) )
1730  {
1731  isOptional = true;
1732  tokens.remove( 0, 8 ); // length "optional" = 8
1733  }
1734  else
1735  {
1736  isOptional = false;
1737  }
1738 
1739  tokens = tokens.trimmed();
1740 
1741  QRegularExpression re2( QStringLiteral( "(.*?)\\s+(.*)" ) );
1742  m = re2.match( tokens );
1743  if ( !m.hasMatch() )
1744  {
1745  type = tokens.toLower().trimmed();
1746  definition.clear();
1747  }
1748  else
1749  {
1750  type = m.captured( 1 ).toLower().trimmed();
1751  definition = m.captured( 2 );
1752  }
1753  return true;
1754 }
1755 
1756 //
1757 // QgsProcessingParameterDefinition
1758 //
1759 
1760 QgsProcessingParameterDefinition::QgsProcessingParameterDefinition( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
1761  : mName( name )
1762  , mDescription( description )
1763  , mDefault( defaultValue )
1764  , mFlags( optional ? FlagOptional : 0 )
1765 {}
1766 
1768 {
1769  if ( !input.isValid() && !mDefault.isValid() )
1770  return mFlags & FlagOptional;
1771 
1772  if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
1773  || ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
1774  return mFlags & FlagOptional;
1775 
1776  return true;
1777 }
1778 
1780 {
1781  if ( !value.isValid() )
1782  return QStringLiteral( "None" );
1783 
1784  if ( value.canConvert<QgsProperty>() )
1785  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
1786 
1787  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
1788 }
1789 
1791 {
1792  QString code = QStringLiteral( "##%1=" ).arg( mName );
1793  if ( mFlags & FlagOptional )
1794  code += QStringLiteral( "optional " );
1795  code += type() + ' ';
1796  code += mDefault.toString();
1797  return code.trimmed();
1798 }
1799 
1801 {
1802  // base class method is probably not much use
1803  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
1804  {
1805  switch ( outputType )
1806  {
1808  {
1809  QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
1810  if ( mFlags & FlagOptional )
1811  code += QStringLiteral( ", optional=True" );
1812 
1814  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
1815  return code;
1816  }
1817  }
1818  }
1819 
1820  // oh well, we tried
1821  return QString();
1822 }
1823 
1825 {
1826  QVariantMap map;
1827  map.insert( QStringLiteral( "parameter_type" ), type() );
1828  map.insert( QStringLiteral( "name" ), mName );
1829  map.insert( QStringLiteral( "description" ), mDescription );
1830  map.insert( QStringLiteral( "default" ), mDefault );
1831  map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
1832  map.insert( QStringLiteral( "metadata" ), mMetadata );
1833  return map;
1834 }
1835 
1837 {
1838  mName = map.value( QStringLiteral( "name" ) ).toString();
1839  mDescription = map.value( QStringLiteral( "description" ) ).toString();
1840  mDefault = map.value( QStringLiteral( "default" ) );
1841  mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
1842  mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
1843  return true;
1844 }
1845 
1847 {
1848  return mAlgorithm;
1849 }
1850 
1852 {
1853  return mAlgorithm ? mAlgorithm->provider() : nullptr;
1854 }
1855 
1857 {
1858  return QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
1859  description(),
1860  QObject::tr( "Python identifier: ‘%1’" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
1861 }
1862 
1863 QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
1864  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
1865 {}
1866 
1868 {
1869  return new QgsProcessingParameterBoolean( *this );
1870 }
1871 
1873 {
1874  if ( !val.isValid() )
1875  return QStringLiteral( "None" );
1876 
1877  if ( val.canConvert<QgsProperty>() )
1878  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
1879  return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
1880 }
1881 
1883 {
1884  QString code = QStringLiteral( "##%1=" ).arg( mName );
1885  if ( mFlags & FlagOptional )
1886  code += QStringLiteral( "optional " );
1887  code += type() + ' ';
1888  code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
1889  return code.trimmed();
1890 }
1891 
1892 QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
1893 {
1894  return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
1895 }
1896 
1897 QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
1898  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
1899 {
1900 
1901 }
1902 
1904 {
1905  return new QgsProcessingParameterCrs( *this );
1906 }
1907 
1909 {
1910  if ( !input.isValid() )
1911  return mFlags & FlagOptional;
1912 
1913  if ( input.canConvert<QgsCoordinateReferenceSystem>() )
1914  {
1915  return true;
1916  }
1917  else if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
1918  {
1919  return true;
1920  }
1921  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
1922  {
1923  return true;
1924  }
1925 
1926  if ( input.canConvert<QgsProperty>() )
1927  {
1928  return true;
1929  }
1930 
1931  // direct map layer value
1932  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
1933  return true;
1934 
1935  if ( input.type() != QVariant::String || input.toString().isEmpty() )
1936  return mFlags & FlagOptional;
1937 
1938  return true;
1939 }
1940 
1941 QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
1942 {
1943  if ( !value.isValid() )
1944  return QStringLiteral( "None" );
1945 
1946  if ( value.canConvert<QgsCoordinateReferenceSystem>() )
1947  {
1948  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
1949  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
1950  else
1951  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
1952  }
1953 
1954  if ( value.canConvert<QgsProperty>() )
1955  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
1956 
1957  QVariantMap p;
1958  p.insert( name(), value );
1959  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
1960  if ( layer )
1962 
1964 }
1965 
1966 QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
1967 {
1968  return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
1969 }
1970 
1971 QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
1972  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
1973 {
1974 
1975 }
1976 
1978 {
1979  return new QgsProcessingParameterMapLayer( *this );
1980 }
1981 
1983 {
1984  if ( !input.isValid() )
1985  return mFlags & FlagOptional;
1986 
1987  if ( input.canConvert<QgsProperty>() )
1988  {
1989  return true;
1990  }
1991 
1992  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
1993  {
1994  return true;
1995  }
1996 
1997  if ( input.type() != QVariant::String || input.toString().isEmpty() )
1998  return mFlags & FlagOptional;
1999 
2000  if ( !context )
2001  {
2002  // that's as far as we can get without a context
2003  return true;
2004  }
2005 
2006  // try to load as layer
2007  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
2008  return true;
2009 
2010  return false;
2011 }
2012 
2014 {
2015  if ( !val.isValid() )
2016  return QStringLiteral( "None" );
2017 
2018  if ( val.canConvert<QgsProperty>() )
2019  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
2020 
2021  QVariantMap p;
2022  p.insert( name(), val );
2023  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2025  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
2026 }
2027 
2028 QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2029 {
2030  return new QgsProcessingParameterMapLayer( name, description, definition, isOptional );
2031 }
2032 
2033 QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2034  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2035 {
2036 
2037 }
2038 
2040 {
2041  return new QgsProcessingParameterExtent( *this );
2042 }
2043 
2045 {
2046  if ( !input.isValid() )
2047  return mFlags & FlagOptional;
2048 
2049  if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
2050  {
2051  return true;
2052  }
2053  else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
2054  {
2055  return true;
2056  }
2057 
2058  if ( input.canConvert<QgsProperty>() )
2059  {
2060  return true;
2061  }
2062 
2063  if ( input.canConvert< QgsRectangle >() )
2064  {
2065  QgsRectangle r = input.value<QgsRectangle>();
2066  return !r.isNull();
2067  }
2068  if ( input.canConvert< QgsReferencedRectangle >() )
2069  {
2071  return !r.isNull();
2072  }
2073 
2074  // direct map layer value
2075  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2076  return true;
2077 
2078  if ( input.type() != QVariant::String || input.toString().isEmpty() )
2079  return mFlags & FlagOptional;
2080 
2081  if ( !context )
2082  {
2083  // that's as far as we can get without a context
2084  return true;
2085  }
2086 
2087  QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
2088  QRegularExpressionMatch match = rx.match( input.toString() );
2089  if ( match.hasMatch() )
2090  {
2091  bool xMinOk = false;
2092  ( void )match.captured( 1 ).toDouble( &xMinOk );
2093  bool xMaxOk = false;
2094  ( void )match.captured( 2 ).toDouble( &xMaxOk );
2095  bool yMinOk = false;
2096  ( void )match.captured( 3 ).toDouble( &yMinOk );
2097  bool yMaxOk = false;
2098  ( void )match.captured( 4 ).toDouble( &yMaxOk );
2099  if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
2100  return true;
2101  }
2102 
2103  // try as layer extent
2104  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
2105 }
2106 
2107 QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2108 {
2109  if ( !value.isValid() )
2110  return QStringLiteral( "None" );
2111 
2112  if ( value.canConvert<QgsProperty>() )
2113  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2114 
2115  if ( value.canConvert< QgsRectangle >() )
2116  {
2117  QgsRectangle r = value.value<QgsRectangle>();
2118  return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
2119  qgsDoubleToString( r.yMinimum() ),
2120  qgsDoubleToString( r.xMaximum() ),
2121  qgsDoubleToString( r.yMaximum() ) );
2122  }
2123  if ( value.canConvert< QgsReferencedRectangle >() )
2124  {
2126  return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
2127  qgsDoubleToString( r.yMinimum() ),
2128  qgsDoubleToString( r.xMaximum() ),
2129  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
2130  }
2131 
2132  QVariantMap p;
2133  p.insert( name(), value );
2134  QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
2135  if ( layer )
2137 
2139 }
2140 
2141 QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2142 {
2143  return new QgsProcessingParameterExtent( name, description, definition, isOptional );
2144 }
2145 
2146 QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2147  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2148 {
2149 
2150 }
2151 
2153 {
2154  return new QgsProcessingParameterPoint( *this );
2155 }
2156 
2158 {
2159  if ( !input.isValid() )
2160  return mFlags & FlagOptional;
2161 
2162  if ( input.canConvert<QgsProperty>() )
2163  {
2164  return true;
2165  }
2166 
2167  if ( input.canConvert< QgsPointXY >() )
2168  {
2169  return true;
2170  }
2171  if ( input.canConvert< QgsReferencedPointXY >() )
2172  {
2173  return true;
2174  }
2175  if ( input.canConvert< QgsGeometry >() )
2176  {
2177  return true;
2178  }
2179 
2180  if ( input.type() == QVariant::String )
2181  {
2182  if ( input.toString().isEmpty() )
2183  return mFlags & FlagOptional;
2184  }
2185 
2186  QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
2187 
2188  QRegularExpressionMatch match = rx.match( input.toString() );
2189  if ( match.hasMatch() )
2190  {
2191  bool xOk = false;
2192  ( void )match.captured( 1 ).toDouble( &xOk );
2193  bool yOk = false;
2194  ( void )match.captured( 2 ).toDouble( &yOk );
2195  return xOk && yOk;
2196  }
2197  else
2198  return false;
2199 }
2200 
2201 QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2202 {
2203  if ( !value.isValid() )
2204  return QStringLiteral( "None" );
2205 
2206  if ( value.canConvert<QgsProperty>() )
2207  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2208 
2209  if ( value.canConvert< QgsPointXY >() )
2210  {
2211  QgsPointXY r = value.value<QgsPointXY>();
2212  return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
2213  qgsDoubleToString( r.y() ) );
2214  }
2215  else if ( value.canConvert< QgsReferencedPointXY >() )
2216  {
2217  QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
2218  return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
2219  qgsDoubleToString( r.y() ),
2220  r.crs().authid() );
2221  }
2222  else if ( value.canConvert< QgsGeometry >() )
2223  {
2224  const QgsGeometry g = value.value<QgsGeometry>();
2225  if ( !g.isNull() )
2226  {
2227  const QString wkt = g.asWkt();
2228  return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
2229  }
2230  }
2231 
2233 }
2234 
2235 QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2236 {
2237  return new QgsProcessingParameterPoint( name, description, definition, isOptional );
2238 }
2239 
2240 QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional )
2241  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2242  , mBehavior( behavior )
2243  , mExtension( extension )
2244 {
2245 
2246 }
2247 
2249 {
2250  return new QgsProcessingParameterFile( *this );
2251 }
2252 
2254 {
2255  if ( !input.isValid() )
2256  return mFlags & FlagOptional;
2257 
2258  if ( input.canConvert<QgsProperty>() )
2259  {
2260  return true;
2261  }
2262 
2263  QString string = input.toString().trimmed();
2264 
2265  if ( input.type() != QVariant::String || string.isEmpty() )
2266  return mFlags & FlagOptional;
2267 
2268  switch ( mBehavior )
2269  {
2270  case File:
2271  {
2272  if ( !mExtension.isEmpty() )
2273  return string.endsWith( mExtension, Qt::CaseInsensitive );
2274  return true;
2275  }
2276 
2277  case Folder:
2278  return true;
2279  }
2280  return true;
2281 }
2282 
2284 {
2285  QString code = QStringLiteral( "##%1=" ).arg( mName );
2286  if ( mFlags & FlagOptional )
2287  code += QStringLiteral( "optional " );
2288  code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
2289  code += mDefault.toString();
2290  return code.trimmed();
2291 }
2292 
2294 {
2295  switch ( outputType )
2296  {
2298  {
2299 
2300  QString code = QStringLiteral( "QgsProcessingParameterFile('%1', '%2'" ).arg( name(), description() );
2301  if ( mFlags & FlagOptional )
2302  code += QStringLiteral( ", optional=True" );
2303  code += QStringLiteral( ", behavior=%1" ).arg( mBehavior == File ? QStringLiteral( "QgsProcessingParameterFile.File" ) : QStringLiteral( "QgsProcessingParameterFile.Folder" ) );
2304  code += QStringLiteral( ", extension='%1'" ).arg( mExtension );
2306  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2307  return code;
2308  }
2309  }
2310  return QString();
2311 }
2312 
2314 {
2316  map.insert( QStringLiteral( "behavior" ), mBehavior );
2317  map.insert( QStringLiteral( "extension" ), mExtension );
2318  return map;
2319 }
2320 
2321 bool QgsProcessingParameterFile::fromVariantMap( const QVariantMap &map )
2322 {
2324  mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
2325  mExtension = map.value( QStringLiteral( "extension" ) ).toString();
2326  return true;
2327 }
2328 
2330 {
2331  return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
2332 }
2333 
2334 QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
2335  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2336  , mHeaders( headers )
2337  , mNumberRows( numberRows )
2338  , mFixedNumberRows( fixedNumberRows )
2339 {
2340 
2341 }
2342 
2344 {
2345  return new QgsProcessingParameterMatrix( *this );
2346 }
2347 
2349 {
2350  if ( !input.isValid() )
2351  return mFlags & FlagOptional;
2352 
2353  if ( input.type() == QVariant::String )
2354  {
2355  if ( input.toString().isEmpty() )
2356  return mFlags & FlagOptional;
2357  return true;
2358  }
2359  else if ( input.type() == QVariant::List )
2360  {
2361  if ( input.toList().isEmpty() )
2362  return mFlags & FlagOptional;
2363  return true;
2364  }
2365  else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
2366  {
2367  return true;
2368  }
2369 
2370  return false;
2371 }
2372 
2373 QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2374 {
2375  if ( !value.isValid() )
2376  return QStringLiteral( "None" );
2377 
2378  if ( value.canConvert<QgsProperty>() )
2379  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2380 
2381  QVariantMap p;
2382  p.insert( name(), value );
2383  QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
2384 
2385  QStringList parts;
2386  const auto constList = list;
2387  for ( const QVariant &v : constList )
2388  {
2389  if ( v.type() == QVariant::List )
2390  {
2391  QStringList parts2;
2392  const auto constToList = v.toList();
2393  for ( const QVariant &v2 : constToList )
2394  {
2395  if ( v2.isNull() || !v2.isValid() )
2396  parts2 << QStringLiteral( "None" );
2397  else if ( v2.toString().isEmpty() )
2398  parts2 << QStringLiteral( "''" );
2399  else
2400  parts2 << v2.toString();
2401  }
2402  parts << parts2.join( ',' ).prepend( '[' ).append( ']' );
2403  }
2404  else
2405  {
2406  if ( v.isNull() || !v.isValid() )
2407  parts << QStringLiteral( "None" );
2408  else if ( v.toString().isEmpty() )
2409  parts << QStringLiteral( "''" );
2410  else
2411  parts << v.toString();
2412  }
2413  }
2414 
2415  return parts.join( ',' ).prepend( '[' ).append( ']' );
2416 }
2417 
2419 {
2420  switch ( outputType )
2421  {
2423  {
2424  QString code = QStringLiteral( "QgsProcessingParameterMatrix('%1', '%2'" ).arg( name(), description() );
2425  if ( mFlags & FlagOptional )
2426  code += QStringLiteral( ", optional=True" );
2427  code += QStringLiteral( ", numberRows=" ).arg( mNumberRows );
2428  code += QStringLiteral( ", hasFixedNumberRows=" ).arg( mFixedNumberRows ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
2429 
2430  QStringList headers;
2431  headers.reserve( mHeaders.size() );
2432  for ( const QString &h : mHeaders )
2434  code += QStringLiteral( ", headers=[%1]" ).arg( headers.join( ',' ) );
2435 
2437  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2438  return code;
2439  }
2440  }
2441  return QString();
2442 }
2443 
2445 {
2446  return mHeaders;
2447 }
2448 
2450 {
2451  mHeaders = headers;
2452 }
2453 
2455 {
2456  return mNumberRows;
2457 }
2458 
2460 {
2461  mNumberRows = numberRows;
2462 }
2463 
2465 {
2466  return mFixedNumberRows;
2467 }
2468 
2470 {
2471  mFixedNumberRows = fixedNumberRows;
2472 }
2473 
2475 {
2477  map.insert( QStringLiteral( "headers" ), mHeaders );
2478  map.insert( QStringLiteral( "rows" ), mNumberRows );
2479  map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
2480  return map;
2481 }
2482 
2483 bool QgsProcessingParameterMatrix::fromVariantMap( const QVariantMap &map )
2484 {
2486  mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
2487  mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
2488  mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
2489  return true;
2490 }
2491 
2492 QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2493 {
2494  return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
2495 }
2496 
2498  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2499  , mLayerType( layerType )
2500 {
2501 
2502 }
2503 
2505 {
2506  return new QgsProcessingParameterMultipleLayers( *this );
2507 }
2508 
2510 {
2511  if ( !input.isValid() )
2512  return mFlags & FlagOptional;
2513 
2514  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
2515  {
2516  return true;
2517  }
2518 
2519  if ( input.type() == QVariant::String )
2520  {
2521  if ( input.toString().isEmpty() )
2522  return mFlags & FlagOptional;
2523 
2524  if ( mMinimumNumberInputs > 1 )
2525  return false;
2526 
2527  if ( !context )
2528  return true;
2529 
2530  return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
2531  }
2532  else if ( input.type() == QVariant::List )
2533  {
2534  if ( input.toList().count() < mMinimumNumberInputs )
2535  return mFlags & FlagOptional;
2536 
2537  if ( mMinimumNumberInputs > input.toList().count() )
2538  return false;
2539 
2540  if ( !context )
2541  return true;
2542 
2543  const auto constToList = input.toList();
2544  for ( const QVariant &v : constToList )
2545  {
2546  if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
2547  continue;
2548 
2549  if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
2550  return false;
2551  }
2552  return true;
2553  }
2554  else if ( input.type() == QVariant::StringList )
2555  {
2556  if ( input.toStringList().count() < mMinimumNumberInputs )
2557  return mFlags & FlagOptional;
2558 
2559  if ( mMinimumNumberInputs > input.toStringList().count() )
2560  return false;
2561 
2562  if ( !context )
2563  return true;
2564 
2565  const auto constToStringList = input.toStringList();
2566  for ( const QString &v : constToStringList )
2567  {
2568  if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
2569  return false;
2570  }
2571  return true;
2572  }
2573  return false;
2574 }
2575 
2577 {
2578  if ( !value.isValid() )
2579  return QStringLiteral( "None" );
2580 
2581  if ( value.canConvert<QgsProperty>() )
2582  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2583 
2584  QVariantMap p;
2585  p.insert( name(), value );
2586  QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
2587  if ( !list.isEmpty() )
2588  {
2589  QStringList parts;
2590  const auto constList = list;
2591  for ( const QgsMapLayer *layer : constList )
2592  {
2594  }
2595  return parts.join( ',' ).prepend( '[' ).append( ']' );
2596  }
2597 
2599 }
2600 
2602 {
2603  QString code = QStringLiteral( "##%1=" ).arg( mName );
2604  if ( mFlags & FlagOptional )
2605  code += QStringLiteral( "optional " );
2606  switch ( mLayerType )
2607  {
2609  code += QStringLiteral( "multiple raster" );
2610  break;
2611 
2613  code += QStringLiteral( "multiple file" );
2614  break;
2615 
2616  default:
2617  code += QStringLiteral( "multiple vector" );
2618  break;
2619  }
2620  code += ' ';
2621  if ( mDefault.type() == QVariant::List )
2622  {
2623  QStringList parts;
2624  const auto constToList = mDefault.toList();
2625  for ( const QVariant &var : constToList )
2626  {
2627  parts << var.toString();
2628  }
2629  code += parts.join( ',' );
2630  }
2631  else if ( mDefault.type() == QVariant::StringList )
2632  {
2633  code += mDefault.toStringList().join( ',' );
2634  }
2635  else
2636  {
2637  code += mDefault.toString();
2638  }
2639  return code.trimmed();
2640 }
2641 
2643 {
2644  switch ( outputType )
2645  {
2647  {
2648  QString code = QStringLiteral( "QgsProcessingParameterMultipleLayers('%1', '%2'" ).arg( name(), description() );
2649  if ( mFlags & FlagOptional )
2650  code += QStringLiteral( ", optional=True" );
2651 
2652  QString layerType = QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mLayerType ) );
2653 
2654  code += QStringLiteral( ", layerType=%1" ).arg( layerType );
2656  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2657  return code;
2658  }
2659  }
2660  return QString();
2661 }
2662 
2664 {
2665  return mLayerType;
2666 }
2667 
2669 {
2670  mLayerType = type;
2671 }
2672 
2674 {
2675  return mMinimumNumberInputs;
2676 }
2677 
2679 {
2680  if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
2681  mMinimumNumberInputs = minimumNumberInputs;
2682 }
2683 
2685 {
2687  map.insert( QStringLiteral( "layer_type" ), mLayerType );
2688  map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
2689  return map;
2690 }
2691 
2693 {
2695  mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
2696  mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
2697  return true;
2698 }
2699 
2700 QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2701 {
2702  QString type = definition;
2703  QString defaultVal;
2704  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
2705  QRegularExpressionMatch m = re.match( definition );
2706  if ( m.hasMatch() )
2707  {
2708  type = m.captured( 1 ).toLower().trimmed();
2709  defaultVal = m.captured( 2 );
2710  }
2712  if ( type == QStringLiteral( "vector" ) )
2714  else if ( type == QStringLiteral( "raster" ) )
2715  layerType = QgsProcessing::TypeRaster;
2716  else if ( type == QStringLiteral( "file" ) )
2717  layerType = QgsProcessing::TypeFile;
2718  return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
2719 }
2720 
2721 QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
2722  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2723  , mMin( minValue )
2724  , mMax( maxValue )
2725  , mDataType( type )
2726 {
2727  if ( mMin >= mMax )
2728  {
2729  QgsMessageLog::logMessage( QObject::tr( "Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg( name ).arg( mMin ).arg( mMax ), QObject::tr( "Processing" ) );
2730  }
2731 }
2732 
2734 {
2735  return new QgsProcessingParameterNumber( *this );
2736 }
2737 
2739 {
2740  QVariant input = value;
2741  if ( !input.isValid() )
2742  {
2743  if ( !defaultValue().isValid() )
2744  return mFlags & FlagOptional;
2745 
2746  input = defaultValue();
2747  }
2748 
2749  if ( input.canConvert<QgsProperty>() )
2750  {
2751  return true;
2752  }
2753 
2754  bool ok = false;
2755  double res = input.toDouble( &ok );
2756  if ( !ok )
2757  return mFlags & FlagOptional;
2758 
2759  return !( res < mMin || res > mMax );
2760 }
2761 
2763 {
2764  if ( !value.isValid() )
2765  return QStringLiteral( "None" );
2766 
2767  if ( value.canConvert<QgsProperty>() )
2768  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2769 
2770  return value.toString();
2771 }
2772 
2774 {
2776  QStringList parts;
2777  if ( mMin > std::numeric_limits<double>::lowest() + 1 )
2778  parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
2779  if ( mMax < std::numeric_limits<double>::max() )
2780  parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
2781  if ( mDefault.isValid() )
2782  parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
2783  QString extra = parts.join( QStringLiteral( "<br />" ) );
2784  if ( !extra.isEmpty() )
2785  text += QStringLiteral( "<p>%1</p>" ).arg( extra );
2786  return text;
2787 }
2788 
2790 {
2791  switch ( outputType )
2792  {
2794  {
2795  QString code = QStringLiteral( "QgsProcessingParameterNumber('%1', '%2'" ).arg( name(), description() );
2796  if ( mFlags & FlagOptional )
2797  code += QStringLiteral( ", optional=True" );
2798 
2799  code += QStringLiteral( ", type=%1" ).arg( mDataType == Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
2800 
2801  if ( mMin != std::numeric_limits<double>::lowest() + 1 )
2802  code += QStringLiteral( ", minValue=%1" ).arg( mMin );
2803  if ( mMax != std::numeric_limits<double>::max() )
2804  code += QStringLiteral( ", maxValue=%1" ).arg( mMax );
2806  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2807  return code;
2808  }
2809  }
2810  return QString();
2811 }
2812 
2814 {
2815  return mMin;
2816 }
2817 
2819 {
2820  mMin = min;
2821 }
2822 
2824 {
2825  return mMax;
2826 }
2827 
2829 {
2830  mMax = max;
2831 }
2832 
2834 {
2835  return mDataType;
2836 }
2837 
2839 {
2840  mDataType = dataType;
2841 }
2842 
2844 {
2846  map.insert( QStringLiteral( "min" ), mMin );
2847  map.insert( QStringLiteral( "max" ), mMax );
2848  map.insert( QStringLiteral( "data_type" ), mDataType );
2849  return map;
2850 }
2851 
2852 bool QgsProcessingParameterNumber::fromVariantMap( const QVariantMap &map )
2853 {
2855  mMin = map.value( QStringLiteral( "min" ) ).toDouble();
2856  mMax = map.value( QStringLiteral( "max" ) ).toDouble();
2857  mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
2858  return true;
2859 }
2860 
2861 QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2862 {
2863  return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
2864  : ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
2865 }
2866 
2868  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2869  , mDataType( type )
2870 {
2871 
2872 }
2873 
2875 {
2876  return new QgsProcessingParameterRange( *this );
2877 }
2878 
2880 {
2881  if ( !input.isValid() )
2882  return mFlags & FlagOptional;
2883 
2884  if ( input.canConvert<QgsProperty>() )
2885  {
2886  return true;
2887  }
2888 
2889  if ( input.type() == QVariant::String )
2890  {
2891  QStringList list = input.toString().split( ',' );
2892  if ( list.count() != 2 )
2893  return mFlags & FlagOptional;
2894  bool ok = false;
2895  list.at( 0 ).toDouble( &ok );
2896  bool ok2 = false;
2897  list.at( 1 ).toDouble( &ok2 );
2898  if ( !ok || !ok2 )
2899  return mFlags & FlagOptional;
2900  return true;
2901  }
2902  else if ( input.type() == QVariant::List )
2903  {
2904  if ( input.toList().count() != 2 )
2905  return mFlags & FlagOptional;
2906 
2907  bool ok = false;
2908  input.toList().at( 0 ).toDouble( &ok );
2909  bool ok2 = false;
2910  input.toList().at( 1 ).toDouble( &ok2 );
2911  if ( !ok || !ok2 )
2912  return mFlags & FlagOptional;
2913  return true;
2914  }
2915 
2916  return false;
2917 }
2918 
2919 QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
2920 {
2921  if ( !value.isValid() )
2922  return QStringLiteral( "None" );
2923 
2924  if ( value.canConvert<QgsProperty>() )
2925  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
2926 
2927  QVariantMap p;
2928  p.insert( name(), value );
2929  QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
2930 
2931  QStringList stringParts;
2932  const auto constParts = parts;
2933  for ( double v : constParts )
2934  {
2935  stringParts << QString::number( v );
2936  }
2937  return stringParts.join( ',' ).prepend( '[' ).append( ']' );
2938 }
2939 
2941 {
2942  switch ( outputType )
2943  {
2945  {
2946  QString code = QStringLiteral( "QgsProcessingParameterRange('%1', '%2'" ).arg( name(), description() );
2947  if ( mFlags & FlagOptional )
2948  code += QStringLiteral( ", optional=True" );
2949 
2950  code += QStringLiteral( ", type=%1" ).arg( mDataType == QgsProcessingParameterNumber::Integer ? QStringLiteral( "QgsProcessingParameterNumber.Integer" ) : QStringLiteral( "QgsProcessingParameterNumber.Double" ) );
2951 
2953  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
2954  return code;
2955  }
2956  }
2957  return QString();
2958 }
2959 
2961 {
2962  return mDataType;
2963 }
2964 
2966 {
2967  mDataType = dataType;
2968 }
2969 
2971 {
2973  map.insert( QStringLiteral( "data_type" ), mDataType );
2974  return map;
2975 }
2976 
2977 bool QgsProcessingParameterRange::fromVariantMap( const QVariantMap &map )
2978 {
2980  mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
2981  return true;
2982 }
2983 
2984 QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
2985 {
2986  return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant() : definition, isOptional );
2987 }
2988 
2989 QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
2990  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
2991 {
2992 
2993 }
2994 
2996 {
2997  return new QgsProcessingParameterRasterLayer( *this );
2998 }
2999 
3001 {
3002  if ( !input.isValid() )
3003  return mFlags & FlagOptional;
3004 
3005  if ( input.canConvert<QgsProperty>() )
3006  {
3007  return true;
3008  }
3009 
3010  if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
3011  return true;
3012 
3013  if ( input.type() != QVariant::String || input.toString().isEmpty() )
3014  return mFlags & FlagOptional;
3015 
3016  if ( !context )
3017  {
3018  // that's as far as we can get without a context
3019  return true;
3020  }
3021 
3022  // try to load as layer
3023  if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::LayerHint::Raster ) )
3024  return true;
3025 
3026  return false;
3027 }
3028 
3030 {
3031  if ( !val.isValid() )
3032  return QStringLiteral( "None" );
3033 
3034  if ( val.canConvert<QgsProperty>() )
3035  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3036 
3037  QVariantMap p;
3038  p.insert( name(), val );
3041  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3042 }
3043 
3044 QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3045 {
3046  return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
3047 }
3048 
3049 QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional )
3050  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3051  , mOptions( options )
3052  , mAllowMultiple( allowMultiple )
3053 {
3054 
3055 }
3056 
3058 {
3059  return new QgsProcessingParameterEnum( *this );
3060 }
3061 
3063 {
3064  QVariant input = value;
3065  if ( !input.isValid() )
3066  {
3067  if ( !defaultValue().isValid() )
3068  return mFlags & FlagOptional;
3069 
3070  input = defaultValue();
3071  }
3072 
3073  if ( input.canConvert<QgsProperty>() )
3074  {
3075  return true;
3076  }
3077 
3078  if ( input.type() == QVariant::List )
3079  {
3080  if ( !mAllowMultiple )
3081  return false;
3082 
3083  const QVariantList values = input.toList();
3084  if ( values.empty() && !( mFlags & FlagOptional ) )
3085  return false;
3086 
3087  for ( const QVariant &val : values )
3088  {
3089  bool ok = false;
3090  int res = val.toInt( &ok );
3091  if ( !ok )
3092  return false;
3093  else if ( res < 0 || res >= mOptions.count() )
3094  return false;
3095  }
3096 
3097  return true;
3098  }
3099  else if ( input.type() == QVariant::String )
3100  {
3101  QStringList parts = input.toString().split( ',' );
3102  if ( parts.count() > 1 && !mAllowMultiple )
3103  return false;
3104 
3105  const auto constParts = parts;
3106  for ( const QString &part : constParts )
3107  {
3108  bool ok = false;
3109  int res = part.toInt( &ok );
3110  if ( !ok )
3111  return false;
3112  else if ( res < 0 || res >= mOptions.count() )
3113  return false;
3114  }
3115  return true;
3116  }
3117  else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
3118  {
3119  bool ok = false;
3120  int res = input.toInt( &ok );
3121  if ( !ok )
3122  return false;
3123  else if ( res >= 0 && res < mOptions.count() )
3124  return true;
3125  }
3126  return false;
3127 }
3128 
3130 {
3131  if ( !value.isValid() )
3132  return QStringLiteral( "None" );
3133 
3134  if ( value.canConvert<QgsProperty>() )
3135  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3136 
3137  if ( value.type() == QVariant::List )
3138  {
3139  QStringList parts;
3140  const auto constToList = value.toList();
3141  for ( const QVariant &val : constToList )
3142  {
3143  parts << QString::number( static_cast< int >( val.toDouble() ) );
3144  }
3145  return parts.join( ',' ).prepend( '[' ).append( ']' );
3146  }
3147  else if ( value.type() == QVariant::String )
3148  {
3149  QStringList parts = value.toString().split( ',' );
3150  if ( parts.count() > 1 )
3151  {
3152  return parts.join( ',' ).prepend( '[' ).append( ']' );
3153  }
3154  }
3155 
3156  return QString::number( static_cast< int >( value.toDouble() ) );
3157 }
3158 
3160 {
3161  QString code = QStringLiteral( "##%1=" ).arg( mName );
3162  if ( mFlags & FlagOptional )
3163  code += QStringLiteral( "optional " );
3164  code += QStringLiteral( "enum " );
3165 
3166  if ( mAllowMultiple )
3167  code += QStringLiteral( "multiple " );
3168 
3169  code += mOptions.join( ';' ) + ' ';
3170 
3171  code += mDefault.toString();
3172  return code.trimmed();
3173 }
3174 
3176 {
3177  switch ( outputType )
3178  {
3180  {
3181  QString code = QStringLiteral( "QgsProcessingParameterEnum('%1', '%2'" ).arg( name(), description() );
3182  if ( mFlags & FlagOptional )
3183  code += QStringLiteral( ", optional=True" );
3184 
3185  QStringList options;
3186  options.reserve( mOptions.size() );
3187  for ( const QString &o : mOptions )
3189  code += QStringLiteral( ", options=[%1]" ).arg( options.join( ',' ) );
3190 
3191  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3192 
3194  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3195  return code;
3196  }
3197  }
3198  return QString();
3199 }
3200 
3202 {
3203  return mOptions;
3204 }
3205 
3207 {
3208  mOptions = options;
3209 }
3210 
3212 {
3213  return mAllowMultiple;
3214 }
3215 
3217 {
3218  mAllowMultiple = allowMultiple;
3219 }
3220 
3222 {
3224  map.insert( QStringLiteral( "options" ), mOptions );
3225  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
3226  return map;
3227 }
3228 
3229 bool QgsProcessingParameterEnum::fromVariantMap( const QVariantMap &map )
3230 {
3232  mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
3233  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
3234  return true;
3235 }
3236 
3237 QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3238 {
3239  QString defaultVal;
3240  bool multiple = false;
3241  QString def = definition;
3242  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
3243  {
3244  multiple = true;
3245  def = def.mid( 9 );
3246  }
3247 
3248  QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
3249  QRegularExpressionMatch m = re.match( def );
3250  QString values = def;
3251  if ( m.hasMatch() )
3252  {
3253  values = m.captured( 1 ).trimmed();
3254  defaultVal = m.captured( 2 );
3255  }
3256 
3257  return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
3258 }
3259 
3260 QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
3261  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3262  , mMultiLine( multiLine )
3263 {
3264 
3265 }
3266 
3268 {
3269  return new QgsProcessingParameterString( *this );
3270 }
3271 
3273 {
3274  if ( !value.isValid() || value.isNull() )
3275  return QStringLiteral( "None" );
3276 
3277  if ( value.canConvert<QgsProperty>() )
3278  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3279 
3280  QString s = value.toString();
3282 }
3283 
3285 {
3286  QString code = QStringLiteral( "##%1=" ).arg( mName );
3287  if ( mFlags & FlagOptional )
3288  code += QStringLiteral( "optional " );
3289  code += QStringLiteral( "string " );
3290 
3291  if ( mMultiLine )
3292  code += QStringLiteral( "long " );
3293 
3294  code += mDefault.toString();
3295  return code.trimmed();
3296 }
3297 
3299 {
3300  switch ( outputType )
3301  {
3303  {
3304  QString code = QStringLiteral( "QgsProcessingParameterString('%1', '%2'" ).arg( name(), description() );
3305  if ( mFlags & FlagOptional )
3306  code += QStringLiteral( ", optional=True" );
3307  code += QStringLiteral( ", multiLine=%1" ).arg( mMultiLine ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3308 
3310  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3311  return code;
3312  }
3313  }
3314  return QString();
3315 }
3316 
3318 {
3319  return mMultiLine;
3320 }
3321 
3323 {
3324  mMultiLine = multiLine;
3325 }
3326 
3328 {
3330  map.insert( QStringLiteral( "multiline" ), mMultiLine );
3331  return map;
3332 }
3333 
3334 bool QgsProcessingParameterString::fromVariantMap( const QVariantMap &map )
3335 {
3337  mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
3338  return true;
3339 }
3340 
3341 QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3342 {
3343  QString def = definition;
3344  bool multiLine = false;
3345  if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
3346  {
3347  multiLine = true;
3348  def = def.mid( 5 );
3349  }
3350 
3351  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
3352  def = def.mid( 1 );
3353  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
3354  def.chop( 1 );
3355 
3356  QVariant defaultValue = def;
3357  if ( def == QStringLiteral( "None" ) )
3358  defaultValue = QVariant();
3359 
3360  return new QgsProcessingParameterString( name, description, defaultValue, multiLine, isOptional );
3361 }
3362 
3363 //
3364 // QgsProcessingParameterAuthConfig
3365 //
3366 
3367 QgsProcessingParameterAuthConfig::QgsProcessingParameterAuthConfig( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
3368  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3369 {
3370 
3371 }
3372 
3374 {
3375  return new QgsProcessingParameterAuthConfig( *this );
3376 }
3377 
3379 {
3380  if ( !value.isValid() )
3381  return QStringLiteral( "None" );
3382 
3383  QString s = value.toString();
3385 }
3386 
3388 {
3389  QString code = QStringLiteral( "##%1=" ).arg( mName );
3390  if ( mFlags & FlagOptional )
3391  code += QStringLiteral( "optional " );
3392  code += QStringLiteral( "authcfg " );
3393 
3394  code += mDefault.toString();
3395  return code.trimmed();
3396 }
3397 
3398 QgsProcessingParameterAuthConfig *QgsProcessingParameterAuthConfig::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3399 {
3400  QString def = definition;
3401 
3402  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
3403  def = def.mid( 1 );
3404  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
3405  def.chop( 1 );
3406 
3407  QVariant defaultValue = def;
3408  if ( def == QStringLiteral( "None" ) )
3409  defaultValue = QVariant();
3410 
3411  return new QgsProcessingParameterAuthConfig( name, description, defaultValue, isOptional );
3412 }
3413 
3414 
3415 //
3416 // QgsProcessingParameterExpression
3417 //
3418 
3419 QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
3420  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3421  , mParentLayerParameterName( parentLayerParameterName )
3422 {
3423 
3424 }
3425 
3427 {
3428  return new QgsProcessingParameterExpression( *this );
3429 }
3430 
3432 {
3433  if ( !value.isValid() )
3434  return QStringLiteral( "None" );
3435 
3436  if ( value.canConvert<QgsProperty>() )
3437  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3438 
3439  QString s = value.toString();
3441 }
3442 
3444 {
3445  QStringList depends;
3446  if ( !mParentLayerParameterName.isEmpty() )
3447  depends << mParentLayerParameterName;
3448  return depends;
3449 }
3450 
3452 {
3453  switch ( outputType )
3454  {
3456  {
3457  QString code = QStringLiteral( "QgsProcessingParameterExpression('%1', '%2'" ).arg( name(), description() );
3458  if ( mFlags & FlagOptional )
3459  code += QStringLiteral( ", optional=True" );
3460 
3461  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
3462 
3464  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3465  return code;
3466  }
3467  }
3468  return QString();
3469 }
3470 
3472 {
3473  return mParentLayerParameterName;
3474 }
3475 
3477 {
3478  mParentLayerParameterName = parentLayerParameterName;
3479 }
3480 
3482 {
3484  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
3485  return map;
3486 }
3487 
3489 {
3491  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
3492  return true;
3493 }
3494 
3495 QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3496 {
3497  return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
3498 }
3499 
3500 QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
3501  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3503 {
3504 
3505 }
3506 
3508 {
3509  return new QgsProcessingParameterVectorLayer( *this );
3510 }
3511 
3513 {
3514  if ( !v.isValid() )
3515  return mFlags & FlagOptional;
3516 
3517  QVariant var = v;
3518 
3519  if ( var.canConvert<QgsProperty>() )
3520  {
3521  QgsProperty p = var.value< QgsProperty >();
3523  {
3524  var = p.staticValue();
3525  }
3526  else
3527  {
3528  return true;
3529  }
3530  }
3531 
3532  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
3533  return true;
3534 
3535  if ( var.type() != QVariant::String || var.toString().isEmpty() )
3536  return mFlags & FlagOptional;
3537 
3538  if ( !context )
3539  {
3540  // that's as far as we can get without a context
3541  return true;
3542  }
3543 
3544  // try to load as layer
3545  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
3546  return true;
3547 
3548  return false;
3549 }
3550 
3552 {
3553  if ( !val.isValid() )
3554  return QStringLiteral( "None" );
3555 
3556  if ( val.canConvert<QgsProperty>() )
3557  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3558 
3559  QVariantMap p;
3560  p.insert( name(), val );
3563  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3564 }
3565 
3567 {
3568  switch ( outputType )
3569  {
3571  {
3572  QString code = QStringLiteral( "QgsProcessingParameterVectorLayer('%1', '%2'" ).arg( name(), description() );
3573  if ( mFlags & FlagOptional )
3574  code += QStringLiteral( ", optional=True" );
3575 
3576  if ( !mDataTypes.empty() )
3577  {
3578  QStringList options;
3579  for ( int t : mDataTypes )
3580  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
3581  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
3582  }
3583 
3585  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3586  return code;
3587  }
3588  }
3589  return QString();
3590 }
3591 
3593 {
3594  return mDataTypes;
3595 }
3596 
3598 {
3599  mDataTypes = types;
3600 }
3601 
3603 {
3605  QVariantList types;
3606  const auto constMDataTypes = mDataTypes;
3607  for ( int type : constMDataTypes )
3608  {
3609  types << type;
3610  }
3611  map.insert( QStringLiteral( "data_types" ), types );
3612  return map;
3613 }
3614 
3616 {
3618  mDataTypes.clear();
3619  QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
3620  const auto constValues = values;
3621  for ( const QVariant &val : constValues )
3622  {
3623  mDataTypes << val.toInt();
3624  }
3625  return true;
3626 }
3627 
3628 QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3629 {
3630  return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
3631 }
3632 
3634  const QString &description,
3635  const QVariant &defaultValue,
3636  bool optional )
3637  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3638 {
3639 
3640 }
3641 
3643 {
3644  return new QgsProcessingParameterMeshLayer( *this );
3645 }
3646 
3648 {
3649  if ( !v.isValid() )
3650  return mFlags & FlagOptional;
3651 
3652  QVariant var = v;
3653 
3654  if ( var.canConvert<QgsProperty>() )
3655  {
3656  QgsProperty p = var.value< QgsProperty >();
3658  {
3659  var = p.staticValue();
3660  }
3661  else
3662  {
3663  return true;
3664  }
3665  }
3666 
3667  if ( qobject_cast< QgsMeshLayer * >( qvariant_cast<QObject *>( var ) ) )
3668  return true;
3669 
3670  if ( var.type() != QVariant::String || var.toString().isEmpty() )
3671  return mFlags & FlagOptional;
3672 
3673  if ( !context )
3674  {
3675  // that's as far as we can get without a context
3676  return true;
3677  }
3678 
3679  // try to load as layer
3680  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Mesh ) )
3681  return true;
3682 
3683  return false;
3684 }
3685 
3687 {
3688  if ( !val.isValid() )
3689  return QStringLiteral( "None" );
3690 
3691  if ( val.canConvert<QgsProperty>() )
3692  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
3693 
3694  QVariantMap p;
3695  p.insert( name(), val );
3696  QgsMeshLayer *layer = QgsProcessingParameters::parameterAsMeshLayer( this, p, context );
3698  : QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3699 }
3700 
3701 QgsProcessingParameterMeshLayer *QgsProcessingParameterMeshLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3702 {
3703  return new QgsProcessingParameterMeshLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
3704 }
3705 
3706 QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional )
3707  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3708  , mParentLayerParameterName( parentLayerParameterName )
3709  , mDataType( type )
3710  , mAllowMultiple( allowMultiple )
3711 {
3712 
3713 }
3714 
3715 
3717 {
3718  return new QgsProcessingParameterField( *this );
3719 }
3720 
3722 {
3723  if ( !input.isValid() )
3724  return mFlags & FlagOptional;
3725 
3726  if ( input.canConvert<QgsProperty>() )
3727  {
3728  return true;
3729  }
3730 
3731  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
3732  {
3733  if ( !mAllowMultiple )
3734  return false;
3735 
3736  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
3737  return false;
3738  }
3739  else if ( input.type() == QVariant::String )
3740  {
3741  if ( input.toString().isEmpty() )
3742  return mFlags & FlagOptional;
3743 
3744  QStringList parts = input.toString().split( ';' );
3745  if ( parts.count() > 1 && !mAllowMultiple )
3746  return false;
3747  }
3748  else
3749  {
3750  if ( input.toString().isEmpty() )
3751  return mFlags & FlagOptional;
3752  }
3753  return true;
3754 }
3755 
3757 {
3758  if ( !value.isValid() )
3759  return QStringLiteral( "None" );
3760 
3761  if ( value.canConvert<QgsProperty>() )
3762  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
3763 
3764  if ( value.type() == QVariant::List )
3765  {
3766  QStringList parts;
3767  const auto constToList = value.toList();
3768  for ( const QVariant &val : constToList )
3769  {
3770  parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
3771  }
3772  return parts.join( ',' ).prepend( '[' ).append( ']' );
3773  }
3774  else if ( value.type() == QVariant::StringList )
3775  {
3776  QStringList parts;
3777  const auto constToStringList = value.toStringList();
3778  for ( QString s : constToStringList )
3779  {
3781  }
3782  return parts.join( ',' ).prepend( '[' ).append( ']' );
3783  }
3784 
3785  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
3786 }
3787 
3789 {
3790  QString code = QStringLiteral( "##%1=" ).arg( mName );
3791  if ( mFlags & FlagOptional )
3792  code += QStringLiteral( "optional " );
3793  code += QStringLiteral( "field " );
3794 
3795  switch ( mDataType )
3796  {
3797  case Numeric:
3798  code += QStringLiteral( "numeric " );
3799  break;
3800 
3801  case String:
3802  code += QStringLiteral( "string " );
3803  break;
3804 
3805  case DateTime:
3806  code += QStringLiteral( "datetime " );
3807  break;
3808 
3809  case Any:
3810  break;
3811  }
3812 
3813  if ( mAllowMultiple )
3814  code += QStringLiteral( "multiple " );
3815 
3816  code += mParentLayerParameterName + ' ';
3817 
3818  code += mDefault.toString();
3819  return code.trimmed();
3820 }
3821 
3823 {
3824  switch ( outputType )
3825  {
3827  {
3828  QString code = QStringLiteral( "QgsProcessingParameterField('%1', '%2'" ).arg( name(), description() );
3829  if ( mFlags & FlagOptional )
3830  code += QStringLiteral( ", optional=True" );
3831 
3832  QString dataType;
3833  switch ( mDataType )
3834  {
3835  case Any:
3836  dataType = QStringLiteral( "QgsProcessingParameterField.Any" );
3837  break;
3838 
3839  case Numeric:
3840  dataType = QStringLiteral( "QgsProcessingParameterField.Numeric" );
3841  break;
3842 
3843  case String:
3844  dataType = QStringLiteral( "QgsProcessingParameterField.String" );
3845  break;
3846 
3847  case DateTime:
3848  dataType = QStringLiteral( "QgsProcessingParameterField.DateTime" );
3849  break;
3850  }
3851  code += QStringLiteral( ", type=%1" ).arg( dataType );
3852 
3853  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
3854  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
3855 
3857  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
3858  return code;
3859  }
3860  }
3861  return QString();
3862 }
3863 
3865 {
3866  QStringList depends;
3867  if ( !mParentLayerParameterName.isEmpty() )
3868  depends << mParentLayerParameterName;
3869  return depends;
3870 }
3871 
3873 {
3874  return mParentLayerParameterName;
3875 }
3876 
3878 {
3879  mParentLayerParameterName = parentLayerParameterName;
3880 }
3881 
3883 {
3884  return mDataType;
3885 }
3886 
3888 {
3889  mDataType = dataType;
3890 }
3891 
3893 {
3894  return mAllowMultiple;
3895 }
3896 
3898 {
3899  mAllowMultiple = allowMultiple;
3900 }
3901 
3903 {
3905  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
3906  map.insert( QStringLiteral( "data_type" ), mDataType );
3907  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
3908  return map;
3909 }
3910 
3911 bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
3912 {
3914  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
3915  mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
3916  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
3917  return true;
3918 }
3919 
3920 QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
3921 {
3922  QString parent;
3923  DataType type = Any;
3924  bool allowMultiple = false;
3925  QString def = definition;
3926 
3927  if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
3928  {
3929  type = Numeric;
3930  def = def.mid( 8 );
3931  }
3932  else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
3933  {
3934  type = String;
3935  def = def.mid( 7 );
3936  }
3937  else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
3938  {
3939  type = DateTime;
3940  def = def.mid( 9 );
3941  }
3942 
3943  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
3944  {
3945  allowMultiple = true;
3946  def = def.mid( 8 ).trimmed();
3947  }
3948 
3949  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
3950  QRegularExpressionMatch m = re.match( def );
3951  if ( m.hasMatch() )
3952  {
3953  parent = m.captured( 1 ).trimmed();
3954  def = m.captured( 2 );
3955  }
3956  else
3957  {
3958  parent = def;
3959  def.clear();
3960  }
3961 
3962  return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional );
3963 }
3964 
3965 QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
3966  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
3968 {
3969 
3970 }
3971 
3973 {
3974  return new QgsProcessingParameterFeatureSource( *this );
3975 }
3976 
3978 {
3979  QVariant var = input;
3980  if ( !var.isValid() )
3981  return mFlags & FlagOptional;
3982 
3983  if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
3984  {
3986  var = fromVar.source;
3987  }
3988  else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
3989  {
3990  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
3992  var = fromVar.sink;
3993  }
3994 
3995  if ( var.canConvert<QgsProperty>() )
3996  {
3997  QgsProperty p = var.value< QgsProperty >();
3999  {
4000  var = p.staticValue();
4001  }
4002  else
4003  {
4004  return true;
4005  }
4006  }
4007  if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
4008  {
4009  return true;
4010  }
4011 
4012  if ( var.type() != QVariant::String || var.toString().isEmpty() )
4013  return mFlags & FlagOptional;
4014 
4015  if ( !context )
4016  {
4017  // that's as far as we can get without a context
4018  return true;
4019  }
4020 
4021  // try to load as layer
4022  if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::LayerHint::Vector ) )
4023  return true;
4024 
4025  return false;
4026 }
4027 
4029 {
4030  if ( !value.isValid() )
4031  return QStringLiteral( "None" );
4032 
4033  if ( value.canConvert<QgsProperty>() )
4034  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4035 
4036  if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
4037  {
4039  if ( fromVar.source.propertyType() == QgsProperty::StaticProperty )
4040  {
4041  if ( fromVar.selectedFeaturesOnly )
4042  {
4043  return QStringLiteral( "QgsProcessingFeatureSourceDefinition('%1', True)" ).arg( fromVar.source.staticValue().toString() );
4044  }
4045  else
4046  {
4047  QString layerString = fromVar.source.staticValue().toString();
4048  // prefer to use layer source instead of id if possible (since it's persistent)
4049  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
4050  layerString = layer->source();
4051  return QgsProcessingUtils::stringToPythonLiteral( layerString );
4052  }
4053  }
4054  else
4055  {
4056  if ( fromVar.selectedFeaturesOnly )
4057  {
4058  return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression('%1'), True)" ).arg( fromVar.source.asExpression() );
4059  }
4060  else
4061  {
4062  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.source.asExpression() );
4063  }
4064  }
4065  }
4066  else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
4067  {
4068  return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
4069  }
4070 
4071  QString layerString = value.toString();
4072 
4073  // prefer to use layer source if possible (since it's persistent)
4074  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::LayerHint::Vector ) ) )
4075  layerString = layer->source();
4076 
4077  return QgsProcessingUtils::stringToPythonLiteral( layerString );
4078 }
4079 
4081 {
4082  QString code = QStringLiteral( "##%1=" ).arg( mName );
4083  if ( mFlags & FlagOptional )
4084  code += QStringLiteral( "optional " );
4085  code += QStringLiteral( "source " );
4086 
4087  const auto constMDataTypes = mDataTypes;
4088  for ( int type : constMDataTypes )
4089  {
4090  switch ( type )
4091  {
4093  code += QStringLiteral( "point " );
4094  break;
4095 
4097  code += QStringLiteral( "line " );
4098  break;
4099 
4101  code += QStringLiteral( "polygon " );
4102  break;
4103 
4104  }
4105  }
4106 
4107  code += mDefault.toString();
4108  return code.trimmed();
4109 }
4110 
4112 {
4113  switch ( outputType )
4114  {
4116  {
4117  QString code = QStringLiteral( "QgsProcessingParameterFeatureSource('%1', '%2'" ).arg( name(), description() );
4118  if ( mFlags & FlagOptional )
4119  code += QStringLiteral( ", optional=True" );
4120 
4121  if ( !mDataTypes.empty() )
4122  {
4123  QStringList options;
4124  options.reserve( mDataTypes.size() );
4125  for ( int t : mDataTypes )
4126  options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
4127  code += QStringLiteral( ", types=[%1]" ).arg( options.join( ',' ) );
4128  }
4129 
4131  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4132  return code;
4133  }
4134  }
4135  return QString();
4136 }
4137 
4139  : mDataTypes( types )
4140 {
4141 
4142 }
4143 
4145 {
4147  QVariantList types;
4148  const auto constMDataTypes = mDataTypes;
4149  for ( int type : constMDataTypes )
4150  {
4151  types << type;
4152  }
4153  map.insert( QStringLiteral( "data_types" ), types );
4154  return map;
4155 }
4156 
4158 {
4160  mDataTypes.clear();
4161  QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
4162  const auto constValues = values;
4163  for ( const QVariant &val : constValues )
4164  {
4165  mDataTypes << val.toInt();
4166  }
4167  return true;
4168 }
4169 
4170 QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4171 {
4172  QList< int > types;
4173  QString def = definition;
4174  while ( true )
4175  {
4176  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
4177  {
4179  def = def.mid( 6 );
4180  continue;
4181  }
4182  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
4183  {
4185  def = def.mid( 5 );
4186  continue;
4187  }
4188  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
4189  {
4191  def = def.mid( 8 );
4192  continue;
4193  }
4194  break;
4195  }
4196 
4197  return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
4198 }
4199 
4200 QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
4201  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4202  , mDataType( type )
4203 {
4204 }
4205 
4207 {
4208  return new QgsProcessingParameterFeatureSink( *this );
4209 }
4210 
4212 {
4213  QVariant var = input;
4214  if ( !var.isValid() )
4215  return mFlags & FlagOptional;
4216 
4217  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4218  {
4220  var = fromVar.sink;
4221  }
4222 
4223  if ( var.canConvert<QgsProperty>() )
4224  {
4225  QgsProperty p = var.value< QgsProperty >();
4227  {
4228  var = p.staticValue();
4229  }
4230  else
4231  {
4232  return true;
4233  }
4234  }
4235 
4236  if ( var.type() != QVariant::String )
4237  return false;
4238 
4239  if ( var.toString().isEmpty() )
4240  return mFlags & FlagOptional;
4241 
4242  return true;
4243 }
4244 
4246 {
4247  if ( !value.isValid() )
4248  return QStringLiteral( "None" );
4249 
4250  if ( value.canConvert<QgsProperty>() )
4251  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4252 
4253  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4254  {
4256  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4257  {
4258  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4259  }
4260  else
4261  {
4262  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4263  }
4264  }
4265 
4266  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4267 }
4268 
4270 {
4271  QString code = QStringLiteral( "##%1=" ).arg( mName );
4272  if ( mFlags & FlagOptional )
4273  code += QStringLiteral( "optional " );
4274  code += QStringLiteral( "sink " );
4275 
4276  switch ( mDataType )
4277  {
4279  code += QStringLiteral( "point " );
4280  break;
4281 
4283  code += QStringLiteral( "line " );
4284  break;
4285 
4287  code += QStringLiteral( "polygon " );
4288  break;
4289 
4291  code += QStringLiteral( "table " );
4292  break;
4293 
4294  default:
4295  break;
4296  }
4297 
4298  code += mDefault.toString();
4299  return code.trimmed();
4300 }
4301 
4303 {
4304  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
4305 }
4306 
4308 {
4309  if ( originalProvider() )
4310  {
4312  }
4313  else if ( QgsProcessingProvider *p = provider() )
4314  {
4315  return p->defaultVectorFileExtension( hasGeometry() );
4316  }
4317  else
4318  {
4319  QgsSettings settings;
4320  if ( hasGeometry() )
4321  {
4322  return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
4323  }
4324  else
4325  {
4326  return QStringLiteral( "dbf" );
4327  }
4328  }
4329 }
4330 
4332 {
4333  switch ( outputType )
4334  {
4336  {
4337  QString code = QStringLiteral( "QgsProcessingParameterFeatureSink('%1', '%2'" ).arg( name(), description() );
4338  if ( mFlags & FlagOptional )
4339  code += QStringLiteral( ", optional=True" );
4340 
4341  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
4342 
4343  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4344 
4346  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4347  return code;
4348  }
4349  }
4350  return QString();
4351 }
4352 
4354 {
4355  if ( originalProvider() )
4356  {
4357  if ( hasGeometry() )
4359  else
4361  }
4362  else if ( QgsProcessingProvider *p = provider() )
4363  {
4364  if ( hasGeometry() )
4365  return p->supportedOutputVectorLayerExtensions();
4366  else
4367  return p->supportedOutputTableExtensions();
4368  }
4369  else
4370  {
4372  }
4373 }
4374 
4376 {
4377  return mDataType;
4378 }
4379 
4381 {
4382  switch ( mDataType )
4383  {
4389  return true;
4390 
4395  return false;
4396  }
4397  return true;
4398 }
4399 
4401 {
4402  mDataType = type;
4403 }
4404 
4406 {
4408  map.insert( QStringLiteral( "data_type" ), mDataType );
4409  return map;
4410 }
4411 
4413 {
4415  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
4416  return true;
4417 }
4418 
4420 {
4422  return QStringLiteral( "memory:%1" ).arg( description() );
4423  else
4425 }
4426 
4427 QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4428 {
4430  QString def = definition;
4431  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
4432  {
4434  def = def.mid( 6 );
4435  }
4436  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
4437  {
4439  def = def.mid( 5 );
4440  }
4441  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
4442  {
4444  def = def.mid( 8 );
4445  }
4446  else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
4447  {
4449  def = def.mid( 6 );
4450  }
4451 
4452  return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
4453 }
4454 
4456  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4457 {
4458 }
4459 
4461 {
4462  return new QgsProcessingParameterRasterDestination( *this );
4463 }
4464 
4466 {
4467  QVariant var = input;
4468  if ( !var.isValid() )
4469  return mFlags & FlagOptional;
4470 
4471  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4472  {
4474  var = fromVar.sink;
4475  }
4476 
4477  if ( var.canConvert<QgsProperty>() )
4478  {
4479  QgsProperty p = var.value< QgsProperty >();
4481  {
4482  var = p.staticValue();
4483  }
4484  else
4485  {
4486  return true;
4487  }
4488  }
4489 
4490  if ( var.type() != QVariant::String )
4491  return false;
4492 
4493  if ( var.toString().isEmpty() )
4494  return mFlags & FlagOptional;
4495 
4496  return true;
4497 }
4498 
4500 {
4501  if ( !value.isValid() )
4502  return QStringLiteral( "None" );
4503 
4504  if ( value.canConvert<QgsProperty>() )
4505  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4506 
4507  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4508  {
4510  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4511  {
4512  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4513  }
4514  else
4515  {
4516  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4517  }
4518  }
4519 
4520  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4521 }
4522 
4524 {
4525  return new QgsProcessingOutputRasterLayer( name(), description() );
4526 }
4527 
4529 {
4530  if ( originalProvider() )
4531  {
4533  }
4534  else if ( QgsProcessingProvider *p = provider() )
4535  {
4536  return p->defaultRasterFileExtension();
4537  }
4538  else
4539  {
4540  QgsSettings settings;
4541  return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
4542  }
4543 }
4544 
4546 {
4547  if ( originalProvider() )
4548  {
4550  }
4551  else if ( QgsProcessingProvider *p = provider() )
4552  {
4553  return p->supportedOutputRasterLayerExtensions();
4554  }
4555  else
4556  {
4558  }
4559 }
4560 
4561 QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4562 {
4563  return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4564 }
4565 
4566 
4567 QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
4568  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4569  , mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
4570 {
4571 
4572 }
4573 
4575 {
4576  return new QgsProcessingParameterFileDestination( *this );
4577 }
4578 
4580 {
4581  QVariant var = input;
4582  if ( !var.isValid() )
4583  return mFlags & FlagOptional;
4584 
4585  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4586  {
4588  var = fromVar.sink;
4589  }
4590 
4591  if ( var.canConvert<QgsProperty>() )
4592  {
4593  QgsProperty p = var.value< QgsProperty >();
4595  {
4596  var = p.staticValue();
4597  }
4598  else
4599  {
4600  return true;
4601  }
4602  }
4603 
4604  if ( var.type() != QVariant::String )
4605  return false;
4606 
4607  if ( var.toString().isEmpty() )
4608  return mFlags & FlagOptional;
4609 
4610  // possible enhancement - check that value is compatible with file filter?
4611 
4612  return true;
4613 }
4614 
4616 {
4617  if ( !value.isValid() )
4618  return QStringLiteral( "None" );
4619 
4620  if ( value.canConvert<QgsProperty>() )
4621  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4622 
4623  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4624  {
4626  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4627  {
4628  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4629  }
4630  else
4631  {
4632  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4633  }
4634  }
4635 
4636  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4637 }
4638 
4640 {
4641  if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
4642  {
4643  return new QgsProcessingOutputHtml( name(), description() );
4644  }
4645  else
4646  {
4647  return new QgsProcessingOutputFile( name(), description() );
4648  }
4649 }
4650 
4652 {
4653  if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
4654  return QStringLiteral( "file" );
4655 
4656  // get first extension from filter
4657  QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
4658  QRegularExpressionMatch match = rx.match( mFileFilter );
4659  if ( !match.hasMatch() )
4660  return QStringLiteral( "file" );
4661 
4662  return match.captured( 1 );
4663 }
4664 
4666 {
4667  switch ( outputType )
4668  {
4670  {
4671  QString code = QStringLiteral( "QgsProcessingParameterFileDestination('%1', '%2'" ).arg( name(), description() );
4672  if ( mFlags & FlagOptional )
4673  code += QStringLiteral( ", optional=True" );
4674 
4675  code += QStringLiteral( ", fileFilter=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mFileFilter ) );
4676 
4677  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4678 
4680  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4681  return code;
4682  }
4683  }
4684  return QString();
4685 }
4686 
4688 {
4689  return mFileFilter;
4690 }
4691 
4693 {
4694  mFileFilter = fileFilter;
4695 }
4696 
4698 {
4700  map.insert( QStringLiteral( "file_filter" ), mFileFilter );
4701  return map;
4702 }
4703 
4705 {
4707  mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
4708  return true;
4709 
4710 }
4711 
4712 QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4713 {
4714  return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
4715 }
4716 
4718  : QgsProcessingDestinationParameter( name, description, defaultValue, optional )
4719 {}
4720 
4722 {
4723  return new QgsProcessingParameterFolderDestination( *this );
4724 }
4725 
4727 {
4728  QVariant var = input;
4729  if ( !var.isValid() )
4730  return mFlags & FlagOptional;
4731 
4732  if ( var.canConvert<QgsProperty>() )
4733  {
4734  QgsProperty p = var.value< QgsProperty >();
4736  {
4737  var = p.staticValue();
4738  }
4739  else
4740  {
4741  return true;
4742  }
4743  }
4744 
4745  if ( var.type() != QVariant::String )
4746  return false;
4747 
4748  if ( var.toString().isEmpty() )
4749  return mFlags & FlagOptional;
4750 
4751  return true;
4752 }
4753 
4755 {
4756  return new QgsProcessingOutputFolder( name(), description() );
4757 }
4758 
4760 {
4761  return QString();
4762 }
4763 
4764 QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
4765 {
4766  return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
4767 }
4768 
4769 QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
4770  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
4771  , mCreateByDefault( createByDefault )
4772 {
4773 
4774 }
4775 
4777 {
4779  map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
4780  map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
4781  return map;
4782 }
4783 
4785 {
4787  mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
4788  mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
4789  return true;
4790 }
4791 
4793 {
4794  switch ( outputType )
4795  {
4797  {
4798  // base class method is probably not much use
4799  if ( QgsProcessingParameterType *t = QgsApplication::processingRegistry()->parameterType( type() ) )
4800  {
4801  QString code = t->className() + QStringLiteral( "('%1', '%2'" ).arg( name(), description() );
4802  if ( mFlags & FlagOptional )
4803  code += QStringLiteral( ", optional=True" );
4804 
4805  code += QStringLiteral( ", createByDefault=%1" ).arg( mCreateByDefault ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4806 
4808  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4809  return code;
4810  }
4811  break;
4812  }
4813  }
4814  // oh well, we tried
4815  return QString();
4816 }
4817 
4819 {
4820  if ( defaultFileExtension().isEmpty() )
4821  {
4823  }
4824  else
4825  {
4827  }
4828 }
4829 
4831 {
4832  return mCreateByDefault;
4833 }
4834 
4836 {
4837  mCreateByDefault = createByDefault;
4838 }
4839 
4841  : QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
4842  , mDataType( type )
4843 {
4844 
4845 }
4846 
4848 {
4849  return new QgsProcessingParameterVectorDestination( *this );
4850 }
4851 
4853 {
4854  QVariant var = input;
4855  if ( !var.isValid() )
4856  return mFlags & FlagOptional;
4857 
4858  if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
4859  {
4861  var = fromVar.sink;
4862  }
4863 
4864  if ( var.canConvert<QgsProperty>() )
4865  {
4866  QgsProperty p = var.value< QgsProperty >();
4868  {
4869  var = p.staticValue();
4870  }
4871  else
4872  {
4873  return true;
4874  }
4875  }
4876 
4877  if ( var.type() != QVariant::String )
4878  return false;
4879 
4880  if ( var.toString().isEmpty() )
4881  return mFlags & FlagOptional;
4882 
4883  return true;
4884 }
4885 
4887 {
4888  if ( !value.isValid() )
4889  return QStringLiteral( "None" );
4890 
4891  if ( value.canConvert<QgsProperty>() )
4892  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
4893 
4894  if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
4895  {
4897  if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
4898  {
4899  return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
4900  }
4901  else
4902  {
4903  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
4904  }
4905  }
4906 
4907  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
4908 }
4909 
4911 {
4912  QString code = QStringLiteral( "##%1=" ).arg( mName );
4913  if ( mFlags & FlagOptional )
4914  code += QStringLiteral( "optional " );
4915  code += QStringLiteral( "vectorDestination " );
4916 
4917  switch ( mDataType )
4918  {
4920  code += QStringLiteral( "point " );
4921  break;
4922 
4924  code += QStringLiteral( "line " );
4925  break;
4926 
4928  code += QStringLiteral( "polygon " );
4929  break;
4930 
4931  default:
4932  break;
4933  }
4934 
4935  code += mDefault.toString();
4936  return code.trimmed();
4937 }
4938 
4940 {
4941  return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
4942 }
4943 
4945 {
4946  if ( originalProvider() )
4947  {
4949  }
4950  else if ( QgsProcessingProvider *p = provider() )
4951  {
4952  return p->defaultVectorFileExtension( hasGeometry() );
4953  }
4954  else
4955  {
4956  QgsSettings settings;
4957  if ( hasGeometry() )
4958  {
4959  return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
4960  }
4961  else
4962  {
4963  return QStringLiteral( "dbf" );
4964  }
4965  }
4966 }
4967 
4969 {
4970  switch ( outputType )
4971  {
4973  {
4974  QString code = QStringLiteral( "QgsProcessingParameterVectorDestination('%1', '%2'" ).arg( name(), description() );
4975  if ( mFlags & FlagOptional )
4976  code += QStringLiteral( ", optional=True" );
4977 
4978  code += QStringLiteral( ", type=QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( mDataType ) );
4979 
4980  code += QStringLiteral( ", createByDefault=%1" ).arg( createByDefault() ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
4981 
4983  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
4984  return code;
4985  }
4986  }
4987  return QString();
4988 }
4989 
4991 {
4992  if ( originalProvider() )
4993  {
4994  if ( hasGeometry() )
4996  else
4998  }
4999  else if ( QgsProcessingProvider *p = provider() )
5000  {
5001  if ( hasGeometry() )
5002  return p->supportedOutputVectorLayerExtensions();
5003  else
5004  return p->supportedOutputTableExtensions();
5005  }
5006  else
5007  {
5009  }
5010 }
5011 
5013 {
5014  return mDataType;
5015 }
5016 
5018 {
5019  switch ( mDataType )
5020  {
5026  return true;
5027 
5032  return false;
5033  }
5034  return true;
5035 }
5036 
5038 {
5039  mDataType = type;
5040 }
5041 
5043 {
5045  map.insert( QStringLiteral( "data_type" ), mDataType );
5046  return map;
5047 }
5048 
5050 {
5052  mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
5053  return true;
5054 }
5055 
5056 QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5057 {
5059  QString def = definition;
5060  if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
5061  {
5063  def = def.mid( 6 );
5064  }
5065  else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
5066  {
5068  def = def.mid( 5 );
5069  }
5070  else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
5071  {
5073  def = def.mid( 8 );
5074  }
5075 
5076  return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
5077 }
5078 
5079 QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
5080  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5081  , mParentLayerParameterName( parentLayerParameterName )
5082  , mAllowMultiple( allowMultiple )
5083 {
5084 
5085 }
5086 
5088 {
5089  return new QgsProcessingParameterBand( *this );
5090 }
5091 
5093 {
5094  if ( !input.isValid() )
5095  return mFlags & FlagOptional;
5096 
5097  if ( input.canConvert<QgsProperty>() )
5098  {
5099  return true;
5100  }
5101 
5102  if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
5103  {
5104  if ( !mAllowMultiple )
5105  return false;
5106 
5107  if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
5108  return false;
5109  }
5110  else
5111  {
5112  bool ok = false;
5113  double res = input.toInt( &ok );
5114  Q_UNUSED( res )
5115  if ( !ok )
5116  return mFlags & FlagOptional;
5117  }
5118  return true;
5119 }
5120 
5122 {
5123  return mAllowMultiple;
5124 }
5125 
5127 {
5128  mAllowMultiple = allowMultiple;
5129 }
5130 
5132 {
5133  if ( !value.isValid() )
5134  return QStringLiteral( "None" );
5135 
5136  if ( value.canConvert<QgsProperty>() )
5137  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5138 
5139  if ( value.type() == QVariant::List )
5140  {
5141  QStringList parts;
5142  QVariantList values = value.toList();
5143  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
5144  {
5145  parts << QString::number( static_cast< int >( it->toDouble() ) );
5146  }
5147  return parts.join( ',' ).prepend( '[' ).append( ']' );
5148  }
5149  else if ( value.type() == QVariant::StringList )
5150  {
5151  QStringList parts;
5152  QStringList values = value.toStringList();
5153  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
5154  {
5155  parts << QString::number( static_cast< int >( it->toDouble() ) );
5156  }
5157  return parts.join( ',' ).prepend( '[' ).append( ']' );
5158  }
5159 
5160  return value.toString();
5161 }
5162 
5164 {
5165  QString code = QStringLiteral( "##%1=" ).arg( mName );
5166  if ( mFlags & FlagOptional )
5167  code += QStringLiteral( "optional " );
5168  code += QStringLiteral( "band " );
5169 
5170  if ( mAllowMultiple )
5171  code += QStringLiteral( "multiple " );
5172 
5173  code += mParentLayerParameterName + ' ';
5174 
5175  code += mDefault.toString();
5176  return code.trimmed();
5177 }
5178 
5180 {
5181  QStringList depends;
5182  if ( !mParentLayerParameterName.isEmpty() )
5183  depends << mParentLayerParameterName;
5184  return depends;
5185 }
5186 
5188 {
5189  switch ( outputType )
5190  {
5192  {
5193  QString code = QStringLiteral( "QgsProcessingParameterBand('%1', '%2'" ).arg( name(), description() );
5194  if ( mFlags & FlagOptional )
5195  code += QStringLiteral( ", optional=True" );
5196 
5197  code += QStringLiteral( ", parentLayerParameterName='%1'" ).arg( mParentLayerParameterName );
5198  code += QStringLiteral( ", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral( "True" ) : QStringLiteral( "False" ) );
5199 
5201  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5202  return code;
5203  }
5204  }
5205  return QString();
5206 }
5207 
5209 {
5210  return mParentLayerParameterName;
5211 }
5212 
5214 {
5215  mParentLayerParameterName = parentLayerParameterName;
5216 }
5217 
5219 {
5221  map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
5222  map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
5223  return map;
5224 }
5225 
5226 bool QgsProcessingParameterBand::fromVariantMap( const QVariantMap &map )
5227 {
5229  mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
5230  mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
5231  return true;
5232 }
5233 
5234 QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5235 {
5236  QString parent;
5237  QString def = definition;
5238  bool allowMultiple = false;
5239 
5240  if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
5241  {
5242  allowMultiple = true;
5243  def = def.mid( 8 ).trimmed();
5244  }
5245 
5246  QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
5247  QRegularExpressionMatch m = re.match( def );
5248  if ( m.hasMatch() )
5249  {
5250  parent = m.captured( 1 ).trimmed();
5251  def = m.captured( 2 );
5252  }
5253  else
5254  {
5255  parent = def;
5256  def.clear();
5257  }
5258 
5259  return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
5260 }
5261 
5262 //
5263 // QgsProcessingParameterDistance
5264 //
5265 
5266 QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
5267  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
5268  , mParentParameterName( parentParameterName )
5269 {
5270 
5271 }
5272 
5274 {
5275  return new QgsProcessingParameterDistance( *this );
5276 }
5277 
5279 {
5280  return typeName();
5281 }
5282 
5284 {
5285  QStringList depends;
5286  if ( !mParentParameterName.isEmpty() )
5287  depends << mParentParameterName;
5288  return depends;
5289 }
5290 
5292 {
5293  switch ( outputType )
5294  {
5296  {
5297  QString code = QStringLiteral( "QgsProcessingParameterDistance('%1', '%2'" ).arg( name(), description() );
5298  if ( mFlags & FlagOptional )
5299  code += QStringLiteral( ", optional=True" );
5300 
5301  code += QStringLiteral( ", parentParameterName='%1'" ).arg( mParentParameterName );
5302 
5303  if ( minimum() != std::numeric_limits<double>::lowest() + 1 )
5304  code += QStringLiteral( ", minValue=%1" ).arg( minimum() );
5305  if ( maximum() != std::numeric_limits<double>::max() )
5306  code += QStringLiteral( ", maxValue=%1" ).arg( maximum() );
5308  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5309  return code;
5310  }
5311  }
5312  return QString();
5313 }
5314 
5316 {
5317  return mParentParameterName;
5318 }
5319 
5321 {
5322  mParentParameterName = parentParameterName;
5323 }
5324 
5326 {
5327  QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
5328  map.insert( QStringLiteral( "parent" ), mParentParameterName );
5329  map.insert( QStringLiteral( "default_unit" ), static_cast< int >( mDefaultUnit ) );
5330  return map;
5331 }
5332 
5334 {
5336  mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
5337  mDefaultUnit = static_cast< QgsUnitTypes::DistanceUnit>( map.value( QStringLiteral( "default_unit" ), QgsUnitTypes::DistanceUnknownUnit ).toInt() );
5338  return true;
5339 }
5340 
5341 
5342 //
5343 // QgsProcessingParameterScale
5344 //
5345 
5346 QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5347  : QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
5348 {
5349 
5350 }
5351 
5353 {
5354  return new QgsProcessingParameterScale( *this );
5355 }
5356 
5358 {
5359  return typeName();
5360 }
5361 
5363 {
5364  switch ( outputType )
5365  {
5367  {
5368  QString code = QStringLiteral( "QgsProcessingParameterScale('%1', '%2'" ).arg( name(), description() );
5369  if ( mFlags & FlagOptional )
5370  code += QStringLiteral( ", optional=True" );
5372  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5373  return code;
5374  }
5375  }
5376  return QString();
5377 }
5378 
5379 QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5380 {
5381  return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
5382  : ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
5383 }
5384 
5385 
5386 //
5387 // QgsProcessingParameterLayout
5388 //
5389 
5390 QgsProcessingParameterLayout::QgsProcessingParameterLayout( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5391  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5392 {}
5393 
5395 {
5396  return new QgsProcessingParameterLayout( *this );
5397 }
5398 
5400 {
5401  if ( !value.isValid() || value.isNull() )
5402  return QStringLiteral( "None" );
5403 
5404  if ( value.canConvert<QgsProperty>() )
5405  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5406 
5407  QString s = value.toString();
5409 }
5410 
5412 {
5413  QString code = QStringLiteral( "##%1=" ).arg( mName );
5414  if ( mFlags & FlagOptional )
5415  code += QStringLiteral( "optional " );
5416  code += QStringLiteral( "layout " );
5417 
5418  code += mDefault.toString();
5419  return code.trimmed();
5420 }
5421 
5423 {
5424  switch ( outputType )
5425  {
5427  {
5428  QString code = QStringLiteral( "QgsProcessingParameterLayout('%1', '%2'" ).arg( name(), description() );
5429  if ( mFlags & FlagOptional )
5430  code += QStringLiteral( ", optional=True" );
5432  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5433  return code;
5434  }
5435  }
5436  return QString();
5437 }
5438 
5439 QgsProcessingParameterLayout *QgsProcessingParameterLayout::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5440 {
5441  QString def = definition;
5442 
5443  if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
5444  def = def.mid( 1 );
5445  if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
5446  def.chop( 1 );
5447 
5448  QVariant defaultValue = def;
5449  if ( def == QStringLiteral( "None" ) )
5450  defaultValue = QVariant();
5451 
5452  return new QgsProcessingParameterLayout( name, description, defaultValue, isOptional );
5453 }
5454 
5455 
5456 //
5457 // QString mParentLayerParameterName;
5458 //
5459 
5460 QgsProcessingParameterLayoutItem::QgsProcessingParameterLayoutItem( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayoutParameterName, int itemType, bool optional )
5461  : QgsProcessingParameterDefinition( name, description, defaultValue, optional )
5462  , mParentLayoutParameterName( parentLayoutParameterName )
5463  , mItemType( itemType )
5464 {
5465 
5466 }
5467 
5469 {
5470  return new QgsProcessingParameterLayoutItem( *this );
5471 }
5472 
5474 {
5475  if ( !value.isValid() || value.isNull() )
5476  return QStringLiteral( "None" );
5477 
5478  if ( value.canConvert<QgsProperty>() )
5479  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
5480 
5481  QString s = value.toString();
5483 }
5484 
5486 {
5487  QString code = QStringLiteral( "##%1=" ).arg( mName );
5488  if ( mFlags & FlagOptional )
5489  code += QStringLiteral( "optional " );
5490  code += QStringLiteral( "layoutitem " );
5491  if ( mItemType >= 0 )
5492  code += QString::number( mItemType ) + ' ';
5493 
5494  code += mParentLayoutParameterName + ' ';
5495 
5496  code += mDefault.toString();
5497  return code.trimmed();
5498 }
5499 
5501 {
5502  switch ( outputType )
5503  {
5505  {
5506  QString code = QStringLiteral( "QgsProcessingParameterLayoutItem('%1', '%2'" ).arg( name(), description() );
5507  if ( mFlags & FlagOptional )
5508  code += QStringLiteral( ", optional=True" );
5509 
5510  if ( mItemType >= 0 )
5511  code += QStringLiteral( ", itemType=%1" ).arg( mItemType );
5512 
5513  code += QStringLiteral( ", parentLayoutParameterName='%1'" ).arg( mParentLayoutParameterName );
5514 
5516  code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5517  return code;
5518  }
5519  }
5520  return QString();
5521 }
5522 
5524 {
5526  map.insert( QStringLiteral( "parent_layout" ), mParentLayoutParameterName );
5527  map.insert( QStringLiteral( "item_type" ), mItemType );
5528  return map;
5529 }
5530 
5532 {
5534  mParentLayoutParameterName = map.value( QStringLiteral( "parent_layout" ) ).toString();
5535  mItemType = map.value( QStringLiteral( "item_type" ) ).toInt();
5536  return true;
5537 }
5538 
5540 {
5541  QStringList depends;
5542  if ( !mParentLayoutParameterName.isEmpty() )
5543  depends << mParentLayoutParameterName;
5544  return depends;
5545 }
5546 
5547 QgsProcessingParameterLayoutItem *QgsProcessingParameterLayoutItem::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5548 {
5549  QString parent;
5550  QString def = definition;
5551  int itemType = -1;
5552  QRegularExpression re( QStringLiteral( "(\\d+)?\\s*(.*?)\\s+(.*)$" ) );
5553  QRegularExpressionMatch m = re.match( def );
5554  if ( m.hasMatch() )
5555  {
5556  itemType = m.captured( 1 ).trimmed().isEmpty() ? -1 : m.captured( 1 ).trimmed().toInt();
5557  parent = m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ).trimmed() : m.captured( 2 ).trimmed();
5558  def = !m.captured( 2 ).trimmed().isEmpty() ? m.captured( 3 ) : QString();
5559  }
5560  else
5561  {
5562  parent = def;
5563  def.clear();
5564  }
5565 
5566  return new QgsProcessingParameterLayoutItem( name, description, def.isEmpty() ? QVariant() : def, parent, itemType, isOptional );
5567 }
5568 
5570 {
5571  return mParentLayoutParameterName;
5572 }
5573 
5575 {
5576  mParentLayoutParameterName = name;
5577 }
5578 
5580 {
5581  return mItemType;
5582 }
5583 
5585 {
5586  mItemType = type;
5587 }
QgsProcessingParameterDefinition(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterDefinition.
QgsProperty sink
Sink/layer definition.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
static QgsCoordinateReferenceSystem parameterAsCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a coordinate reference system.
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...
A boolean parameter for processing algorithms.
int itemType() const
Returns the acceptable item type, or -1 if any item type is allowed.
Class for parsing and evaluation of expressions (formerly called "search strings").
void setDataTypes(const QList< int > &types)
Sets the geometry types for sources acceptable by the parameter.
static QString typeName()
Returns the type name for the parameter class.
An input file or folder parameter for processing algorithms.
A parameter for processing algorithms which accepts multiple map layers.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
virtual QString asScriptCode() const
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 QgsProcessingParameterLayoutItem * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
Base class for all map layer types.
Definition: qgsmaplayer.h:78
static QString descriptionFromName(const QString &name)
Creates an autogenerated parameter description from a parameter name.
static QString parameterAsString(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static string value.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QgsLayoutItem * itemById(const QString &id) const
Returns a layout item given its id.
Definition: qgslayout.cpp:264
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.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
static QString typeName()
Returns the type name for the parameter class.
Base class for providing feedback from a processing algorithm.
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...
virtual bool fromVariantMap(const QVariantMap &map)
Restores 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...
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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.
static QVariantList parameterAsMatrix(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a matrix/table of values.
Base class for graphical items within a QgsLayout.
virtual QStringList supportedOutputTableExtensions() const
Returns a list of the table (geometry-less vector layers) file extensions supported by this provider...
Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString type() const override
Unique parameter type name.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
bool hasFixedNumberRows() const
Returns whether the table has a fixed number of rows.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
bool createFromString(const QString &definition)
Set up this CRS from a string definition.
QString type() const override
Unique parameter type name.
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 vector layer or feature source field parameter for processing algorithms.
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
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.
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.
DataType dataType() const
Returns the acceptable data type for the field.
bool fromVariantMap(const QVariantMap &map) override
Restores 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 type() const override
Unique parameter type name.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
virtual QStringList supportedOutputRasterLayerExtensions() const
Returns a list of the raster format file extensions supported for this parameter. ...
void setHasFixedNumberRows(bool hasFixedNumberRows)
Sets whether the table has a fixed number of rows.
QgsProcessingParameterMultipleLayers(const QString &name, const QString &description=QString(), QgsProcessing::SourceType layerType=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMultipleLayers.
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...
QgsProcessingParameterExpression(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), const QString &parentLayerParameterName=QString(), bool optional=false)
Constructor for QgsProcessingParameterExpression.
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...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
LayerHint
Layer type hints.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessingParameterRange(const QString &name, const QString &description=QString(), QgsProcessingParameterNumber::Type type=QgsProcessingParameterNumber::Integer, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRange.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QgsProcessingParameterFeatureSource(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterFeatureSource.
void setDataType(QgsProcessingParameterNumber::Type dataType)
Sets the acceptable data type for the range.
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.
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
static QList< int > parameterAsEnums(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to list of enum values.
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
static QString typeName()
Returns the type name for the parameter class.
A print layout parameter, allowing users to select a print layout.
QString type() const override
Unique parameter type name.
double y
Definition: qgspointxy.h:48
A map layer 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...
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...
QStringList headers() const
Returns a list of column headers (if set).
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
A class to represent a 2D point.
Definition: qgspointxy.h:43
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 HTML file output for processing algorithms.
QgsProcessingParameterLayout(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterLayout.
QgsProcessingProvider * provider() const
Returns a pointer to the provider for the algorithm which owns this parameter.
An expression parameter for processing algorithms.
A QgsPointXY with associated coordinate reference system.
static QString typeName()
Returns the type name for the parameter class.
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.
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:236
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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...
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...
bool createByDefault() const
Returns true if the destination should be created by default.
An interface for objects which accept features via addFeature(s) methods.
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 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...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
PythonOutputType
Available Python output types.
Definition: qgsprocessing.h:58
QgsProcessingProvider * originalProvider() const
Original (source) provider which this parameter has been derived from.
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...
QgsProcessingAlgorithm * mAlgorithm
Pointer to algorithm which owns this parameter.
virtual QStringList supportedOutputRasterLayerExtensions() const
Returns a list of the raster format file extensions supported by this provider.
static QString typeName()
Returns the type name for the parameter class.
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap mMetadata
Freeform metadata for parameter. Mostly used by widget wrappers to customize their appearance and beh...
QString type() const override
Unique parameter type name.
double minimum() const
Returns the minimum value acceptable by the parameter.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource, modifying results according to the settings in a QgsProcessingContext.
Container of fields for a vector layer.
Definition: qgsfields.h:42
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.
static QgsRasterLayer * parameterAsRasterLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a raster layer.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
static QgsMapLayer * parameterAsLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a map layer.
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...
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.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Abstract base class for processing providers.
virtual QVariantMap toVariantMap() const
Saves this parameter to a QVariantMap.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
bool allowMultiple() const
Returns true if the parameter allows multiple selected values.
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...
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
QgsProcessingParameterMapLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMapLayer.
A raster band parameter for Processing algorithms.
QString type() const override
Unique parameter type name.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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...
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.
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...
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 QgsProcessingParameterDefinition * parameterFromVariantMap(const QVariantMap &map)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied variant map...
QgsProcessingParameterEnum(const QString &name, const QString &description=QString(), const QStringList &options=QStringList(), bool allowMultiple=false, const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterEnum.
QgsProcessingParameterBoolean(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterBoolean.
QString type() const override
Unique parameter type name.
QgsProcessingParameterType * parameterType(const QString &id) const
Returns the parameter type registered for id.
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.
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
const QgsCoordinateReferenceSystem & crs
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 convertToCompatibleFormat(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback)
Converts a source vector layer to a file path to a vector layer of compatible format.
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...
static QString typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
void setMaximum(double maximum)
Sets the maximum value acceptable by the parameter.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
static QString normalizeLayerSource(const QString &source)
Normalizes a layer source string for safe comparison across different operating system environments...
static QgsVectorLayer * parameterAsVectorLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a vector layer.
Base class for all parameter definitions which represent file or layer destinations, e.g.
Abstract base class for processing algorithms.
static QgsPointXY parameterAsPoint(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Evaluates the parameter with matching definition to a point.
A vector layer output for processing algorithms.
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.
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 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 parameterAsFile(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file/folder name.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A feature sink output for processing algorithms.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QString fileFilter() const
Returns the file filter string for file destinations compatible with this 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.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Files (i.e. non map layer sources, such as text files)
Definition: qgsprocessing.h:52
bool selectedFeaturesOnly
true if only selected features in the source should be used by algorithms.
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...
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsProcessingParameterScale(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterScale.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
int minimumNumberInputs() const
Returns the minimum number of layers required for the parameter.
void setAllowMultiple(bool allowMultiple)
Sets whether multiple field selections are permitted.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
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.
static QString typeName()
Returns the type name for the parameter class.
QgsProcessing::SourceType layerType() const
Returns the layer type for layers acceptable by the parameter.
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 QgsCoordinateReferenceSystem parameterAsExtentCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an extent parameter value.
static QString typeName()
Returns the type name for the parameter class.
A numeric range parameter for processing algorithms.
A double numeric parameter for map scale values.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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.
QString parentLayoutParameterName() const
Returns the name of the parent layout parameter, or an empty string if this is not set...
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.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
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.
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
QgsProcessingParameterCrs(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterCrs.
QVariant toVariant() const
Saves this property to a QVariantMap, wrapped in a QVariant.
QList< int > dataTypes() const
Returns the geometry types for sources acceptable by the parameter.
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.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set...
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)
Constructor for QgsProcessingParameterFolderDestination.
static QString typeName()
Returns the type name for the parameter class.
static QgsFeatureSink * createFeatureSink(QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions=QVariantMap(), QgsFeatureSink::SinkFlags sinkFlags=nullptr)
Creates a feature sink ready for adding features.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QString parentLayerParameterName() const
Returns the name of the parent layer parameter, or an empty string if this is not set...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
Can be inherited by parameters which require limits to their acceptable data types.
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...
A raster layer parameter for processing algorithms.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QgsProcessingParameterFeatureSink(const QString &name, const QString &description=QString(), QgsProcessing::SourceType type=QgsProcessing::TypeVectorAnyGeometry, const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterFeatureSink.
QgsProcessingParameterFile(const QString &name, const QString &description=QString(), Behavior behavior=File, const QString &extension=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterFile.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
static QStringList supportedFormatExtensions(RasterFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats.
virtual QString toolTip() const
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
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.
static QgsCoordinateReferenceSystem parameterAsPointCrs(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Returns the coordinate reference system associated with an point parameter value. ...
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.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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=nullptr)
Evaluates the parameter with matching definition to a feature sink.
QgsProperty source
Source definition.
virtual QgsProcessingParameterDefinition * create(const QString &name) const =0
Creates a new parameter of this type.
Type propertyType() const
Returns the property type.
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...
QVariantMap toVariantMap() const override
Saves 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.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable 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 type() const override
Unique parameter type name.
An enum based parameter for processing algorithms, allowing for selection from predefined values...
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
void setMinimum(double minimum)
Sets the minimum value acceptable by the parameter.
Flags flags() const
Returns any flags associated with the parameter.
QgsProcessing::SourceType dataType() const
Returns the layer type for this created vector layer.
static QString typeName()
Returns the type name for the parameter class.
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.
QVariant defaultValue() const
Returns the default value 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...
bool hasGeometry() const
Returns true if the created layer is likely to include geometries.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDistance * clone() const override
Creates a clone of the parameter definition.
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.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
bool allowMultiple() const
Returns whether multiple band selections are permitted.
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Returns a copy of the geometry which has been densified by adding the specified number of extra nodes...
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:225
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
virtual QString defaultRasterFileExtension() const
Returns the default file extension to use for raster outputs created by the provider.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
A double numeric parameter for distance values.
A file output for processing algorithms.
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:95
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QgsProcessingDestinationParameter(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingDestinationParameter.
QString parentParameterName() const
Returns the name of the parent 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 QgsProcessingParameterScale * fromScriptCode(const QString &name, const QString &description, bool isOptional, const QString &definition)
Creates a new parameter using the definition from a script code.
QgsProcessingAlgorithm * algorithm() const
Returns a pointer to the algorithm which owns this parameter.
static const QString TEMPORARY_OUTPUT
Constant used to indicate that a Processing algorithm output should be a temporary layer/file...
Definition: qgsprocessing.h:99
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
static QList< double > parameterAsRange(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a range of values.
QString type() const override
Unique parameter type name.
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.
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
virtual QgsMasterLayoutInterface::Type layoutType() const =0
Returns the master layout type.
virtual QString type() const =0
Unique parameter type name.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
Reads and writes project states.
Definition: qgsproject.h:89
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.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
Vector polygon layers.
Definition: qgsprocessing.h:50
static bool parameterAsBoolean(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
A vector layer (with or without geometry) parameter for processing algorithms.
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.
bool multiLine() const
Returns true if the parameter allows multiline strings.
virtual QString defaultFileExtension() const =0
Returns the default file extension for destination file paths associated with this parameter...
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterScale * clone() const override
Creates a clone of the parameter definition.
void setParentLayerParameterName(const QString &parentLayerParameterName)
Sets the name of the parent layer parameter.
void setParentParameterName(const QString &parentParameterName)
Sets the name of the parent layer parameter.
QStringList options() const
Returns the list of acceptable options for the parameter.
A QgsRectangle with associated coordinate reference system.
void setItemType(int type)
Sets the acceptable item type, or -1 if any item type is allowed.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
A print layout item parameter, allowing users to select a particular item from a print layout...
A mesh layer parameter for processing algorithms.
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.
A coordinate reference system parameter for processing algorithms.
static QgsProcessingFeatureSource * variantToSource(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a new feature source.
A store for object properties.
Definition: qgsproperty.h:229
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...
A rectangular map extent parameter for processing algorithms.
void setMinimumNumberInputs(int minimum)
Sets the minimum number of layers required for 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...
void setLayerType(QgsProcessing::SourceType type)
Sets the layer type for layers acceptable by the parameter.
void setAllowMultiple(bool allowMultiple)
Sets whether multiple band selections are permitted.
Details for layers to load into projects.
void setAllowMultiple(bool allowMultiple)
Sets whether the parameter allows multiple selected values.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A numeric parameter for processing algorithms.
bool loadVariant(const QVariantMap &map)
Loads this output layer definition from a QVariantMap, wrapped in a QVariant.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
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.
QgsExpressionContext & expressionContext()
Returns the expression context.
double x
Definition: qgspointxy.h:47
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 QgsPrintLayout * parameterAsLayout(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a print layout.
const QgsLayoutManager * layoutManager() const
Returns the project&#39;s layout manager, which manages compositions within the project.
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.
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 fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
QString name() const
Returns the name of 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...
QList< int > mDataTypes
List of acceptable data types for the parameter.
Encapsulates settings relating to a feature source input to a processing algorithm.
void setMultiLine(bool multiLine)
Sets whether the parameter allows multiline strings.
QStringList dependsOnOtherParameters() const override
Returns a list of other parameter names on which this parameter is dependent (e.g.
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...
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool supportsNonFileBasedOutput() const
Returns true if the destination parameter supports non filed-based outputs, such as memory layers or ...
Behavior behavior() const
Returns the parameter behavior (e.g.
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.
QString asWkt(int precision=17) const
Exports the geometry to WKT.
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.
static QString generateTempFilename(const QString &basename)
Returns a temporary filename for a given file, putting it into a temporary folder (creating that fold...
QString type() const override
Unique parameter type name.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:54
QVariant toVariant() const
Saves this output layer definition to a QVariantMap, wrapped in a QVariant.
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...
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
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 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...
virtual QString defaultVectorFileExtension(bool hasGeometry=true) const
Returns the default file extension to use for vector outputs created by the provider.
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.
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.
Base class for the definition of processing outputs.
void setCreateByDefault(bool createByDefault)
Sets whether the destination should be created by default.
static QString typeName()
Returns the type name for the parameter class.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Unknown distance unit.
Definition: qgsunittypes.h:65
QgsProcessing::SourceType dataType() const
Returns the layer type for sinks associated with the parameter.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
QgsProcessingParameterLimitedDataTypes(const QList< int > &types=QList< int >())
Constructor for QgsProcessingParameterLimitedDataTypes, with a list of acceptable data types...
void setNumberRows(int rows)
Sets the fixed number of rows in the table.
A vector layer destination parameter, for specifying the destination path for a vector layer created ...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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...
A point parameter for processing algorithms.
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
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.
void setDataType(DataType type)
Sets the acceptable data type for the field.
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.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
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...
Vector point layers.
Definition: qgsprocessing.h:48
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
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.
QString source() const
Returns the source for the layer.
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 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...
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
An input feature source (such as vector layers) parameter for processing algorithms.
A folder destination parameter, for specifying the destination path for a folder created by the algor...
int valueAsInt(const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as an integer.
QString destinationName
Name to use for sink if it&#39;s to be loaded into a destination project.
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.
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.
Any map layer type (raster or vector or mesh)
Definition: qgsprocessing.h:46
Makes metadata of processing parameters available.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QString toolTip() const override
Returns a formatted tooltip for use with the parameter, which gives helpful information like paramete...
QgsProject * destinationProject
Destination project.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
This class represents a coordinate reference system (CRS).
int numberRows() const
Returns the fixed number of rows in the table.
Base class for the definition of processing parameters.
Vector line layers.
Definition: qgsprocessing.h:49
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:436
virtual bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const
Checks whether the specified input value is acceptable for the parameter.
static QgsProcessingParameterDefinition * parameterFromScriptCode(const QString &code)
Creates a new QgsProcessingParameterDefinition using the configuration from a supplied script code st...
QVariant staticValue() const
Returns the current static value for the property.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:53
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...
Class for doing transforms between two map coordinate systems.
static double parameterAsDouble(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static double value.
QVariant mDefault
Default value for parameter.
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
static QString parameterAsOutputLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a output layer destination.
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.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
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 typeName()
Returns the type name for the parameter class.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
static QgsProcessingFeatureSource * parameterAsSource(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a feature source.
bool fromVariantMap(const QVariantMap &map) override
Restores 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...
QgsProcessingParameterMeshLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterMeshLayer.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:90
static QString typeName()
Returns the type name for the parameter class.
static bool parameterAsBool(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static boolean value.
virtual QString generateTemporaryDestination() const
Generates a temporary destination value for this parameter.
A folder output for processing algorithms.
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...
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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.
A table (matrix) parameter for processing algorithms.
Full Python QgsProcessingAlgorithm subclass.
Definition: qgsprocessing.h:60
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
Type dataType() const
Returns the acceptable data type for the parameter.
QString type() const override
Unique parameter type name.
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.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
A string parameter for authentication configuration ID values.
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.
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this provider.
QString mDescription
Parameter description.
void setFileFilter(const QString &filter)
Sets 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.
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 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...
bool hasGeometry() const
Returns true if sink is likely to include geometries.
QgsProcessingParameterAuthConfig(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterAuthConfig.
Interface for master layout type objects, such as print layouts and reports.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
QgsProcessingParameterExtent(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterExtent.
bool fromVariantMap(const QVariantMap &map) override
Restores this parameter to a QVariantMap.
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)
Constructor for QgsProcessingParameterField.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
QString asScriptCode() const override
Returns the parameter definition encoded in a string which can be used within a Processing script...
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.
Represents a vector layer which manages a vector based data sets.
static QString parameterAsExpression(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to an expression.
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...
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
Static property (QgsStaticProperty)
Definition: qgsproperty.h:237
Contains information about the context in which a processing algorithm is executed.
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.
static QString sourceTypeToString(SourceType type)
Converts a source type to a string representation.
Definition: qgsprocessing.h:68
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 defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this 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...
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the created vector layer.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
A string 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 description() const
Returns the description for the parameter.
QgsProcessingParameterDefinition * clone() const override
Creates a clone of the parameter definition.
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...
QgsProcessingParameterVectorLayer(const QString &name, const QString &description=QString(), const QList< int > &types=QList< int >(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterVectorLayer.
void setDataType(QgsProcessing::SourceType type)
Sets the layer type for the sinks associated with the parameter.
Any vector layer with geometry.
Definition: qgsprocessing.h:47
QgsProcessingParameterNumber::Type dataType() const
Returns the acceptable data type for the range.
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.
QString type() const override
Unique parameter type name.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
bool allowMultiple() const
Returns whether multiple field selections are permitted.
QString authid() const
Returns the authority identifier for the CRS.
QString defaultFileExtension() const override
Returns the default file extension for destination file paths associated with this parameter...
virtual QStringList supportedOutputVectorLayerExtensions() const
Returns a list of the vector format file extensions supported by this parameter.
QString generateTemporaryDestination() const override
Generates a temporary destination value for this parameter.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:85
void setParentLayoutParameterName(const QString &name)
Sets the name of the parent layout parameter.
QgsProcessingParameterRasterLayer(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false)
Constructor for QgsProcessingParameterRasterLayer.
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.
double maximum() const
Returns the maximum value acceptable by the parameter.
QVariantMap createOptions
Map of optional sink/layer creation options, which are passed to the underlying provider when creatin...
Individual print layout (QgsPrintLayout)
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
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.
QgsProcessingParameterRasterDestination(const QString &name, const QString &description=QString(), const QVariant &defaultValue=QVariant(), bool optional=false, bool createByDefault=true)
Constructor for QgsProcessingParameterRasterDestination.
bool checkValueIsAcceptable(const QVariant &input, QgsProcessingContext *context=nullptr) const override
Checks whether the specified input value is acceptable for the parameter.
QgsProcessingOutputDefinition * toOutputDefinition() const override
Returns a new QgsProcessingOutputDefinition corresponding to the definition of the destination parame...
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.
A raster layer output for processing algorithms.
static QgsProcessingRegistry * processingRegistry()
Returns the application&#39;s processing registry, used for managing processing providers, algorithms, and various parameters and outputs.
static QString parameterAsFileOutput(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a file based output destination.
QVariantMap toVariantMap() const override
Saves this parameter to a QVariantMap.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
static QStringList parameterAsFields(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of fields.
void setHeaders(const QStringList &headers)
Sets the list of column headers.