41#include <QRegularExpression>
49 map.insert( QStringLiteral(
"feature_limit" ),
featureLimit );
51 map.insert( QStringLiteral(
"flags" ),
static_cast< int >(
flags ) );
52 map.insert( QStringLiteral(
"geometry_check" ),
static_cast< int >(
geometryCheck ) );
60 featureLimit = map.value( QStringLiteral(
"feature_limit" ), -1 ).toLongLong();
62 flags =
static_cast< Flags
>( map.value( QStringLiteral(
"flags" ), 0 ).toInt() );
75 mRemappingDefinition = definition;
82 map.insert( QStringLiteral(
"create_options" ),
createOptions );
84 map.insert( QStringLiteral(
"remapping" ), QVariant::fromValue( mRemappingDefinition ) );
91 createOptions = map.value( QStringLiteral(
"create_options" ) ).toMap();
92 if ( map.contains( QStringLiteral(
"remapping" ) ) )
99 mUseRemapping =
false;
107 && mUseRemapping == other.mUseRemapping && mRemappingDefinition == other.mRemappingDefinition;
112 return !( *
this == other );
117 const QVariant val = parameters.value( name );
118 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
137 QVariant val = value;
138 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
141 if ( !val.isValid() )
150 return destParam->generateTemporaryDestination( &context );
153 return val.toString();
169 const QVariant val = value;
170 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
173 if ( val.isValid() && !val.toString().isEmpty() )
177 return val.toString();
197 QVariant val = value;
198 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
202 const double res = val.toDouble( &ok );
208 return val.toDouble();
224 QVariant val = value;
225 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
229 double dbl = val.toDouble( &ok );
234 dbl = val.toDouble( &ok );
241 const double round = std::round( dbl );
242 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
247 return static_cast< int >( std::round( dbl ) );
256 return QList< int >();
264 return QList< int >();
266 QList< int > resultList;
267 const QVariant val = value;
270 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
272 else if ( val.type() == QVariant::List )
274 const QVariantList list = val.toList();
275 for (
auto it = list.constBegin(); it != list.constEnd(); ++it )
276 resultList << it->toInt();
280 const QStringList parts = val.toString().split(
';' );
281 for (
auto it = parts.constBegin(); it != parts.constEnd(); ++it )
282 resultList << it->toInt();
286 if ( resultList.isEmpty() )
291 if ( definition->
defaultValue().type() == QVariant::List )
293 const QVariantList list = definition->
defaultValue().toList();
294 for (
auto it = list.constBegin(); it != list.constEnd(); ++it )
295 resultList << it->toInt();
299 const QStringList parts = definition->
defaultValue().toString().split(
';' );
300 for (
auto it = parts.constBegin(); it != parts.constEnd(); ++it )
301 resultList << it->toInt();
322 QVariant val = value;
323 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
326 QDateTime d = val.toDateTime();
327 if ( !d.isValid() && val.type() == QVariant::String )
329 d = QDateTime::fromString( val.toString() );
336 d = val.toDateTime();
338 if ( !d.isValid() && val.type() == QVariant::String )
340 d = QDateTime::fromString( val.toString() );
359 QVariant val = value;
360 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
363 QDate d = val.toDate();
364 if ( !d.isValid() && val.type() == QVariant::String )
366 d = QDate::fromString( val.toString() );
375 if ( !d.isValid() && val.type() == QVariant::String )
377 d = QDate::fromString( val.toString() );
396 QVariant val = value;
397 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
402 if ( val.type() == QVariant::DateTime )
403 d = val.toDateTime().time();
407 if ( !d.isValid() && val.type() == QVariant::String )
409 d = QTime::fromString( val.toString() );
418 if ( !d.isValid() && val.type() == QVariant::String )
420 d = QTime::fromString( val.toString() );
441 if ( enumDef && val >= enumDef->
options().size() )
461 QVariantList resultList;
462 const QVariant val = value;
463 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
465 else if ( val.type() == QVariant::List )
467 const auto constToList = val.toList();
468 for (
const QVariant &var : constToList )
471 else if ( val.type() == QVariant::String )
473 const auto constSplit = val.toString().split(
',' );
474 for (
const QString &var : constSplit )
480 if ( resultList.isEmpty() )
481 return QList< int >();
483 if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
487 if ( definition->
defaultValue().type() == QVariant::List )
489 const auto constToList = definition->
defaultValue().toList();
490 for (
const QVariant &var : constToList )
493 else if ( definition->
defaultValue().type() == QVariant::String )
495 const auto constSplit = definition->
defaultValue().toString().split(
',' );
496 for (
const QString &var : constSplit )
505 const auto constResultList = resultList;
506 for (
const QVariant &var : constResultList )
508 const int resInt = var.toInt();
509 if ( !enumDef || resInt < enumDef->options().size() )
532 if ( enumText.isEmpty() || !enumDef->
options().contains( enumText ) )
541 return QStringList();
549 return QStringList();
551 const QVariant val = value;
553 QStringList enumValues;
555 std::function< void(
const QVariant &var ) > processVariant;
556 processVariant = [ &enumValues, &context, &definition, &processVariant ](
const QVariant & var )
558 if ( var.type() == QVariant::List )
560 const auto constToList = var.toList();
561 for (
const QVariant &listVar : constToList )
563 processVariant( listVar );
566 else if ( var.type() == QVariant::StringList )
568 const auto constToStringList = var.toStringList();
569 for (
const QString &s : constToStringList )
574 else if ( var.userType() == QMetaType::type(
"QgsProperty" ) )
578 const QStringList parts = var.toString().split(
',' );
579 for (
const QString &s : parts )
586 processVariant( val );
592 const QStringList options = enumDef->
options();
593 const QSet<QString> subtraction = QSet<QString>( enumValues.begin(), enumValues.end() ).subtract( QSet<QString>( options.begin(), options.end() ) );
595 if ( enumValues.isEmpty() || !subtraction.isEmpty() )
628 const QVariant val = value;
629 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
631 else if ( val.isValid() )
644 const QVariant val = value;
645 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
647 else if ( val.isValid() )
655 QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags,
656 const QVariantMap &createOptions,
const QStringList &datasourceOptions,
const QStringList &layerOptions )
661 val = parameters.value( definition->
name() );
664 return parameterAsSink( definition, val, fields, geometryType,
crs, context, destinationIdentifier, sinkFlags, createOptions, datasourceOptions, layerOptions );
667QgsFeatureSink *
QgsProcessingParameters::parameterAsSink(
const QgsProcessingParameterDefinition *definition,
const QVariant &value,
const QgsFields &fields,
Qgis::WkbType geometryType,
const QgsCoordinateReferenceSystem &
crs,
QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags,
const QVariantMap &createOptions,
const QStringList &datasourceOptions,
const QStringList &layerOptions )
669 QVariantMap options = createOptions;
670 QVariant val = value;
675 bool useRemapDefinition =
false;
676 if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
687 useRemapDefinition =
true;
693 if ( definition && val.userType() == QMetaType::type(
"QgsProperty" ) )
697 else if ( !val.isValid() || val.toString().isEmpty() )
713 dest = val.toString();
718 dest = destParam->generateTemporaryDestination( &context );
721 if ( dest.isEmpty() )
724 std::unique_ptr< QgsFeatureSink > sink(
QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType,
crs, options, datasourceOptions, layerOptions, sinkFlags, useRemapDefinition ? &remapDefinition :
nullptr ) );
725 destinationIdentifier = dest;
727 if ( destinationProject )
729 if ( destName.isEmpty() && definition )
735 outputName = definition->
name();
739 return sink.release();
763 QVariant val = parameters.value( definition->
name() );
765 bool selectedFeaturesOnly =
false;
766 long long featureLimit = -1;
767 QString filterExpression;
768 if ( val.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
777 else if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
784 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
790 vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
795 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
799 else if ( !val.isValid() || val.toString().isEmpty() )
805 vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
811 layerRef = val.toString();
816 if ( layerRef.isEmpty() )
828 compatibleFormats, preferredFormat, context, feedback, *layerName, featureLimit, filterExpression );
831 compatibleFormats, preferredFormat, context, feedback, featureLimit, filterExpression );
841 QString *destLayer = layerName;
856 return parameterAsLayer( definition, parameters.value( definition->
name() ), context, layerHint, flags );
864 QVariant val = value;
865 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
870 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
875 if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
887 if ( !val.isValid() || val.toString().isEmpty() )
893 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
898 QString layerRef = val.toString();
899 if ( layerRef.isEmpty() )
902 if ( layerRef.isEmpty() )
933 val = parameters.value( definition->
name() );
940 QVariant val = value;
944 if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
954 if ( definition && val.userType() == QMetaType::type(
"QgsProperty" ) )
958 else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
965 dest = val.toString();
970 dest = destParam->generateTemporaryDestination( &context );
973 if ( destinationProject )
976 if ( destName.isEmpty() && definition )
981 outputName = definition->
name();
1004 val = parameters.value( definition->
name() );
1011 QVariant val = value;
1013 if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1021 if ( definition && val.userType() == QMetaType::type(
"QgsProperty" ) )
1025 else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
1032 dest = val.toString();
1037 dest = destParam->generateTemporaryDestination( &context );
1057 return parameterAsCrs( definition, parameters.value( definition->
name() ), context );
1082 QVariant val = value;
1084 if ( val.userType() == QMetaType::type(
"QgsRectangle" ) )
1088 if ( val.userType() == QMetaType::type(
"QgsGeometry" ) )
1094 if ( val.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
1113 if ( val.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1119 else if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1132 QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1135 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
1138 rectText = val.toString();
1140 if ( rectText.isEmpty() && !layer )
1143 const thread_local QRegularExpression rx( QStringLiteral(
"^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1144 const QRegularExpressionMatch match = rx.match( rectText );
1145 if ( match.hasMatch() )
1147 bool xMinOk =
false;
1148 const double xMin = match.captured( 1 ).toDouble( &xMinOk );
1149 bool xMaxOk =
false;
1150 const double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1151 bool yMinOk =
false;
1152 const double yMin = match.captured( 3 ).toDouble( &yMinOk );
1153 bool yMaxOk =
false;
1154 const double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1155 if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1206 QVariant val = parameters.value( definition->
name() );
1208 if ( val.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
1214 g = g.densifyByCount( 20 );
1228 if ( val.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1234 else if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1247 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
1250 rectText = val.toString();
1252 if ( !rectText.isEmpty() )
1254 const thread_local QRegularExpression rx( QStringLiteral(
"^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1255 const QRegularExpressionMatch match = rx.match( rectText );
1256 if ( match.hasMatch() )
1258 bool xMinOk =
false;
1259 const double xMin = match.captured( 1 ).toDouble( &xMinOk );
1260 bool xMaxOk =
false;
1261 const double xMax = match.captured( 2 ).toDouble( &xMaxOk );
1262 bool yMinOk =
false;
1263 const double yMin = match.captured( 3 ).toDouble( &yMinOk );
1264 bool yMaxOk =
false;
1265 const double yMax = match.captured( 4 ).toDouble( &yMaxOk );
1266 if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
1292 QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
1321 const QVariant val = parameters.value( definition->
name() );
1327 QVariant val = value;
1328 if ( val.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
1337 if ( val.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1343 else if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1355 QString valueAsString;
1356 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
1359 valueAsString = val.toString();
1361 const thread_local QRegularExpression rx( QStringLiteral(
"^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
1363 const QRegularExpressionMatch match = rx.match( valueAsString );
1364 if ( match.hasMatch() )
1371 if ( val.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
1377 else if ( val.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1390 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1391 return layer->crs();
1393 return layer->crs();
1395 if (
auto *lProject = context.
project() )
1396 return lProject->crs();
1414 const QVariant val = value;
1415 if ( val.userType() == QMetaType::type(
"QgsPointXY" ) )
1419 if ( val.userType() == QMetaType::type(
"QgsGeometry" ) )
1425 if ( val.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
1444 if ( pointText.isEmpty() )
1447 if ( pointText.isEmpty() )
1450 const thread_local QRegularExpression rx( QStringLiteral(
"^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1453 const QRegularExpressionMatch match = rx.match( valueAsString );
1454 if ( match.hasMatch() )
1457 const double x = match.captured( 1 ).toDouble( &xOk );
1459 const double y = match.captured( 2 ).toDouble( &yOk );
1487 const QVariant val = parameters.value( definition->
name() );
1493 if ( value.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
1502 const thread_local QRegularExpression rx( QStringLiteral(
"^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
1505 const QRegularExpressionMatch match = rx.match( valueAsString );
1506 if ( match.hasMatch() )
1513 if (
auto *lProject = context.
project() )
1514 return lProject->crs();
1532 const QVariant val = value;
1533 if ( val.userType() == QMetaType::type(
"QgsGeometry" ) )
1538 if ( val.userType() == QMetaType::type(
"QgsPointXY" ) )
1543 if ( val.userType() == QMetaType::type(
"QgsRectangle" ) )
1548 if ( val.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
1566 if ( val.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
1572 g = g.densifyByCount( 20 );
1586 if ( val.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
1605 if ( valueAsString.isEmpty() )
1608 if ( valueAsString.isEmpty() )
1611 const thread_local QRegularExpression rx( QStringLiteral(
"^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1613 const QRegularExpressionMatch match = rx.match( valueAsString );
1614 if ( match.hasMatch() )
1641 const QVariant val = parameters.value( definition->
name() );
1647 if ( value.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
1656 if ( value.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
1665 if ( value.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
1675 const QRegularExpression rx( QStringLiteral(
"^\\s*(?:CRS=(.*);)?(.*?)$" ) );
1678 const QRegularExpressionMatch match = rx.match( valueAsString );
1679 if ( match.hasMatch() )
1686 if (
auto *lProject = context.
project() )
1687 return lProject->crs();
1698 if ( fileText.isEmpty() )
1709 if ( fileText.isEmpty() )
1717 return QVariantList();
1725 return QVariantList();
1727 QString resultString;
1728 const QVariant val = value;
1729 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
1731 else if ( val.type() == QVariant::List )
1732 return val.toList();
1734 resultString = val.toString();
1736 if ( resultString.isEmpty() )
1739 if ( definition->
defaultValue().type() == QVariant::List )
1745 QVariantList result;
1746 const auto constSplit = resultString.split(
',' );
1749 for (
const QString &s : constSplit )
1751 number = s.toDouble( &ok );
1752 result << ( ok ? QVariant( number ) : s );
1761 return QList<QgsMapLayer *>();
1769 return QList<QgsMapLayer *>();
1771 const QVariant val = value;
1772 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
1774 return QList<QgsMapLayer *>() << layer;
1777 QList<QgsMapLayer *> layers;
1779 std::function< void(
const QVariant &var ) > processVariant;
1780 processVariant = [ &layers, &context, &definition, flags, &processVariant](
const QVariant & var )
1782 if ( var.type() == QVariant::List )
1784 const auto constToList = var.toList();
1785 for (
const QVariant &listVar : constToList )
1787 processVariant( listVar );
1790 else if ( var.type() == QVariant::StringList )
1792 const auto constToStringList = var.toStringList();
1793 for (
const QString &s : constToStringList )
1795 processVariant( s );
1798 else if ( var.userType() == QMetaType::type(
"QgsProperty" ) )
1800 else if ( var.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
1804 const QVariant sink = fromVar.
sink;
1805 if ( sink.userType() == QMetaType::type(
"QgsProperty" ) )
1810 else if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1822 processVariant( val );
1824 if ( layers.isEmpty() )
1827 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->
defaultValue() ) ) )
1831 else if ( definition->
defaultValue().type() == QVariant::List )
1833 const auto constToList = definition->
defaultValue().toList();
1834 for (
const QVariant &var : constToList )
1836 if (
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
1842 processVariant( var );
1856 return QStringList();
1858 const QVariant val = value;
1862 std::function< void(
const QVariant &var ) > processVariant;
1863 processVariant = [ &
files, &context, &definition, &processVariant ](
const QVariant & var )
1865 if ( var.type() == QVariant::List )
1867 const auto constToList = var.toList();
1868 for (
const QVariant &listVar : constToList )
1870 processVariant( listVar );
1873 else if ( var.type() == QVariant::StringList )
1875 const auto constToStringList = var.toStringList();
1876 for (
const QString &s : constToStringList )
1878 processVariant( s );
1881 else if ( var.userType() == QMetaType::type(
"QgsProperty" ) )
1885 files << var.toString();
1889 processVariant( val );
1891 if (
files.isEmpty() )
1902 return QStringList();
1910 return QList<double>();
1918 return QList<double>();
1920 QStringList resultStringList;
1921 const QVariant val = value;
1923 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
1925 else if ( val.type() == QVariant::List )
1927 const auto constToList = val.toList();
1928 for (
const QVariant &var : constToList )
1929 resultStringList << var.toString();
1932 resultStringList << val.toString();
1934 if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
1936 resultStringList.clear();
1938 if ( definition->
defaultValue().type() == QVariant::List )
1940 const auto constToList = definition->
defaultValue().toList();
1941 for (
const QVariant &var : constToList )
1942 resultStringList << var.toString();
1945 resultStringList << definition->
defaultValue().toString();
1948 if ( resultStringList.size() == 1 )
1950 resultStringList = resultStringList.at( 0 ).split(
',' );
1953 if ( resultStringList.size() < 2 )
1954 return QList< double >() << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN() ;
1956 QList< double > result;
1958 double n = resultStringList.at( 0 ).toDouble( &ok );
1962 result << std::numeric_limits<double>::quiet_NaN() ;
1964 n = resultStringList.at( 1 ).toDouble( &ok );
1968 result << std::numeric_limits<double>::quiet_NaN() ;
1976 return QStringList();
1989 return QStringList();
1997 return QStringList();
1999 QStringList resultStringList;
2000 const QVariant val = value;
2001 if ( val.isValid() )
2003 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
2005 else if ( val.type() == QVariant::List )
2007 const auto constToList = val.toList();
2008 for (
const QVariant &var : constToList )
2009 resultStringList << var.toString();
2011 else if ( val.type() == QVariant::StringList )
2013 resultStringList = val.toStringList();
2016 resultStringList.append( val.toString().split(
';' ) );
2019 if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
2021 resultStringList.clear();
2025 if ( definition->
defaultValue().type() == QVariant::List )
2027 const auto constToList = definition->
defaultValue().toList();
2028 for (
const QVariant &var : constToList )
2029 resultStringList << var.toString();
2031 else if ( definition->
defaultValue().type() == QVariant::StringList )
2033 resultStringList = definition->
defaultValue().toStringList();
2036 resultStringList.append( definition->
defaultValue().toString().split(
';' ) );
2040 return resultStringList;
2054 if ( layoutName.isEmpty() )
2106 QVariant val = value;
2107 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
2111 if ( val.type() == QVariant::Color )
2113 QColor
c = val.value< QColor >();
2115 if ( !colorParam->opacityEnabled() )
2123 if ( definition->
defaultValue().type() == QVariant::Color )
2129 if ( colorText.isEmpty() )
2132 bool containsAlpha =
false;
2135 if (
c.isValid() && !colorParam->opacityEnabled() )
2207 const QString type = map.value( QStringLiteral(
"parameter_type" ) ).toString();
2208 const QString name = map.value( QStringLiteral(
"name" ) ).toString();
2209 std::unique_ptr< QgsProcessingParameterDefinition > def;
2286 def.reset( paramType->
create( name ) );
2292 def->fromVariantMap( map );
2293 return def.release();
2298 QString desc = name;
2299 desc.replace(
'_',
' ' );
2305 bool isOptional =
false;
2309 if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
2314 if ( type == QLatin1String(
"boolean" ) )
2316 else if ( type == QLatin1String(
"crs" ) )
2318 else if ( type == QLatin1String(
"layer" ) )
2320 else if ( type == QLatin1String(
"extent" ) )
2322 else if ( type == QLatin1String(
"point" ) )
2324 else if ( type == QLatin1String(
"geometry" ) )
2326 else if ( type == QLatin1String(
"file" ) )
2328 else if ( type == QLatin1String(
"folder" ) )
2330 else if ( type == QLatin1String(
"matrix" ) )
2332 else if ( type == QLatin1String(
"multiple" ) )
2334 else if ( type == QLatin1String(
"number" ) )
2336 else if ( type == QLatin1String(
"distance" ) )
2338 else if ( type == QLatin1String(
"duration" ) )
2340 else if ( type == QLatin1String(
"scale" ) )
2342 else if ( type == QLatin1String(
"range" ) )
2344 else if ( type == QLatin1String(
"raster" ) )
2346 else if ( type == QLatin1String(
"enum" ) )
2348 else if ( type == QLatin1String(
"string" ) )
2350 else if ( type == QLatin1String(
"authcfg" ) )
2352 else if ( type == QLatin1String(
"expression" ) )
2354 else if ( type == QLatin1String(
"field" ) )
2356 else if ( type == QLatin1String(
"vector" ) )
2358 else if ( type == QLatin1String(
"source" ) )
2360 else if ( type == QLatin1String(
"sink" ) )
2362 else if ( type == QLatin1String(
"vectordestination" ) )
2364 else if ( type == QLatin1String(
"rasterdestination" ) )
2366 else if ( type == QLatin1String(
"pointclouddestination" ) )
2368 else if ( type == QLatin1String(
"filedestination" ) )
2370 else if ( type == QLatin1String(
"folderdestination" ) )
2372 else if ( type == QLatin1String(
"band" ) )
2374 else if ( type == QLatin1String(
"mesh" ) )
2376 else if ( type == QLatin1String(
"layout" ) )
2378 else if ( type == QLatin1String(
"layoutitem" ) )
2380 else if ( type == QLatin1String(
"color" ) )
2382 else if ( type == QLatin1String(
"coordinateoperation" ) )
2384 else if ( type == QLatin1String(
"maptheme" ) )
2386 else if ( type == QLatin1String(
"datetime" ) )
2388 else if ( type == QLatin1String(
"providerconnection" ) )
2390 else if ( type == QLatin1String(
"databaseschema" ) )
2392 else if ( type == QLatin1String(
"databasetable" ) )
2394 else if ( type == QLatin1String(
"pointcloud" ) )
2396 else if ( type == QLatin1String(
"annotation" ) )
2398 else if ( type == QLatin1String(
"attribute" ) )
2400 else if ( type == QLatin1String(
"vectortiledestination" ) )
2406bool QgsProcessingParameters::parseScriptCodeParameterOptions(
const QString &code,
bool &isOptional, QString &name, QString &type, QString &definition )
2408 const thread_local QRegularExpression re( QStringLiteral(
"(?:#*)(.*?)=\\s*(.*)" ) );
2409 QRegularExpressionMatch m = re.match( code );
2410 if ( !m.hasMatch() )
2413 name = m.captured( 1 );
2414 QString tokens = m.captured( 2 );
2415 if ( tokens.startsWith( QLatin1String(
"optional" ), Qt::CaseInsensitive ) )
2418 tokens.remove( 0, 8 );
2425 tokens = tokens.trimmed();
2427 const thread_local QRegularExpression re2( QStringLiteral(
"(.*?)\\s+(.*)" ) );
2428 m = re2.match( tokens );
2429 if ( !m.hasMatch() )
2431 type = tokens.toLower().trimmed();
2436 type = m.captured( 1 ).toLower().trimmed();
2437 definition = m.captured( 2 );
2448 , mDescription( description )
2450 , mDefault( defaultValue )
2451 , mFlags( optional ? FlagOptional : 0 )
2456 if ( !input.isValid() && !
mDefault.isValid() )
2459 if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
2460 || ( !input.isValid() &&
mDefault.type() == QVariant::String &&
mDefault.toString().isEmpty() ) )
2468 if ( !value.isValid() )
2469 return QStringLiteral(
"None" );
2471 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
2472 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
2484 if ( !value.isValid() )
2488 if ( value.type() == QVariant::Type::Map )
2490 const QVariantMap sourceMap = value.toMap();
2491 QVariantMap resultMap;
2492 for (
auto it = sourceMap.constBegin(); it != sourceMap.constEnd(); it++ )
2498 else if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList )
2500 const QVariantList sourceList = value.toList();
2501 QVariantList resultList;
2502 resultList.reserve( sourceList.size() );
2503 for (
const QVariant &v : sourceList )
2511 switch ( value.userType() )
2514 case QMetaType::Bool:
2515 case QMetaType::Char:
2516 case QMetaType::Int:
2517 case QMetaType::Double:
2518 case QMetaType::Float:
2519 case QMetaType::LongLong:
2520 case QMetaType::ULongLong:
2521 case QMetaType::UInt:
2522 case QMetaType::ULong:
2523 case QMetaType::UShort:
2530 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
2540 return QVariantMap( {{QStringLiteral(
"type" ), QStringLiteral(
"data_defined" )}, {QStringLiteral(
"field" ), prop.
field() }} );
2542 return QVariantMap( {{QStringLiteral(
"type" ), QStringLiteral(
"data_defined" )}, {QStringLiteral(
"expression" ), prop.
expressionString() }} );
2547 if ( value.userType() == QMetaType::type(
"QgsCoordinateReferenceSystem" ) )
2557 else if ( value.userType() == QMetaType::type(
"QgsRectangle" ) )
2565 else if ( value.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
2574 else if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
2586 else if ( value.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
2601 else if ( value.userType() == QMetaType::type(
"QgsPointXY" ) )
2607 else if ( value.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
2614 else if ( value.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
2621 else if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
2626 else if ( value.userType() == QMetaType::type(
"QColor" ) )
2628 const QColor fromVar = value.value< QColor >();
2629 if ( !fromVar.isValid() )
2632 return QStringLiteral(
"rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(),
'f', 2 ) );
2634 else if ( value.userType() == QMetaType::type(
"QDateTime" ) )
2636 const QDateTime fromVar = value.toDateTime();
2637 if ( !fromVar.isValid() )
2640 return fromVar.toString( Qt::ISODate );
2642 else if ( value.userType() == QMetaType::type(
"QDate" ) )
2644 const QDate fromVar = value.toDate();
2645 if ( !fromVar.isValid() )
2648 return fromVar.toString( Qt::ISODate );
2650 else if ( value.userType() == QMetaType::type(
"QTime" ) )
2652 const QTime fromVar = value.toTime();
2653 if ( !fromVar.isValid() )
2656 return fromVar.toString( Qt::ISODate );
2663 p.insert(
name(), value );
2667 if ( !source.isEmpty() )
2674 if ( value.userType() == QMetaType::QString )
2679 Q_ASSERT_X(
false,
"QgsProcessingParameterDefinition::valueAsJsonObject", QStringLiteral(
"unsupported variant type %1" ).arg(
QMetaType::typeName( value.userType() ) ).toLocal8Bit() );
2692 if ( !value.isValid() )
2695 switch ( value.userType() )
2698 case QMetaType::Bool:
2699 case QMetaType::Char:
2700 case QMetaType::Int:
2701 case QMetaType::Double:
2702 case QMetaType::Float:
2703 case QMetaType::LongLong:
2704 case QMetaType::ULongLong:
2705 case QMetaType::UInt:
2706 case QMetaType::ULong:
2707 case QMetaType::UShort:
2708 return value.toString();
2714 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
2724 return QStringLiteral(
"field:%1" ).arg( prop.
field() );
2731 if ( value.userType() == QMetaType::type(
"QgsCoordinateReferenceSystem" ) )
2741 else if ( value.userType() == QMetaType::type(
"QgsRectangle" ) )
2749 else if ( value.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
2757 else if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
2769 else if ( value.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
2784 else if ( value.userType() == QMetaType::type(
"QgsPointXY" ) )
2790 else if ( value.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
2797 else if ( value.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
2802 else if ( value.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
2807 else if ( value.userType() == QMetaType::type(
"QColor" ) )
2809 const QColor fromVar = value.value< QColor >();
2810 if ( !fromVar.isValid() )
2813 return QStringLiteral(
"rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(),
'f', 2 ) );
2815 else if ( value.userType() == QMetaType::type(
"QDateTime" ) )
2817 const QDateTime fromVar = value.toDateTime();
2818 if ( !fromVar.isValid() )
2821 return fromVar.toString( Qt::ISODate );
2823 else if ( value.userType() == QMetaType::type(
"QDate" ) )
2825 const QDate fromVar = value.toDate();
2826 if ( !fromVar.isValid() )
2829 return fromVar.toString( Qt::ISODate );
2831 else if ( value.userType() == QMetaType::type(
"QTime" ) )
2833 const QTime fromVar = value.toTime();
2834 if ( !fromVar.isValid() )
2837 return fromVar.toString( Qt::ISODate );
2844 p.insert(
name(), value );
2848 if ( !source.isEmpty() )
2855 if ( value.userType() == QMetaType::QString )
2856 return value.toString();
2861 return value.toString();
2867 if ( !value.isValid( ) )
2868 return QStringList();
2870 if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList )
2872 const QVariantList sourceList = value.toList();
2873 QStringList resultList;
2874 resultList.reserve( sourceList.size() );
2875 for (
const QVariant &v : sourceList )
2884 return QStringList();
2896 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
2898 code += QLatin1String(
"optional " );
2899 code +=
type() +
' ';
2901 return code.trimmed();
2909 switch ( outputType )
2913 QString code = t->className() + QStringLiteral(
"('%1', %2" )
2916 code += QLatin1String(
", optional=True" );
2932 map.insert( QStringLiteral(
"parameter_type" ),
type() );
2933 map.insert( QStringLiteral(
"name" ),
mName );
2934 map.insert( QStringLiteral(
"description" ),
mDescription );
2935 map.insert( QStringLiteral(
"help" ),
mHelp );
2936 map.insert( QStringLiteral(
"default" ),
mDefault );
2937 map.insert( QStringLiteral(
"defaultGui" ),
mGuiDefault );
2938 map.insert( QStringLiteral(
"flags" ),
static_cast< int >(
mFlags ) );
2939 map.insert( QStringLiteral(
"metadata" ),
mMetadata );
2945 mName = map.value( QStringLiteral(
"name" ) ).toString();
2946 mDescription = map.value( QStringLiteral(
"description" ) ).toString();
2947 mHelp = map.value( QStringLiteral(
"help" ) ).toString();
2948 mDefault = map.value( QStringLiteral(
"default" ) );
2949 mGuiDefault = map.value( QStringLiteral(
"defaultGui" ) );
2950 mFlags =
static_cast< Flags
>( map.value( QStringLiteral(
"flags" ) ).toInt() );
2951 mMetadata = map.value( QStringLiteral(
"metadata" ) ).toMap();
2967 QString text = QStringLiteral(
"<p><b>%1</b></p>" ).arg(
description() );
2968 if ( !
help().isEmpty() )
2970 text += QStringLiteral(
"<p>%1</p>" ).arg(
help() );
2972 text += QStringLiteral(
"<p>%1</p>" ).arg( QObject::tr(
"Python identifier: ‘%1’" ).arg( QStringLiteral(
"<i>%1</i>" ).arg(
name() ) ) );
2987 if ( !val.isValid() )
2988 return QStringLiteral(
"None" );
2990 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
2992 return val.toBool() ? QStringLiteral(
"True" ) : QStringLiteral(
"False" );
2997 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
2999 code += QLatin1String(
"optional " );
3000 code +=
type() +
' ';
3001 code +=
mDefault.toBool() ? QStringLiteral(
"true" ) : QStringLiteral(
"false" );
3002 return code.trimmed();
3023 if ( !input.isValid() )
3026 if ( input.userType() == QMetaType::type(
"QgsCoordinateReferenceSystem" ) )
3030 else if ( input.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
3034 else if ( input.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
3039 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
3045 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3048 if ( input.type() != QVariant::String || input.toString().isEmpty() )
3056 if ( !value.isValid() )
3057 return QStringLiteral(
"None" );
3059 if ( value.userType() == QMetaType::type(
"QgsCoordinateReferenceSystem" ) )
3062 return QStringLiteral(
"QgsCoordinateReferenceSystem()" );
3067 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
3068 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
3071 p.insert(
name(), value );
3108 if ( !input.isValid() )
3111 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
3116 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3121 if ( input.type() != QVariant::String || input.toString().isEmpty() )
3139 if ( !val.isValid() )
3140 return QStringLiteral(
"None" );
3142 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
3146 p.insert(
name(), val );
3166 for (
const QString &raster : rasters )
3168 if ( !vectors.contains( raster ) )
3172 for (
const QString &mesh : meshFilters )
3174 if ( !vectors.contains( mesh ) )
3178 for (
const QString &pointCloud : pointCloudFilters )
3180 if ( !vectors.contains( pointCloud ) )
3181 vectors << pointCloud;
3183 vectors.removeAll( QObject::tr(
"All files (*.*)" ) );
3184 std::sort( vectors.begin(), vectors.end() );
3186 return QObject::tr(
"All files (*.*)" ) + QStringLiteral(
";;" ) + vectors.join( QLatin1String(
";;" ) );
3196 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
3198 code += QLatin1String(
"optional " );
3199 code += QLatin1String(
"layer " );
3206 code += QLatin1String(
"hasgeometry " );
3210 code += QLatin1String(
"point " );
3214 code += QLatin1String(
"line " );
3218 code += QLatin1String(
"polygon " );
3222 code += QLatin1String(
"raster " );
3226 code += QLatin1String(
"mesh " );
3230 code += QLatin1String(
"plugin " );
3234 code += QLatin1String(
"pointcloud " );
3238 code += QLatin1String(
"annotation " );
3244 return code.trimmed();
3250 QString def = definition;
3253 if ( def.startsWith( QLatin1String(
"hasgeometry" ), Qt::CaseInsensitive ) )
3256 def = def.mid( 12 );
3259 else if ( def.startsWith( QLatin1String(
"point" ), Qt::CaseInsensitive ) )
3265 else if ( def.startsWith( QLatin1String(
"line" ), Qt::CaseInsensitive ) )
3271 else if ( def.startsWith( QLatin1String(
"polygon" ), Qt::CaseInsensitive ) )
3277 else if ( def.startsWith( QLatin1String(
"raster" ), Qt::CaseInsensitive ) )
3283 else if ( def.startsWith( QLatin1String(
"mesh" ), Qt::CaseInsensitive ) )
3289 else if ( def.startsWith( QLatin1String(
"plugin" ), Qt::CaseInsensitive ) )
3295 else if ( def.startsWith( QLatin1String(
"pointcloud" ), Qt::CaseInsensitive ) )
3298 def = def.mid( 11 );
3301 else if ( def.startsWith( QLatin1String(
"annotation" ), Qt::CaseInsensitive ) )
3304 def = def.mid( 11 );
3315 switch ( outputType )
3319 QString code = QStringLiteral(
"QgsProcessingParameterMapLayer('%1', %2" )
3322 code += QLatin1String(
", optional=True" );
3329 QStringList options;
3333 code += QStringLiteral(
", types=[%1])" ).arg( options.join(
',' ) );
3337 code += QLatin1Char(
')' );
3354 map.insert( QStringLiteral(
"data_types" ), types );
3362 const QVariantList values = map.value( QStringLiteral(
"data_types" ) ).toList();
3363 for (
const QVariant &val : values )
3383 if ( !input.isValid() )
3386 if ( input.userType() == QMetaType::type(
"QgsProcessingFeatureSourceDefinition" ) )
3390 else if ( input.userType() == QMetaType::type(
"QgsProcessingOutputLayerDefinition" ) )
3395 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
3400 if ( input.userType() == QMetaType::type(
"QgsRectangle" ) )
3405 if ( input.userType() == QMetaType::type(
"QgsGeometry" ) )
3409 if ( input.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
3416 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
3419 if ( input.type() != QVariant::String || input.toString().isEmpty() )
3428 const thread_local QRegularExpression rx( QStringLiteral(
"^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
3429 const QRegularExpressionMatch match = rx.match( input.toString() );
3430 if ( match.hasMatch() )
3432 bool xMinOk =
false;
3433 ( void )match.captured( 1 ).toDouble( &xMinOk );
3434 bool xMaxOk =
false;
3435 ( void )match.captured( 2 ).toDouble( &xMaxOk );
3436 bool yMinOk =
false;
3437 ( void )match.captured( 3 ).toDouble( &yMinOk );
3438 bool yMaxOk =
false;
3439 ( void )match.captured( 4 ).toDouble( &yMaxOk );
3440 if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
3450 if ( !value.isValid() )
3451 return QStringLiteral(
"None" );
3453 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
3454 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
3456 if ( value.userType() == QMetaType::type(
"QgsRectangle" ) )
3464 else if ( value.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
3472 else if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
3477 const QString wkt = g.
asWkt();
3478 return QStringLiteral(
"QgsGeometry.fromWkt('%1')" ).arg( wkt );
3483 p.insert(
name(), value );
3519 if ( !input.isValid() )
3522 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
3527 if ( input.userType() == QMetaType::type(
"QgsPointXY" ) )
3531 if ( input.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
3535 if ( input.userType() == QMetaType::type(
"QgsGeometry" ) )
3540 if ( input.type() == QVariant::String )
3542 if ( input.toString().isEmpty() )
3546 const thread_local QRegularExpression rx( QStringLiteral(
"^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
3548 const QRegularExpressionMatch match = rx.match( input.toString() );
3549 if ( match.hasMatch() )
3552 ( void )match.captured( 1 ).toDouble( &xOk );
3554 ( void )match.captured( 2 ).toDouble( &yOk );
3563 if ( !value.isValid() )
3564 return QStringLiteral(
"None" );
3566 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
3567 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
3569 if ( value.userType() == QMetaType::type(
"QgsPointXY" ) )
3575 else if ( value.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
3582 else if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
3587 const QString wkt = g.
asWkt();
3588 return QStringLiteral(
"QgsGeometry.fromWkt('%1')" ).arg( wkt );
3601 const QVariant &defaultValue,
bool optional,
const QList<int> &geometryTypes,
bool allowMultipart )
3603 mGeomTypes( geometryTypes ),
3604 mAllowMultipart( allowMultipart )
3616 if ( !input.isValid() )
3619 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
3624 const bool anyTypeAllowed = mGeomTypes.isEmpty() || mGeomTypes.contains(
static_cast< int >( Qgis::GeometryType::Unknown ) );
3626 if ( input.userType() == QMetaType::type(
"QgsGeometry" ) )
3628 return ( anyTypeAllowed || mGeomTypes.contains(
static_cast< int >( input.value<
QgsGeometry>().
type() ) ) ) &&
3629 ( mAllowMultipart || !input.value<
QgsGeometry>().isMultipart() );
3632 if ( input.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
3638 if ( input.userType() == QMetaType::type(
"QgsPointXY" ) )
3640 return anyTypeAllowed || mGeomTypes.contains(
static_cast< int >( Qgis::GeometryType::Point ) );
3643 if ( input.userType() == QMetaType::type(
"QgsRectangle" ) )
3645 return anyTypeAllowed || mGeomTypes.contains(
static_cast< int >( Qgis::GeometryType::Polygon ) );
3648 if ( input.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
3650 return anyTypeAllowed || mGeomTypes.contains(
static_cast< int >( Qgis::GeometryType::Point ) );
3653 if ( input.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
3655 return anyTypeAllowed || mGeomTypes.contains(
static_cast< int >( Qgis::GeometryType::Polygon ) );
3658 if ( input.type() == QVariant::String )
3660 if ( input.toString().isEmpty() )
3665 const thread_local QRegularExpression rx( QStringLiteral(
"^\\s*(?:CRS=(.*);)?(.*?)$" ) );
3667 const QRegularExpressionMatch match = rx.match( input.toString() );
3668 if ( match.hasMatch() )
3673 return ( anyTypeAllowed || mGeomTypes.contains(
static_cast< int >( g.
type() ) ) ) && ( mAllowMultipart || !g.
isMultipart() );
3693 if ( !value.isValid() )
3694 return QStringLiteral(
"None" );
3696 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
3699 if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
3706 if ( value.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
3713 if ( value.userType() == QMetaType::type(
"QgsPointXY" ) )
3720 if ( value.userType() == QMetaType::type(
"QgsReferencedPointXY" ) )
3727 if ( value.userType() == QMetaType::type(
"QgsRectangle" ) )
3734 if ( value.userType() == QMetaType::type(
"QgsReferencedRectangle" ) )
3746 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
3748 code += QLatin1String(
"optional " );
3749 code +=
type() +
' ';
3751 for (
const int type : mGeomTypes )
3755 case Qgis::GeometryType::Point:
3756 code += QLatin1String(
"point " );
3759 case Qgis::GeometryType::Line:
3760 code += QLatin1String(
"line " );
3763 case Qgis::GeometryType::Polygon:
3764 code += QLatin1String(
"polygon " );
3768 code += QLatin1String(
"unknown " );
3774 return code.trimmed();
3779 switch ( outputType )
3783 QString code = QStringLiteral(
"QgsProcessingParameterGeometry('%1', %2" )
3786 code += QLatin1String(
", optional=True" );
3788 if ( !mGeomTypes.empty() )
3794 case Qgis::GeometryType::Point:
3795 return QStringLiteral(
"PointGeometry" );
3797 case Qgis::GeometryType::Line:
3798 return QStringLiteral(
"LineGeometry" );
3800 case Qgis::GeometryType::Polygon:
3801 return QStringLiteral(
"PolygonGeometry" );
3803 case Qgis::GeometryType::Unknown:
3804 return QStringLiteral(
"UnknownGeometry" );
3806 case Qgis::GeometryType::Null:
3807 return QStringLiteral(
"NullGeometry" );
3812 QStringList options;
3813 options.reserve( mGeomTypes.size() );
3814 for (
const int type : mGeomTypes )
3816 options << QStringLiteral(
" QgsWkbTypes.%1" ).arg( geomTypeToString(
static_cast<Qgis::GeometryType>(
type ) ) );
3818 code += QStringLiteral(
", geometryTypes=[%1 ]" ).arg( options.join(
',' ) );
3821 if ( ! mAllowMultipart )
3823 code += QLatin1String(
", allowMultipart=False" );
3838 for (
const int type : mGeomTypes )
3842 map.insert( QStringLiteral(
"geometrytypes" ), types );
3843 map.insert( QStringLiteral(
"multipart" ), mAllowMultipart );
3851 const QVariantList values = map.value( QStringLiteral(
"geometrytypes" ) ).toList();
3852 for (
const QVariant &val : values )
3854 mGeomTypes << val.toInt();
3856 mAllowMultipart = map.value( QStringLiteral(
"multipart" ) ).toBool();
3867 , mBehavior( behavior )
3868 , mExtension( fileFilter.isEmpty() ? extension : QString() )
3869 , mFileFilter( fileFilter.isEmpty() && extension.isEmpty() ? QObject::tr(
"All files (*.*)" ) : fileFilter )
3881 if ( !input.isValid() )
3884 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
3889 const QString
string = input.toString().trimmed();
3891 if ( input.type() != QVariant::String ||
string.isEmpty() )
3894 switch ( mBehavior )
3898 if ( !mExtension.isEmpty() )
3900 return string.endsWith( mExtension, Qt::CaseInsensitive );
3902 else if ( !mFileFilter.isEmpty() )
3920 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
3922 code += QLatin1String(
"optional " );
3923 code += ( mBehavior ==
File ? QStringLiteral(
"file" ) : QStringLiteral(
"folder" ) ) +
' ';
3925 return code.trimmed();
3930 switch ( outputType )
3935 QString code = QStringLiteral(
"QgsProcessingParameterFile('%1', %2" )
3938 code += QLatin1String(
", optional=True" );
3939 code += QStringLiteral(
", behavior=%1" ).arg( mBehavior ==
File ? QStringLiteral(
"QgsProcessingParameterFile.File" ) : QStringLiteral(
"QgsProcessingParameterFile.Folder" ) );
3940 if ( !mExtension.isEmpty() )
3941 code += QStringLiteral(
", extension='%1'" ).arg( mExtension );
3942 if ( !mFileFilter.isEmpty() )
3943 code += QStringLiteral(
", fileFilter='%1'" ).arg( mFileFilter );
3954 switch ( mBehavior )
3958 if ( !mFileFilter.isEmpty() )
3959 return mFileFilter != QObject::tr(
"All files (*.*)" ) ? mFileFilter + QStringLiteral(
";;" ) + QObject::tr(
"All files (*.*)" ) : mFileFilter;
3960 else if ( !mExtension.isEmpty() )
3961 return QObject::tr(
"%1 files" ).arg( mExtension.toUpper() ) + QStringLiteral(
" (*." ) + mExtension.toLower() + QStringLiteral(
");;" ) + QObject::tr(
"All files (*.*)" );
3963 return QObject::tr(
"All files (*.*)" );
3975 mFileFilter.clear();
3985 mFileFilter = filter;
3992 map.insert( QStringLiteral(
"behavior" ), mBehavior );
3993 map.insert( QStringLiteral(
"extension" ), mExtension );
3994 map.insert( QStringLiteral(
"filefilter" ), mFileFilter );
4001 mBehavior =
static_cast< Behavior >( map.value( QStringLiteral(
"behavior" ) ).toInt() );
4002 mExtension = map.value( QStringLiteral(
"extension" ) ).toString();
4003 mFileFilter = map.value( QStringLiteral(
"filefilter" ) ).toString();
4014 , mHeaders( headers )
4015 , mNumberRows( numberRows )
4016 , mFixedNumberRows( fixedNumberRows )
4028 if ( !input.isValid() )
4031 if ( input.type() == QVariant::String )
4033 if ( input.toString().isEmpty() )
4037 else if ( input.type() == QVariant::List )
4039 if ( input.toList().isEmpty() )
4043 else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
4053 if ( !value.isValid() )
4054 return QStringLiteral(
"None" );
4056 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
4057 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
4060 p.insert(
name(), value );
4068 switch ( outputType )
4072 QString code = QStringLiteral(
"QgsProcessingParameterMatrix('%1', %2" )
4075 code += QLatin1String(
", optional=True" );
4076 code += QStringLiteral(
", numberRows=%1" ).arg( mNumberRows );
4077 code += QStringLiteral(
", hasFixedNumberRows=%1" ).arg( mFixedNumberRows ? QStringLiteral(
"True" ) : QStringLiteral(
"False" ) );
4080 headers.reserve( mHeaders.size() );
4081 for (
const QString &h : mHeaders )
4083 code += QStringLiteral(
", headers=[%1]" ).arg(
headers.join(
',' ) );
4115 return mFixedNumberRows;
4120 mFixedNumberRows = fixedNumberRows;
4126 map.insert( QStringLiteral(
"headers" ), mHeaders );
4127 map.insert( QStringLiteral(
"rows" ), mNumberRows );
4128 map.insert( QStringLiteral(
"fixed_number_rows" ), mFixedNumberRows );
4135 mHeaders = map.value( QStringLiteral(
"headers" ) ).toStringList();
4136 mNumberRows = map.value( QStringLiteral(
"rows" ) ).toInt();
4137 mFixedNumberRows = map.value( QStringLiteral(
"fixed_number_rows" ) ).toBool();
4148 , mLayerType( layerType )
4160 if ( !input.isValid() )
4165 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
4171 if ( input.type() == QVariant::String )
4173 if ( input.toString().isEmpty() )
4176 if ( mMinimumNumberInputs > 1 )
4187 else if ( input.type() == QVariant::List )
4189 if ( input.toList().count() < mMinimumNumberInputs )
4192 if ( mMinimumNumberInputs > input.toList().count() )
4200 const auto constToList = input.toList();
4201 for (
const QVariant &v : constToList )
4203 if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
4212 else if ( input.type() == QVariant::StringList )
4214 if ( input.toStringList().count() < mMinimumNumberInputs )
4217 if ( mMinimumNumberInputs > input.toStringList().count() )
4225 const auto constToStringList = input.toStringList();
4226 for (
const QString &v : constToStringList )
4239 if ( !value.isValid() )
4240 return QStringLiteral(
"None" );
4242 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
4243 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
4248 if ( value.type() == QVariant::StringList )
4250 const QStringList list = value.toStringList();
4251 parts.reserve( list.count() );
4252 for (
const QString &v : list )
4255 else if ( value.type() == QVariant::List )
4257 const QVariantList list = value.toList();
4258 parts.reserve( list.count() );
4259 for (
const QVariant &v : list )
4262 if ( !parts.isEmpty() )
4263 return parts.join(
',' ).prepend(
'[' ).append(
']' );
4268 p.insert(
name(), value );
4270 if ( !list.isEmpty() )
4273 parts.reserve( list.count() );
4278 return parts.join(
',' ).prepend(
'[' ).append(
']' );
4297 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
4299 code += QLatin1String(
"optional " );
4300 switch ( mLayerType )
4303 code += QLatin1String(
"multiple raster" );
4307 code += QLatin1String(
"multiple file" );
4311 code += QLatin1String(
"multiple vector" );
4315 if (
mDefault.type() == QVariant::List )
4318 const auto constToList =
mDefault.toList();
4319 for (
const QVariant &var : constToList )
4321 parts << var.toString();
4323 code += parts.join(
',' );
4325 else if (
mDefault.type() == QVariant::StringList )
4327 code +=
mDefault.toStringList().join(
',' );
4333 return code.trimmed();
4338 switch ( outputType )
4342 QString code = QStringLiteral(
"QgsProcessingParameterMultipleLayers('%1', %2" )
4345 code += QLatin1String(
", optional=True" );
4349 code += QStringLiteral(
", layerType=%1" ).arg(
layerType );
4360 switch ( mLayerType )
4363 return QObject::tr(
"All files (*.*)" );
4402 return mMinimumNumberInputs;
4414 map.insert( QStringLiteral(
"layer_type" ), mLayerType );
4415 map.insert( QStringLiteral(
"min_inputs" ), mMinimumNumberInputs );
4423 mMinimumNumberInputs = map.value( QStringLiteral(
"min_inputs" ) ).toInt();
4429 QString
type = definition;
4431 const thread_local QRegularExpression re( QStringLiteral(
"(.*?)\\s+(.*)" ) );
4432 const QRegularExpressionMatch m = re.match( definition );
4435 type = m.captured( 1 ).toLower().trimmed();
4436 defaultVal = m.captured( 2 );
4439 if (
type == QLatin1String(
"vector" ) )
4441 else if (
type == QLatin1String(
"raster" ) )
4443 else if (
type == QLatin1String(
"file" ) )
4456 QgsMessageLog::logMessage( QObject::tr(
"Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg(
name ).arg( mMin ).arg( mMax ), QObject::tr(
"Processing" ) );
4467 QVariant input = value;
4468 if ( !input.isValid() )
4476 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
4482 const double res = input.toDouble( &ok );
4486 return !( res < mMin || res > mMax );
4491 if ( !value.isValid() )
4492 return QStringLiteral(
"None" );
4494 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
4495 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
4497 return value.toString();
4504 if ( mMin > std::numeric_limits<double>::lowest() + 1 )
4505 parts << QObject::tr(
"Minimum value: %1" ).arg( mMin );
4506 if ( mMax < std::numeric_limits<double>::max() )
4507 parts << QObject::tr(
"Maximum value: %1" ).arg( mMax );
4509 parts << QObject::tr(
"Default value: %1" ).arg( mDataType ==
Integer ?
mDefault.toInt() :
mDefault.toDouble() );
4510 const QString extra = parts.join( QLatin1String(
"<br />" ) );
4511 if ( !extra.isEmpty() )
4512 text += QStringLiteral(
"<p>%1</p>" ).arg( extra );
4518 switch ( outputType )
4522 QString code = QStringLiteral(
"QgsProcessingParameterNumber('%1', %2" )
4525 code += QLatin1String(
", optional=True" );
4527 code += QStringLiteral(
", type=%1" ).arg( mDataType ==
Integer ? QStringLiteral(
"QgsProcessingParameterNumber.Integer" ) : QStringLiteral(
"QgsProcessingParameterNumber.Double" ) );
4529 if ( mMin != std::numeric_limits<double>::lowest() + 1 )
4530 code += QStringLiteral(
", minValue=%1" ).arg( mMin );
4531 if ( mMax != std::numeric_limits<double>::max() )
4532 code += QStringLiteral(
", maxValue=%1" ).arg( mMax );
4574 map.insert( QStringLiteral(
"min" ), mMin );
4575 map.insert( QStringLiteral(
"max" ), mMax );
4576 map.insert( QStringLiteral(
"data_type" ), mDataType );
4583 mMin = map.value( QStringLiteral(
"min" ) ).toDouble();
4584 mMax = map.value( QStringLiteral(
"max" ) ).toDouble();
4585 mDataType =
static_cast< Type >( map.value( QStringLiteral(
"data_type" ) ).toInt() );
4592 : ( definition.toLower().trimmed() == QLatin1String(
"none" ) ? QVariant() : definition ), isOptional );
4609 if ( !input.isValid() )
4612 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
4617 if ( input.type() == QVariant::String )
4619 const QStringList list = input.toString().split(
',' );
4620 if ( list.count() != 2 )
4623 list.at( 0 ).toDouble( &ok );
4625 list.at( 1 ).toDouble( &ok2 );
4630 else if ( input.type() == QVariant::List )
4632 if ( input.toList().count() != 2 )
4636 input.toList().at( 0 ).toDouble( &ok );
4638 input.toList().at( 1 ).toDouble( &ok2 );
4649 if ( !value.isValid() )
4650 return QStringLiteral(
"None" );
4652 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
4653 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
4656 p.insert(
name(), value );
4659 QStringList stringParts;
4660 const auto constParts = parts;
4661 for (
const double v : constParts )
4663 stringParts << QString::number( v );
4665 return stringParts.join(
',' ).prepend(
'[' ).append(
']' );
4670 switch ( outputType )
4674 QString code = QStringLiteral(
"QgsProcessingParameterRange('%1', %2" )
4677 code += QLatin1String(
", optional=True" );
4679 code += QStringLiteral(
", type=%1" ).arg( mDataType ==
QgsProcessingParameterNumber::Integer ? QStringLiteral(
"QgsProcessingParameterNumber.Integer" ) : QStringLiteral(
"QgsProcessingParameterNumber.Double" ) );
4702 map.insert( QStringLiteral(
"data_type" ), mDataType );
4716 : ( definition.toLower().trimmed() == QLatin1String(
"none" ) ? QVariant() : definition ), isOptional );
4732 if ( !input.isValid() )
4735 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
4740 if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
4743 if ( input.type() != QVariant::String || input.toString().isEmpty() )
4761 if ( !val.isValid() )
4762 return QStringLiteral(
"None" );
4764 if ( val.userType() == QMetaType::type(
"QgsProperty" ) )
4768 p.insert(
name(), val );
4796 , mOptions( options )
4797 , mAllowMultiple( allowMultiple )
4798 , mUsesStaticStrings( usesStaticStrings )
4810 QVariant input = value;
4811 if ( !input.isValid() )
4819 if ( input.userType() == QMetaType::type(
"QgsProperty" ) )
4824 if ( mUsesStaticStrings )
4826 if ( input.type() == QVariant::List )
4828 if ( !mAllowMultiple )
4831 const QVariantList values = input.toList();
4835 for (
const QVariant &val : values )
4837 if ( !mOptions.contains( val.toString() ) )
4843 else if ( input.type() == QVariant::StringList )
4845 if ( !mAllowMultiple )
4848 const QStringList values = input.toStringList();
4853 if ( values.count() > 1 && !mAllowMultiple )
4856 for (
const QString &val : values )
4858 if ( !mOptions.contains( val ) )
4863 else if ( input.type() == QVariant::String )
4865 const QStringList parts = input.toString().split(
',' );
4866 if ( parts.count() > 1 && !mAllowMultiple )
4869 const auto constParts = parts;
4870 for (
const QString &part : constParts )
4872 if ( !mOptions.contains( part ) )
4880 if ( input.type() == QVariant::List )
4882 if ( !mAllowMultiple )
4885 const QVariantList values = input.toList();
4889 for (
const QVariant &val : values )
4892 const int res = val.toInt( &ok );
4895 else if ( res < 0 || res >= mOptions.count() )
4901 else if ( input.type() == QVariant::String )
4903 const QStringList parts = input.toString().split(
',' );
4904 if ( parts.count() > 1 && !mAllowMultiple )
4907 const auto constParts = parts;
4908 for (
const QString &part : constParts )
4911 const int res = part.toInt( &ok );
4914 else if ( res < 0 || res >= mOptions.count() )
4919 else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
4922 const int res = input.toInt( &ok );
4925 else if ( res >= 0 && res < mOptions.count() )
4935 if ( !value.isValid() )
4936 return QStringLiteral(
"None" );
4938 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
4939 return QStringLiteral(
"QgsProperty.fromExpression('%1')" ).arg( value.value<
QgsProperty >().
asExpression() );
4941 if ( mUsesStaticStrings )
4943 if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
4946 const QStringList constList = value.toStringList();
4947 for (
const QString &val : constList )
4951 return parts.join(
',' ).prepend(
'[' ).append(
']' );
4953 else if ( value.type() == QVariant::String )
4956 const QStringList constList = value.toString().split(
',' );
4957 if ( constList.count() > 1 )
4959 for (
const QString &val : constList )
4963 return parts.join(
',' ).prepend(
'[' ).append(
']' );
4971 if ( value.type() == QVariant::List )
4974 const auto constToList = value.toList();
4975 for (
const QVariant &val : constToList )
4977 parts << QString::number( static_cast< int >( val.toDouble() ) );
4979 return parts.join(
',' ).prepend(
'[' ).append(
']' );
4981 else if ( value.type() == QVariant::String )
4983 const QStringList parts = value.toString().split(
',' );
4984 if ( parts.count() > 1 )
4986 return parts.join(
',' ).prepend(
'[' ).append(
']' );
4990 return QString::number(
static_cast< int >( value.toDouble() ) );
4996 if ( !value.isValid() )
4999 if ( value.userType() == QMetaType::type(
"QgsProperty" ) )
5002 if ( mUsesStaticStrings )
5008 if ( value.type() == QVariant::List )
5011 const QVariantList toList = value.toList();
5012 parts.reserve( toList.size() );
5013 for (
const QVariant &val : toList )
5015 parts << mOptions.value(
static_cast< int >( val.toDouble() ) );
5017 return parts.join(
',' );
5019 else if ( value.type() == QVariant::String )
5021 const QStringList parts = value.toString().split(
',' );
5022 QStringList comments;
5023 if ( parts.count() > 1 )
5025 for (
const QString &part : parts )
5028 const int val = part.toInt( &ok );
5030 comments << mOptions.value( val );
5032 return comments.join(
',' );
5036 return mOptions.value(
static_cast< int >( value.toDouble() ) );
5042 QString code = QStringLiteral(
"##%1=" ).arg(
mName );
5044 code += QLatin1String(
"optional " );
5045 code += QLatin1String(
"enum " );
5047 if ( mAllowMultiple )
5048 code += QLatin1String(
"multiple " );
5050 if ( mUsesStaticStrings )
5051 code += QLatin1String(
"static " );
5053 code += mOptions.join(
';' ) +
' ';
5056 return code.trimmed();
5061 switch ( outputType )
5065 QString code = QStringLiteral(
"QgsProcessingParameterEnum('%1', %2" )
5068 code += QLatin1String(
", optional=True" );
5071 options.reserve( mOptions.size() );
5072 for (
const QString &o : mOptions )
5074 code += QStringLiteral(
", options=[%1]" ).arg(
options.join(
',' ) );
5076 code += QStringLiteral(
", allowMultiple=%1" ).arg( mAllowMultiple ? QStringLiteral(
"True" ) : QStringLiteral(
"False" ) );
5078 code += QStringLiteral(
", usesStaticStrings=%1" ).arg( mUsesStaticStrings ? QStringLiteral(
"True" ) : QStringLiteral(
"False" ) );
5101 return mAllowMultiple;
5111 return mUsesStaticStrings;
5122 map.insert( QStringLiteral(
"options" ), mOptions );
5123 map.insert( QStringLiteral(
"allow_multiple" ), mAllowMultiple );
5124 map.insert( QStringLiteral(
"uses_static_strings" ), mUsesStaticStrings );
5131 mOptions = map.value( QStringLiteral(
"options" ) ).toStringList();
5132 mAllowMultiple = map.value( QStringLiteral(
"allow_multiple" ) ).toBool();
5133 mUsesStaticStrings = map.value( QStringLiteral(
"uses_static_strings" ) ).toBool();