QGIS/src/core/processing/qgsprocessingparameters.cpp
2018-10-31 10:27:54 +01:00

4584 lines
146 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***************************************************************************
qgsprocessingparameters.cpp
---------------------------
begin : April 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsprocessingparameters.h"
#include "qgsprocessingprovider.h"
#include "qgsprocessingcontext.h"
#include "qgsprocessingutils.h"
#include "qgsprocessingalgorithm.h"
#include "qgsvectorlayerfeatureiterator.h"
#include "qgsprocessingoutputs.h"
#include "qgssettings.h"
#include "qgsvectorfilewriter.h"
#include "qgsreferencedgeometry.h"
#include "qgsprocessingregistry.h"
#include "qgsprocessingparametertype.h"
#include "qgsrasterfilewriter.h"
#include "qgsvectorlayer.h"
#include <functional>
QVariant QgsProcessingOutputLayerDefinition::toVariant() const
{
QVariantMap map;
map.insert( QStringLiteral( "sink" ), sink.toVariant() );
map.insert( QStringLiteral( "create_options" ), createOptions );
return map;
}
bool QgsProcessingOutputLayerDefinition::loadVariant( const QVariantMap &map )
{
sink.loadVariant( map.value( QStringLiteral( "sink" ) ) );
createOptions = map.value( QStringLiteral( "create_options" ) ).toMap();
return true;
}
bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
{
QVariant val = parameters.value( name );
if ( val.canConvert<QgsProperty>() )
return val.value< QgsProperty >().propertyType() != QgsProperty::StaticProperty;
else
return false;
}
QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return QString();
return parameterAsString( definition, parameters.value( definition->name() ), context );
}
QString QgsProcessingParameters::parameterAsString( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return QString();
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
if ( !val.isValid() )
{
// fall back to default
val = definition->defaultValue();
}
return val.toString();
}
QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return QString();
return parameterAsExpression( definition, parameters.value( definition->name() ), context );
}
QString QgsProcessingParameters::parameterAsExpression( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return QString();
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
return val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
if ( val.isValid() && !val.toString().isEmpty() )
{
QgsExpression e( val.toString() );
if ( e.isValid() )
return val.toString();
}
// fall back to default
return definition->defaultValue().toString();
}
double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return 0;
return parameterAsDouble( definition, parameters.value( definition->name() ), context );
}
double QgsProcessingParameters::parameterAsDouble( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return 0;
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
return val.value< QgsProperty >().valueAsDouble( context.expressionContext(), definition->defaultValue().toDouble() );
bool ok = false;
double res = val.toDouble( &ok );
if ( ok )
return res;
// fall back to default
val = definition->defaultValue();
return val.toDouble();
}
int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return 0;
return parameterAsInt( definition, parameters.value( definition->name() ), context );
}
int QgsProcessingParameters::parameterAsInt( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return 0;
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
return val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
bool ok = false;
double dbl = val.toDouble( &ok );
if ( !ok )
{
// fall back to default
val = definition->defaultValue();
dbl = val.toDouble( &ok );
}
//String representations of doubles in QVariant will not convert to int
//work around this by first converting to double, and then checking whether the double is convertible to int
if ( ok )
{
double round = std::round( dbl );
if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
{
//double too large to fit in int
return 0;
}
return static_cast< int >( std::round( dbl ) );
}
return val.toInt();
}
QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return QList< int >();
return parameterAsInts( definition, parameters.value( definition->name() ), context );
}
QList< int > QgsProcessingParameters::parameterAsInts( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return QList< int >();
QList< int > resultList;
QVariant val = value;
if ( val.isValid() )
{
if ( val.canConvert<QgsProperty>() )
resultList << val.value< QgsProperty >().valueAsInt( context.expressionContext(), definition->defaultValue().toInt() );
else if ( val.type() == QVariant::List )
{
QVariantList list = val.toList();
for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
resultList << it->toInt();
}
else
{
QStringList parts = val.toString().split( ';' );
for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
resultList << it->toInt();
}
}
if ( ( resultList.isEmpty() || resultList.at( 0 ) == 0 ) )
{
resultList.clear();
// check default
if ( definition->defaultValue().isValid() )
{
if ( definition->defaultValue().type() == QVariant::List )
{
QVariantList list = definition->defaultValue().toList();
for ( auto it = list.constBegin(); it != list.constEnd(); ++it )
resultList << it->toInt();
}
else
{
QStringList parts = definition->defaultValue().toString().split( ';' );
for ( auto it = parts.constBegin(); it != parts.constEnd(); ++it )
resultList << it->toInt();
}
}
}
return resultList;
}
int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return 0;
return parameterAsEnum( definition, parameters.value( definition->name() ), context );
}
int QgsProcessingParameters::parameterAsEnum( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return 0;
int val = parameterAsInt( definition, value, context );
const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
if ( enumDef && val >= enumDef->options().size() )
{
return enumDef->defaultValue().toInt();
}
return val;
}
QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return QList<int>();
QVariantList resultList;
return parameterAsEnums( definition, parameters.value( definition->name() ), context );
}
QList<int> QgsProcessingParameters::parameterAsEnums( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return QList<int>();
QVariantList resultList;
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
resultList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else if ( val.type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, val.toList() )
resultList << var;
}
else if ( val.type() == QVariant::String )
{
Q_FOREACH ( const QString &var, val.toString().split( ',' ) )
resultList << var;
}
else
resultList << val;
if ( resultList.isEmpty() )
return QList< int >();
if ( ( !val.isValid() || !resultList.at( 0 ).isValid() ) && definition )
{
resultList.clear();
// check default
if ( definition->defaultValue().type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, definition->defaultValue().toList() )
resultList << var;
}
else if ( definition->defaultValue().type() == QVariant::String )
{
Q_FOREACH ( const QString &var, definition->defaultValue().toString().split( ',' ) )
resultList << var;
}
else
resultList << definition->defaultValue();
}
QList< int > result;
const QgsProcessingParameterEnum *enumDef = dynamic_cast< const QgsProcessingParameterEnum *>( definition );
Q_FOREACH ( const QVariant &var, resultList )
{
int resInt = var.toInt();
if ( !enumDef || resInt < enumDef->options().size() )
{
result << resInt;
}
}
return result;
}
bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context )
{
if ( !definition )
return false;
return parameterAsBool( definition, parameters.value( definition->name() ), context );
}
bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefinition *definition, const QVariant &value, const QgsProcessingContext &context )
{
if ( !definition )
return false;
QVariant def = definition->defaultValue();
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
return val.value< QgsProperty >().valueAsBool( context.expressionContext(), def.toBool() );
else if ( val.isValid() )
return val.toBool();
else
return def.toBool();
}
QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
QgsProcessingContext &context, QString &destinationIdentifier, QgsFeatureSink::SinkFlags sinkFlags )
{
QVariant val;
if ( definition )
{
val = parameters.value( definition->name() );
}
return parameterAsSink( definition, val, fields, geometryType, crs, context, destinationIdentifier, sinkFlags );
}
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 )
{
QVariant val = value;
QgsProject *destinationProject = nullptr;
QString destName;
QVariantMap createOptions;
if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
destinationProject = fromVar.destinationProject;
createOptions = fromVar.createOptions;
val = fromVar.sink;
destName = fromVar.destinationName;
}
QString dest;
if ( val.canConvert<QgsProperty>() )
{
dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
}
else if ( !val.isValid() || val.toString().isEmpty() )
{
if ( definition && definition->flags() & QgsProcessingParameterDefinition::FlagOptional && !definition->defaultValue().isValid() )
{
// unset, optional sink, no default => no sink
return nullptr;
}
// fall back to default
dest = definition->defaultValue().toString();
}
else
{
dest = val.toString();
}
if ( dest.isEmpty() )
return nullptr;
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, createOptions, sinkFlags ) );
destinationIdentifier = dest;
if ( destinationProject )
{
if ( destName.isEmpty() && definition )
{
destName = definition->description();
}
QString outputName;
if ( definition )
outputName = definition->name();
context.addLayerToLoadOnCompletion( destinationIdentifier, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, QgsProcessingUtils::Vector ) );
}
return sink.release();
}
QgsProcessingFeatureSource *QgsProcessingParameters::parameterAsSource( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return nullptr;
return parameterAsSource( definition, parameters.value( definition->name() ), context );
}
QgsProcessingFeatureSource *QgsProcessingParameters::parameterAsSource( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return nullptr;
return QgsProcessingUtils::variantToSource( value, context, definition->defaultValue() );
}
QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingFeedback *feedback )
{
if ( !definition )
return QString();
QVariant val = parameters.value( definition->name() );
bool selectedFeaturesOnly = false;
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() )
{
val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
}
QgsVectorLayer *vl = nullptr;
vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
if ( !vl )
{
QString layerRef;
if ( val.canConvert<QgsProperty>() )
{
layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
}
else if ( !val.isValid() || val.toString().isEmpty() )
{
// fall back to default
val = definition->defaultValue();
// default value may be a vector layer
vl = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) );
if ( !vl )
layerRef = definition->defaultValue().toString();
}
else
{
layerRef = val.toString();
}
if ( !vl )
{
if ( layerRef.isEmpty() )
return QString();
vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, QgsProcessingUtils::Vector ) );
}
}
if ( !vl )
return QString();
return QgsProcessingUtils::convertToCompatibleFormat( vl, selectedFeaturesOnly, definition->name(),
compatibleFormats, preferredFormat, context, feedback );
}
QgsMapLayer *QgsProcessingParameters::parameterAsLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return nullptr;
return parameterAsLayer( definition, parameters.value( definition->name() ), context );
}
QgsMapLayer *QgsProcessingParameters::parameterAsLayer( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return nullptr;
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
{
val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
}
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
{
return layer;
}
if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
{
val = val.value< QgsProperty >().staticValue();
}
if ( !val.isValid() || val.toString().isEmpty() )
{
// fall back to default
val = definition->defaultValue();
}
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
{
return layer;
}
QString layerRef = val.toString();
if ( layerRef.isEmpty() )
layerRef = definition->defaultValue().toString();
if ( layerRef.isEmpty() )
return nullptr;
return QgsProcessingUtils::mapLayerFromString( layerRef, context );
}
QgsRasterLayer *QgsProcessingParameters::parameterAsRasterLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, parameters, context ) );
}
QgsRasterLayer *QgsProcessingParameters::parameterAsRasterLayer( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
return qobject_cast< QgsRasterLayer *>( parameterAsLayer( definition, value, context ) );
}
QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
QVariant val;
if ( definition )
{
val = parameters.value( definition->name() );
}
return parameterAsOutputLayer( definition, val, context );
}
QString QgsProcessingParameters::parameterAsOutputLayer( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
QVariant val = value;
QgsProject *destinationProject = nullptr;
QVariantMap createOptions;
QString destName;
if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
destinationProject = fromVar.destinationProject;
createOptions = fromVar.createOptions;
val = fromVar.sink;
destName = fromVar.destinationName;
}
QString dest;
if ( val.canConvert<QgsProperty>() )
{
dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
}
else if ( definition && ( !val.isValid() || val.toString().isEmpty() ) )
{
// fall back to default
dest = definition->defaultValue().toString();
}
else
{
dest = val.toString();
}
if ( destinationProject )
{
QString outputName;
if ( destName.isEmpty() && definition )
{
destName = definition->description();
}
if ( definition )
outputName = definition->name();
QgsProcessingUtils::LayerHint layerTypeHint = QgsProcessingUtils::UnknownType;
if ( definition->type() == QgsProcessingParameterVectorDestination::typeName() )
layerTypeHint = QgsProcessingUtils::Vector;
else if ( definition->type() == QgsProcessingParameterRasterDestination::typeName() )
layerTypeHint = QgsProcessingUtils::Raster;
context.addLayerToLoadOnCompletion( dest, QgsProcessingContext::LayerDetails( destName, destinationProject, outputName, layerTypeHint ) );
}
return dest;
}
QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
QVariant val;
if ( definition )
{
val = parameters.value( definition->name() );
}
return parameterAsFileOutput( definition, val, context );
}
QString QgsProcessingParameters::parameterAsFileOutput( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
QVariant val = value;
if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
QString dest;
if ( val.canConvert<QgsProperty>() )
{
dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
}
else if ( !val.isValid() || val.toString().isEmpty() )
{
// fall back to default
dest = definition->defaultValue().toString();
}
else
{
dest = val.toString();
}
return dest;
}
QgsVectorLayer *QgsProcessingParameters::parameterAsVectorLayer( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, parameters, context ) );
}
QgsVectorLayer *QgsProcessingParameters::parameterAsVectorLayer( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
return qobject_cast< QgsVectorLayer *>( parameterAsLayer( definition, value, context ) );
}
QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QgsCoordinateReferenceSystem();
return parameterAsCrs( definition, parameters.value( definition->name() ), context );
}
QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QgsCoordinateReferenceSystem();
QVariant val = value;
if ( val.canConvert<QgsCoordinateReferenceSystem>() )
{
// input is a QgsCoordinateReferenceSystem - done!
return val.value< QgsCoordinateReferenceSystem >();
}
else if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
{
val = val.value< QgsProperty >().staticValue();
}
// maybe a map layer
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
return layer->crs();
if ( val.canConvert<QgsProperty>() )
val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
if ( !val.isValid() )
{
// fall back to default
val = definition->defaultValue();
}
QString crsText = val.toString();
if ( crsText.isEmpty() )
crsText = definition->defaultValue().toString();
if ( crsText.isEmpty() )
return QgsCoordinateReferenceSystem();
// maybe special string
if ( context.project() && crsText.compare( QLatin1String( "ProjectCrs" ), Qt::CaseInsensitive ) == 0 )
return context.project()->crs();
// maybe a map layer reference
if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( crsText, context ) )
return layer->crs();
// else CRS from string
QgsCoordinateReferenceSystem crs;
crs.createFromString( crsText );
return crs;
}
QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs )
{
if ( !definition )
return QgsRectangle();
return parameterAsExtent( definition, parameters.value( definition->name() ), context, crs );
}
QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs )
{
if ( !definition )
return QgsRectangle();
QVariant val = value;
if ( val.canConvert< QgsRectangle >() )
{
return val.value<QgsRectangle>();
}
if ( val.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
{
QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
try
{
return ct.transformBoundingBox( rr );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
}
}
return rr;
}
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
{
val = val.value< QgsProperty >().staticValue();
}
// maybe parameter is a direct layer value?
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
QString rectText;
if ( val.canConvert<QgsProperty>() )
rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else
rectText = val.toString();
if ( rectText.isEmpty() && !layer )
return QgsRectangle();
QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
QRegularExpressionMatch match = rx.match( rectText );
if ( match.hasMatch() )
{
bool xMinOk = false;
double xMin = match.captured( 1 ).toDouble( &xMinOk );
bool xMaxOk = false;
double xMax = match.captured( 2 ).toDouble( &xMaxOk );
bool yMinOk = false;
double yMin = match.captured( 3 ).toDouble( &yMinOk );
bool yMaxOk = false;
double yMax = match.captured( 4 ).toDouble( &yMaxOk );
if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
{
QgsRectangle rect( xMin, yMin, xMax, yMax );
QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
{
QgsCoordinateTransform ct( rectCrs, crs, context.project() );
try
{
return ct.transformBoundingBox( rect );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
}
}
return rect;
}
}
// try as layer extent
if ( !layer )
layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
if ( layer )
{
QgsRectangle rect = layer->extent();
if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
{
QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
try
{
return ct.transformBoundingBox( rect );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
}
}
return rect;
}
return QgsRectangle();
}
QgsGeometry QgsProcessingParameters::parameterAsExtentGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs )
{
if ( !definition )
return QgsGeometry();
QVariant val = parameters.value( definition->name() );
if ( val.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
QgsGeometry g = QgsGeometry::fromRect( rr );
if ( crs.isValid() && rr.crs().isValid() && crs != rr.crs() )
{
g = g.densifyByCount( 20 );
QgsCoordinateTransform ct( rr.crs(), crs, context.project() );
try
{
g.transform( ct );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
}
return g;
}
}
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
{
val = val.value< QgsProperty >().staticValue();
}
QString rectText;
if ( val.canConvert<QgsProperty>() )
rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else
rectText = val.toString();
if ( !rectText.isEmpty() )
{
QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
QRegularExpressionMatch match = rx.match( rectText );
if ( match.hasMatch() )
{
bool xMinOk = false;
double xMin = match.captured( 1 ).toDouble( &xMinOk );
bool xMaxOk = false;
double xMax = match.captured( 2 ).toDouble( &xMaxOk );
bool yMinOk = false;
double yMin = match.captured( 3 ).toDouble( &yMinOk );
bool yMaxOk = false;
double yMax = match.captured( 4 ).toDouble( &yMaxOk );
if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
{
QgsRectangle rect( xMin, yMin, xMax, yMax );
QgsCoordinateReferenceSystem rectCrs( match.captured( 5 ) );
QgsGeometry g = QgsGeometry::fromRect( rect );
if ( crs.isValid() && rectCrs.isValid() && crs != rectCrs )
{
g = g.densifyByCount( 20 );
QgsCoordinateTransform ct( rectCrs, crs, context.project() );
try
{
g.transform( ct );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
}
return g;
}
}
}
}
// try as layer extent
// maybe parameter is a direct layer value?
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
if ( !layer )
layer = QgsProcessingUtils::mapLayerFromString( rectText, context );
if ( layer )
{
QgsRectangle rect = layer->extent();
QgsGeometry g = QgsGeometry::fromRect( rect );
if ( crs.isValid() && layer->crs().isValid() && crs != layer->crs() )
{
g = g.densifyByCount( 20 );
QgsCoordinateTransform ct( layer->crs(), crs, context.project() );
try
{
g.transform( ct );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming extent geometry" ) );
}
}
return g;
}
return QgsGeometry::fromRect( parameterAsExtent( definition, parameters, context, crs ) );
}
QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
QVariant val = parameters.value( definition->name() );
if ( val.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
if ( rr.crs().isValid() )
{
return rr.crs();
}
}
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
{
val = val.value< QgsProperty >().staticValue();
}
QString valueAsString;
if ( val.canConvert<QgsProperty>() )
valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else
valueAsString = val.toString();
QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
QRegularExpressionMatch match = rx.match( valueAsString );
if ( match.hasMatch() )
{
QgsCoordinateReferenceSystem crs( match.captured( 5 ) );
if ( crs.isValid() )
return crs;
}
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
{
val = val.value< QgsProperty >().staticValue();
}
// try as layer crs
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
return layer->crs();
else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( valueAsString, context ) )
return layer->crs();
if ( context.project() )
return context.project()->crs();
else
return QgsCoordinateReferenceSystem();
}
QgsPointXY QgsProcessingParameters::parameterAsPoint( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs )
{
if ( !definition )
return QgsPointXY();
return parameterAsPoint( definition, parameters.value( definition->name() ), context, crs );
}
QgsPointXY QgsProcessingParameters::parameterAsPoint( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context, const QgsCoordinateReferenceSystem &crs )
{
if ( !definition )
return QgsPointXY();
QVariant val = value;
if ( val.canConvert< QgsPointXY >() )
{
return val.value<QgsPointXY>();
}
if ( val.canConvert< QgsReferencedPointXY >() )
{
QgsReferencedPointXY rp = val.value<QgsReferencedPointXY>();
if ( crs.isValid() && rp.crs().isValid() && crs != rp.crs() )
{
QgsCoordinateTransform ct( rp.crs(), crs, context.project() );
try
{
return ct.transform( rp );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
}
}
return rp;
}
QString pointText = parameterAsString( definition, value, context );
if ( pointText.isEmpty() )
pointText = definition->defaultValue().toString();
if ( pointText.isEmpty() )
return QgsPointXY();
QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
QString valueAsString = parameterAsString( definition, value, context );
QRegularExpressionMatch match = rx.match( valueAsString );
if ( match.hasMatch() )
{
bool xOk = false;
double x = match.captured( 1 ).toDouble( &xOk );
bool yOk = false;
double y = match.captured( 2 ).toDouble( &yOk );
if ( xOk && yOk )
{
QgsPointXY pt( x, y );
QgsCoordinateReferenceSystem pointCrs( match.captured( 3 ) );
if ( crs.isValid() && pointCrs.isValid() && crs != pointCrs )
{
QgsCoordinateTransform ct( pointCrs, crs, context.project() );
try
{
return ct.transform( pt );
}
catch ( QgsCsException & )
{
QgsMessageLog::logMessage( QObject::tr( "Error transforming point geometry" ) );
}
}
return pt;
}
}
return QgsPointXY();
}
QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsPointCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
QVariant val = parameters.value( definition->name() );
if ( val.canConvert< QgsReferencedPointXY >() )
{
QgsReferencedPointXY rr = val.value<QgsReferencedPointXY>();
if ( rr.crs().isValid() )
{
return rr.crs();
}
}
QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
QString valueAsString = parameterAsString( definition, parameters, context );
QRegularExpressionMatch match = rx.match( valueAsString );
if ( match.hasMatch() )
{
QgsCoordinateReferenceSystem crs( match.captured( 3 ) );
if ( crs.isValid() )
return crs;
}
if ( context.project() )
return context.project()->crs();
else
return QgsCoordinateReferenceSystem();
}
QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QString();
QString fileText = parameterAsString( definition, parameters, context );
if ( fileText.isEmpty() )
fileText = definition->defaultValue().toString();
return fileText;
}
QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QString();
QString fileText = parameterAsString( definition, value, context );
if ( fileText.isEmpty() )
fileText = definition->defaultValue().toString();
return fileText;
}
QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QVariantList();
return parameterAsMatrix( definition, parameters.value( definition->name() ), context );
}
QVariantList QgsProcessingParameters::parameterAsMatrix( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QVariantList();
QString resultString;
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
resultString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else if ( val.type() == QVariant::List )
return val.toList();
else
resultString = val.toString();
if ( resultString.isEmpty() )
{
// check default
if ( definition->defaultValue().type() == QVariant::List )
return definition->defaultValue().toList();
else
resultString = definition->defaultValue().toString();
}
QVariantList result;
Q_FOREACH ( const QString &s, resultString.split( ',' ) )
result << s;
return result;
}
QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QList<QgsMapLayer *>();
return parameterAsLayerList( definition, parameters.value( definition->name() ), context );
}
QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QList<QgsMapLayer *>();
QVariant val = value;
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
{
return QList<QgsMapLayer *>() << layer;
}
QList<QgsMapLayer *> layers;
std::function< void( const QVariant &var ) > processVariant;
processVariant = [ &layers, &context, &definition, &processVariant ]( const QVariant & var )
{
if ( var.type() == QVariant::List )
{
Q_FOREACH ( const QVariant &listVar, var.toList() )
{
processVariant( listVar );
}
}
else if ( var.type() == QVariant::StringList )
{
Q_FOREACH ( const QString &s, var.toStringList() )
{
processVariant( s );
}
}
else if ( var.canConvert<QgsProperty>() )
processVariant( var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
QVariant sink = fromVar.sink;
if ( sink.canConvert<QgsProperty>() )
{
processVariant( sink.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() ) );
}
}
else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
{
layers << layer;
}
else
{
QgsMapLayer *alayer = QgsProcessingUtils::mapLayerFromString( var.toString(), context );
if ( alayer )
layers << alayer;
}
};
processVariant( val );
if ( layers.isEmpty() )
{
// check default
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( definition->defaultValue() ) ) )
{
layers << layer;
}
else if ( definition->defaultValue().type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, definition->defaultValue().toList() )
{
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
{
layers << layer;
}
else
{
processVariant( var );
}
}
}
else
processVariant( definition->defaultValue() );
}
return layers;
}
QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QList<double>();
return parameterAsRange( definition, parameters.value( definition->name() ), context );
}
QList<double> QgsProcessingParameters::parameterAsRange( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QList<double>();
QStringList resultStringList;
QVariant val = value;
if ( val.canConvert<QgsProperty>() )
resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else if ( val.type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, val.toList() )
resultStringList << var.toString();
}
else
resultStringList << val.toString();
if ( ( resultStringList.isEmpty() || ( resultStringList.size() == 1 && resultStringList.at( 0 ).isEmpty() ) ) )
{
resultStringList.clear();
// check default
if ( definition->defaultValue().type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, definition->defaultValue().toList() )
resultStringList << var.toString();
}
else
resultStringList << definition->defaultValue().toString();
}
if ( resultStringList.size() == 1 )
{
resultStringList = resultStringList.at( 0 ).split( ',' );
}
if ( resultStringList.size() < 2 )
return QList< double >() << 0.0 << 0.0;
return QList< double >() << resultStringList.at( 0 ).toDouble() << resultStringList.at( 1 ).toDouble();
}
QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QStringList();
QStringList resultStringList;
return parameterAsFields( definition, parameters.value( definition->name() ), context );
}
QStringList QgsProcessingParameters::parameterAsFields( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QStringList();
QStringList resultStringList;
QVariant val = value;
if ( val.isValid() )
{
if ( val.canConvert<QgsProperty>() )
resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
else if ( val.type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, val.toList() )
resultStringList << var.toString();
}
else
resultStringList.append( val.toString().split( ';' ) );
}
if ( ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
{
resultStringList.clear();
// check default
if ( definition->defaultValue().isValid() )
{
if ( definition->defaultValue().type() == QVariant::List )
{
Q_FOREACH ( const QVariant &var, definition->defaultValue().toList() )
resultStringList << var.toString();
}
else
resultStringList.append( definition->defaultValue().toString().split( ';' ) );
}
}
return resultStringList;
}
QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromVariantMap( const QVariantMap &map )
{
QString type = map.value( QStringLiteral( "parameter_type" ) ).toString();
QString name = map.value( QStringLiteral( "name" ) ).toString();
std::unique_ptr< QgsProcessingParameterDefinition > def;
if ( type == QgsProcessingParameterBoolean::typeName() )
def.reset( new QgsProcessingParameterBoolean( name ) );
else if ( type == QgsProcessingParameterCrs::typeName() )
def.reset( new QgsProcessingParameterCrs( name ) );
else if ( type == QgsProcessingParameterMapLayer::typeName() )
def.reset( new QgsProcessingParameterMapLayer( name ) );
else if ( type == QgsProcessingParameterExtent::typeName() )
def.reset( new QgsProcessingParameterExtent( name ) );
else if ( type == QgsProcessingParameterPoint::typeName() )
def.reset( new QgsProcessingParameterPoint( name ) );
else if ( type == QgsProcessingParameterFile::typeName() )
def.reset( new QgsProcessingParameterFile( name ) );
else if ( type == QgsProcessingParameterMatrix::typeName() )
def.reset( new QgsProcessingParameterMatrix( name ) );
else if ( type == QgsProcessingParameterMultipleLayers::typeName() )
def.reset( new QgsProcessingParameterMultipleLayers( name ) );
else if ( type == QgsProcessingParameterNumber::typeName() )
def.reset( new QgsProcessingParameterNumber( name ) );
else if ( type == QgsProcessingParameterRange::typeName() )
def.reset( new QgsProcessingParameterRange( name ) );
else if ( type == QgsProcessingParameterRasterLayer::typeName() )
def.reset( new QgsProcessingParameterRasterLayer( name ) );
else if ( type == QgsProcessingParameterEnum::typeName() )
def.reset( new QgsProcessingParameterEnum( name ) );
else if ( type == QgsProcessingParameterString::typeName() )
def.reset( new QgsProcessingParameterString( name ) );
else if ( type == QgsProcessingParameterExpression::typeName() )
def.reset( new QgsProcessingParameterExpression( name ) );
else if ( type == QgsProcessingParameterVectorLayer::typeName() )
def.reset( new QgsProcessingParameterVectorLayer( name ) );
else if ( type == QgsProcessingParameterField::typeName() )
def.reset( new QgsProcessingParameterField( name ) );
else if ( type == QgsProcessingParameterFeatureSource::typeName() )
def.reset( new QgsProcessingParameterFeatureSource( name ) );
else if ( type == QgsProcessingParameterFeatureSink::typeName() )
def.reset( new QgsProcessingParameterFeatureSink( name ) );
else if ( type == QgsProcessingParameterVectorDestination::typeName() )
def.reset( new QgsProcessingParameterVectorDestination( name ) );
else if ( type == QgsProcessingParameterRasterDestination::typeName() )
def.reset( new QgsProcessingParameterRasterDestination( name ) );
else if ( type == QgsProcessingParameterFileDestination::typeName() )
def.reset( new QgsProcessingParameterFileDestination( name ) );
else if ( type == QgsProcessingParameterFolderDestination::typeName() )
def.reset( new QgsProcessingParameterFolderDestination( name ) );
else if ( type == QgsProcessingParameterBand::typeName() )
def.reset( new QgsProcessingParameterBand( name ) );
else
{
QgsProcessingParameterType *paramType = QgsApplication::instance()->processingRegistry()->parameterType( type );
if ( paramType )
def.reset( paramType->create( name ) );
}
if ( !def )
return nullptr;
def->fromVariantMap( map );
return def.release();
}
QString QgsProcessingParameters::descriptionFromName( const QString &name )
{
QString desc = name;
desc.replace( '_', ' ' );
return desc;
}
QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromScriptCode( const QString &code )
{
bool isOptional = false;
QString name;
QString definition;
QString type;
if ( !parseScriptCodeParameterOptions( code, isOptional, name, type, definition ) )
return nullptr;
QString description = descriptionFromName( name );
if ( type == QStringLiteral( "boolean" ) )
return QgsProcessingParameterBoolean::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "crs" ) )
return QgsProcessingParameterCrs::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "layer" ) )
return QgsProcessingParameterMapLayer::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "extent" ) )
return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "point" ) )
return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "file" ) )
return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
else if ( type == QStringLiteral( "folder" ) )
return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::Folder );
else if ( type == QStringLiteral( "matrix" ) )
return QgsProcessingParameterMatrix::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "multiple" ) )
return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "number" ) )
return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "range" ) )
return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "raster" ) )
return QgsProcessingParameterRasterLayer::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "enum" ) )
return QgsProcessingParameterEnum::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "string" ) )
return QgsProcessingParameterString::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "expression" ) )
return QgsProcessingParameterExpression::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "field" ) )
return QgsProcessingParameterField::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "vector" ) )
return QgsProcessingParameterVectorLayer::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "source" ) )
return QgsProcessingParameterFeatureSource::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "sink" ) )
return QgsProcessingParameterFeatureSink::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "vectordestination" ) )
return QgsProcessingParameterVectorDestination::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "rasterdestination" ) )
return QgsProcessingParameterRasterDestination::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "filedestination" ) )
return QgsProcessingParameterFileDestination::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "folderdestination" ) )
return QgsProcessingParameterFolderDestination::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "band" ) )
return QgsProcessingParameterBand::fromScriptCode( name, description, isOptional, definition );
return nullptr;
}
bool QgsProcessingParameters::parseScriptCodeParameterOptions( const QString &code, bool &isOptional, QString &name, QString &type, QString &definition )
{
QRegularExpression re( QStringLiteral( "(?:#*)(.*?)=\\s*(.*)" ) );
QRegularExpressionMatch m = re.match( code );
if ( !m.hasMatch() )
return false;
name = m.captured( 1 );
QString tokens = m.captured( 2 );
if ( tokens.startsWith( QLatin1String( "optional" ), Qt::CaseInsensitive ) )
{
isOptional = true;
tokens.remove( 0, 8 ); // length "optional" = 8
}
else
{
isOptional = false;
}
tokens = tokens.trimmed();
QRegularExpression re2( QStringLiteral( "(.*?)\\s+(.*)" ) );
m = re2.match( tokens );
if ( !m.hasMatch() )
{
type = tokens.toLower().trimmed();
definition.clear();
}
else
{
type = m.captured( 1 ).toLower().trimmed();
definition = m.captured( 2 );
}
return true;
}
//
// QgsProcessingParameterDefinition
//
QgsProcessingParameterDefinition::QgsProcessingParameterDefinition( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: mName( name )
, mDescription( description )
, mDefault( defaultValue )
, mFlags( optional ? FlagOptional : 0 )
{}
bool QgsProcessingParameterDefinition::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() && !mDefault.isValid() )
return mFlags & FlagOptional;
if ( ( input.type() == QVariant::String && input.toString().isEmpty() )
|| ( !input.isValid() && mDefault.type() == QVariant::String && mDefault.toString().isEmpty() ) )
return mFlags & FlagOptional;
return true;
}
QString QgsProcessingParameterDefinition::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}
QString QgsProcessingParameterDefinition::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += type() + ' ';
code += mDefault.toString();
return code.trimmed();
}
QVariantMap QgsProcessingParameterDefinition::toVariantMap() const
{
QVariantMap map;
map.insert( QStringLiteral( "parameter_type" ), type() );
map.insert( QStringLiteral( "name" ), mName );
map.insert( QStringLiteral( "description" ), mDescription );
map.insert( QStringLiteral( "default" ), mDefault );
map.insert( QStringLiteral( "flags" ), static_cast< int >( mFlags ) );
map.insert( QStringLiteral( "metadata" ), mMetadata );
return map;
}
bool QgsProcessingParameterDefinition::fromVariantMap( const QVariantMap &map )
{
mName = map.value( QStringLiteral( "name" ) ).toString();
mDescription = map.value( QStringLiteral( "description" ) ).toString();
mDefault = map.value( QStringLiteral( "default" ) );
mFlags = static_cast< Flags >( map.value( QStringLiteral( "flags" ) ).toInt() );
mMetadata = map.value( QStringLiteral( "metadata" ) ).toMap();
return true;
}
QgsProcessingAlgorithm *QgsProcessingParameterDefinition::algorithm() const
{
return mAlgorithm;
}
QgsProcessingProvider *QgsProcessingParameterDefinition::provider() const
{
return mAlgorithm ? mAlgorithm->provider() : nullptr;
}
QString QgsProcessingParameterDefinition::toolTip() const
{
return QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
description(),
QObject::tr( "Python identifier: %1" ).arg( QStringLiteral( "<i>%1</i>" ).arg( name() ) ) );
}
QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{}
QgsProcessingParameterDefinition *QgsProcessingParameterBoolean::clone() const
{
return new QgsProcessingParameterBoolean( *this );
}
QString QgsProcessingParameterBoolean::valueAsPythonString( const QVariant &val, QgsProcessingContext & ) const
{
if ( !val.isValid() )
return QStringLiteral( "None" );
if ( val.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
return val.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
}
QString QgsProcessingParameterBoolean::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += type() + ' ';
code += mDefault.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
return code.trimmed();
}
QgsProcessingParameterBoolean *QgsProcessingParameterBoolean::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterBoolean( name, description, definition.toLower().trimmed() != QStringLiteral( "false" ), isOptional );
}
QgsProcessingParameterCrs::QgsProcessingParameterCrs( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterCrs::clone() const
{
return new QgsProcessingParameterCrs( *this );
}
bool QgsProcessingParameterCrs::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsCoordinateReferenceSystem>() )
{
return true;
}
else if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
return true;
}
else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
{
return true;
}
if ( input.canConvert<QgsProperty>() )
{
return true;
}
// direct map layer value
if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
return true;
if ( input.type() != QVariant::String || input.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
QString QgsProcessingParameterCrs::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsCoordinateReferenceSystem>() )
{
if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
return QStringLiteral( "QgsCoordinateReferenceSystem()" );
else
return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
}
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), value );
QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
if ( layer )
return QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
}
QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterCrs( name, description, definition.compare( QLatin1String( "none" ), Qt::CaseInsensitive ) == 0 ? QVariant() : definition, isOptional );
}
QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterMapLayer::clone() const
{
return new QgsProcessingParameterMapLayer( *this );
}
bool QgsProcessingParameterMapLayer::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
{
return true;
}
if ( input.type() != QVariant::String || input.toString().isEmpty() )
return mFlags & FlagOptional;
if ( !context )
{
// that's as far as we can get without a context
return true;
}
// try to load as layer
if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
return true;
return false;
}
QString QgsProcessingParameterMapLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
{
if ( !val.isValid() )
return QStringLiteral( "None" );
if ( val.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), val );
QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
: QgsProcessingUtils::stringToPythonLiteral( val.toString() );
}
QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterMapLayer( name, description, definition, isOptional );
}
QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterExtent::clone() const
{
return new QgsProcessingParameterExtent( *this );
}
bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
return true;
}
else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
{
return true;
}
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( input.canConvert< QgsRectangle >() )
{
QgsRectangle r = input.value<QgsRectangle>();
return !r.isNull();
}
if ( input.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle r = input.value<QgsReferencedRectangle>();
return !r.isNull();
}
// direct map layer value
if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
return true;
if ( input.type() != QVariant::String || input.toString().isEmpty() )
return mFlags & FlagOptional;
if ( !context )
{
// that's as far as we can get without a context
return true;
}
QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
QRegularExpressionMatch match = rx.match( input.toString() );
if ( match.hasMatch() )
{
bool xMinOk = false;
( void )match.captured( 1 ).toDouble( &xMinOk );
bool xMaxOk = false;
( void )match.captured( 2 ).toDouble( &xMaxOk );
bool yMinOk = false;
( void )match.captured( 3 ).toDouble( &yMinOk );
bool yMaxOk = false;
( void )match.captured( 4 ).toDouble( &yMaxOk );
if ( xMinOk && xMaxOk && yMinOk && yMaxOk )
return true;
}
// try as layer extent
return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
}
QString QgsProcessingParameterExtent::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert< QgsRectangle >() )
{
QgsRectangle r = value.value<QgsRectangle>();
return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
qgsDoubleToString( r.yMinimum() ),
qgsDoubleToString( r.xMaximum() ),
qgsDoubleToString( r.yMaximum() ) );
}
if ( value.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle r = value.value<QgsReferencedRectangle>();
return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
qgsDoubleToString( r.yMinimum() ),
qgsDoubleToString( r.xMaximum() ),
qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
}
QVariantMap p;
p.insert( name(), value );
QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context );
if ( layer )
return QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
}
QgsProcessingParameterExtent *QgsProcessingParameterExtent::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterExtent( name, description, definition, isOptional );
}
QgsProcessingParameterPoint::QgsProcessingParameterPoint( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterPoint::clone() const
{
return new QgsProcessingParameterPoint( *this );
}
bool QgsProcessingParameterPoint::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( input.canConvert< QgsPointXY >() )
{
return true;
}
if ( input.canConvert< QgsReferencedPointXY >() )
{
return true;
}
if ( input.type() == QVariant::String )
{
if ( input.toString().isEmpty() )
return mFlags & FlagOptional;
}
QRegularExpression rx( QStringLiteral( "^\\s*\\(?\\s*(.*?)\\s*,\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*\\)?\\s*$" ) );
QRegularExpressionMatch match = rx.match( input.toString() );
if ( match.hasMatch() )
{
bool xOk = false;
( void )match.captured( 1 ).toDouble( &xOk );
bool yOk = false;
( void )match.captured( 2 ).toDouble( &yOk );
return xOk && yOk;
}
else
return false;
}
QString QgsProcessingParameterPoint::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert< QgsPointXY >() )
{
QgsPointXY r = value.value<QgsPointXY>();
return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
qgsDoubleToString( r.y() ) );
}
if ( value.canConvert< QgsReferencedPointXY >() )
{
QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
qgsDoubleToString( r.y() ),
r.crs().authid() );
}
return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
}
QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterPoint( name, description, definition, isOptional );
}
QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mBehavior( behavior )
, mExtension( extension )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterFile::clone() const
{
return new QgsProcessingParameterFile( *this );
}
bool QgsProcessingParameterFile::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
QString string = input.toString().trimmed();
if ( input.type() != QVariant::String || string.isEmpty() )
return mFlags & FlagOptional;
switch ( mBehavior )
{
case File:
{
if ( !mExtension.isEmpty() )
return string.endsWith( mExtension, Qt::CaseInsensitive );
return true;
}
case Folder:
return true;
}
return true;
}
QString QgsProcessingParameterFile::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += ( mBehavior == File ? QStringLiteral( "file" ) : QStringLiteral( "folder" ) ) + ' ';
code += mDefault.toString();
return code.trimmed();
}
QVariantMap QgsProcessingParameterFile::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "behavior" ), mBehavior );
map.insert( QStringLiteral( "extension" ), mExtension );
return map;
}
bool QgsProcessingParameterFile::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mBehavior = static_cast< Behavior >( map.value( QStringLiteral( "behavior" ) ).toInt() );
mExtension = map.value( QStringLiteral( "extension" ) ).toString();
return true;
}
QgsProcessingParameterFile *QgsProcessingParameterFile::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition, QgsProcessingParameterFile::Behavior behavior )
{
return new QgsProcessingParameterFile( name, description, behavior, QString(), definition, isOptional );
}
QgsProcessingParameterMatrix::QgsProcessingParameterMatrix( const QString &name, const QString &description, int numberRows, bool fixedNumberRows, const QStringList &headers, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mHeaders( headers )
, mNumberRows( numberRows )
, mFixedNumberRows( fixedNumberRows )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterMatrix::clone() const
{
return new QgsProcessingParameterMatrix( *this );
}
bool QgsProcessingParameterMatrix::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.type() == QVariant::String )
{
if ( input.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
else if ( input.type() == QVariant::List )
{
if ( input.toList().isEmpty() )
return mFlags & FlagOptional;
return true;
}
else if ( input.type() == QVariant::Double || input.type() == QVariant::Int )
{
return true;
}
return false;
}
QString QgsProcessingParameterMatrix::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), value );
QVariantList list = QgsProcessingParameters::parameterAsMatrix( this, p, context );
QStringList parts;
Q_FOREACH ( const QVariant &v, list )
{
if ( v.type() == QVariant::List )
{
QStringList parts2;
Q_FOREACH ( const QVariant &v2, v.toList() )
{
if ( v2.isNull() || !v2.isValid() )
parts2 << QStringLiteral( "None" );
else if ( v2.toString().isEmpty() )
parts2 << QStringLiteral( "''" );
else
parts2 << v2.toString();
}
parts << parts2.join( ',' ).prepend( '[' ).append( ']' );
}
else
{
if ( v.isNull() || !v.isValid() )
parts << QStringLiteral( "None" );
else if ( v.toString().isEmpty() )
parts << QStringLiteral( "''" );
else
parts << v.toString();
}
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
QStringList QgsProcessingParameterMatrix::headers() const
{
return mHeaders;
}
void QgsProcessingParameterMatrix::setHeaders( const QStringList &headers )
{
mHeaders = headers;
}
int QgsProcessingParameterMatrix::numberRows() const
{
return mNumberRows;
}
void QgsProcessingParameterMatrix::setNumberRows( int numberRows )
{
mNumberRows = numberRows;
}
bool QgsProcessingParameterMatrix::hasFixedNumberRows() const
{
return mFixedNumberRows;
}
void QgsProcessingParameterMatrix::setHasFixedNumberRows( bool fixedNumberRows )
{
mFixedNumberRows = fixedNumberRows;
}
QVariantMap QgsProcessingParameterMatrix::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "headers" ), mHeaders );
map.insert( QStringLiteral( "rows" ), mNumberRows );
map.insert( QStringLiteral( "fixed_number_rows" ), mFixedNumberRows );
return map;
}
bool QgsProcessingParameterMatrix::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mHeaders = map.value( QStringLiteral( "headers" ) ).toStringList();
mNumberRows = map.value( QStringLiteral( "rows" ) ).toInt();
mFixedNumberRows = map.value( QStringLiteral( "fixed_number_rows" ) ).toBool();
return true;
}
QgsProcessingParameterMatrix *QgsProcessingParameterMatrix::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterMatrix( name, description, 0, false, QStringList(), definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingParameterMultipleLayers::QgsProcessingParameterMultipleLayers( const QString &name, const QString &description, QgsProcessing::SourceType layerType, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mLayerType( layerType )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterMultipleLayers::clone() const
{
return new QgsProcessingParameterMultipleLayers( *this );
}
bool QgsProcessingParameterMultipleLayers::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( input ) ) )
{
return true;
}
if ( input.type() == QVariant::String )
{
if ( input.toString().isEmpty() )
return mFlags & FlagOptional;
if ( mMinimumNumberInputs > 1 )
return false;
if ( !context )
return true;
return QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
}
else if ( input.type() == QVariant::List )
{
if ( input.toList().count() < mMinimumNumberInputs )
return mFlags & FlagOptional;
if ( mMinimumNumberInputs > input.toList().count() )
return false;
if ( !context )
return true;
Q_FOREACH ( const QVariant &v, input.toList() )
{
if ( qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( v ) ) )
continue;
if ( !QgsProcessingUtils::mapLayerFromString( v.toString(), *context ) )
return false;
}
return true;
}
else if ( input.type() == QVariant::StringList )
{
if ( input.toStringList().count() < mMinimumNumberInputs )
return mFlags & FlagOptional;
if ( mMinimumNumberInputs > input.toStringList().count() )
return false;
if ( !context )
return true;
Q_FOREACH ( const QString &v, input.toStringList() )
{
if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
return false;
}
return true;
}
return false;
}
QString QgsProcessingParameterMultipleLayers::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), value );
QList<QgsMapLayer *> list = QgsProcessingParameters::parameterAsLayerList( this, p, context );
if ( !list.isEmpty() )
{
QStringList parts;
Q_FOREACH ( const QgsMapLayer *layer, list )
{
parts << QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) );
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
}
QString QgsProcessingParameterMultipleLayers::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
switch ( mLayerType )
{
case QgsProcessing::TypeRaster:
code += QStringLiteral( "multiple raster" );
break;
case QgsProcessing::TypeFile:
code += QStringLiteral( "multiple file" );
break;
default:
code += QStringLiteral( "multiple vector" );
break;
}
code += ' ';
if ( mDefault.type() == QVariant::List )
{
QStringList parts;
Q_FOREACH ( const QVariant &var, mDefault.toList() )
{
parts << var.toString();
}
code += parts.join( ',' );
}
else if ( mDefault.type() == QVariant::StringList )
{
code += mDefault.toStringList().join( ',' );
}
else
{
code += mDefault.toString();
}
return code.trimmed();
}
QgsProcessing::SourceType QgsProcessingParameterMultipleLayers::layerType() const
{
return mLayerType;
}
void QgsProcessingParameterMultipleLayers::setLayerType( QgsProcessing::SourceType type )
{
mLayerType = type;
}
int QgsProcessingParameterMultipleLayers::minimumNumberInputs() const
{
return mMinimumNumberInputs;
}
void QgsProcessingParameterMultipleLayers::setMinimumNumberInputs( int minimumNumberInputs )
{
if ( mMinimumNumberInputs >= 1 || !( flags() & QgsProcessingParameterDefinition::FlagOptional ) )
mMinimumNumberInputs = minimumNumberInputs;
}
QVariantMap QgsProcessingParameterMultipleLayers::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "layer_type" ), mLayerType );
map.insert( QStringLiteral( "min_inputs" ), mMinimumNumberInputs );
return map;
}
bool QgsProcessingParameterMultipleLayers::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mLayerType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "layer_type" ) ).toInt() );
mMinimumNumberInputs = map.value( QStringLiteral( "min_inputs" ) ).toInt();
return true;
}
QgsProcessingParameterMultipleLayers *QgsProcessingParameterMultipleLayers::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString type = definition;
QString defaultVal;
QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)" ) );
QRegularExpressionMatch m = re.match( definition );
if ( m.hasMatch() )
{
type = m.captured( 1 ).toLower().trimmed();
defaultVal = m.captured( 2 );
}
QgsProcessing::SourceType layerType = QgsProcessing::TypeVectorAnyGeometry;
if ( type == QStringLiteral( "vector" ) )
layerType = QgsProcessing::TypeVectorAnyGeometry;
else if ( type == QStringLiteral( "raster" ) )
layerType = QgsProcessing::TypeRaster;
else if ( type == QStringLiteral( "file" ) )
layerType = QgsProcessing::TypeFile;
return new QgsProcessingParameterMultipleLayers( name, description, layerType, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
}
QgsProcessingParameterNumber::QgsProcessingParameterNumber( const QString &name, const QString &description, Type type, const QVariant &defaultValue, bool optional, double minValue, double maxValue )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mMin( minValue )
, mMax( maxValue )
, mDataType( type )
{
if ( mMin >= mMax )
{
QgsMessageLog::logMessage( QObject::tr( "Invalid number parameter \"%1\": min value %2 is >= max value %3!" ).arg( name ).arg( mMin ).arg( mMax ), QObject::tr( "Processing" ) );
}
}
QgsProcessingParameterDefinition *QgsProcessingParameterNumber::clone() const
{
return new QgsProcessingParameterNumber( *this );
}
bool QgsProcessingParameterNumber::checkValueIsAcceptable( const QVariant &value, QgsProcessingContext * ) const
{
QVariant input = value;
if ( !input.isValid() )
{
if ( !defaultValue().isValid() )
return mFlags & FlagOptional;
input = defaultValue();
}
if ( input.canConvert<QgsProperty>() )
{
return true;
}
bool ok = false;
double res = input.toDouble( &ok );
if ( !ok )
return mFlags & FlagOptional;
return !( res < mMin || res > mMax );
}
QString QgsProcessingParameterNumber::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
return value.toString();
}
QString QgsProcessingParameterNumber::toolTip() const
{
QString text = QgsProcessingParameterDefinition::toolTip();
QStringList parts;
if ( mMin > std::numeric_limits<double>::lowest() + 1 )
parts << QObject::tr( "Minimum value: %1" ).arg( mMin );
if ( mMax < std::numeric_limits<double>::max() )
parts << QObject::tr( "Maximum value: %1" ).arg( mMax );
if ( mDefault.isValid() )
parts << QObject::tr( "Default value: %1" ).arg( mDataType == Integer ? mDefault.toInt() : mDefault.toDouble() );
QString extra = parts.join( QStringLiteral( "<br />" ) );
if ( !extra.isEmpty() )
text += QStringLiteral( "<p>%1</p>" ).arg( extra );
return text;
}
double QgsProcessingParameterNumber::minimum() const
{
return mMin;
}
void QgsProcessingParameterNumber::setMinimum( double min )
{
mMin = min;
}
double QgsProcessingParameterNumber::maximum() const
{
return mMax;
}
void QgsProcessingParameterNumber::setMaximum( double max )
{
mMax = max;
}
QgsProcessingParameterNumber::Type QgsProcessingParameterNumber::dataType() const
{
return mDataType;
}
void QgsProcessingParameterNumber::setDataType( Type dataType )
{
mDataType = dataType;
}
QVariantMap QgsProcessingParameterNumber::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "min" ), mMin );
map.insert( QStringLiteral( "max" ), mMax );
map.insert( QStringLiteral( "data_type" ), mDataType );
return map;
}
bool QgsProcessingParameterNumber::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mMin = map.value( QStringLiteral( "min" ) ).toDouble();
mMax = map.value( QStringLiteral( "max" ) ).toDouble();
mDataType = static_cast< Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
return true;
}
QgsProcessingParameterNumber *QgsProcessingParameterNumber::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterNumber( name, description, Double, definition.isEmpty() ? QVariant()
: ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
}
QgsProcessingParameterRange::QgsProcessingParameterRange( const QString &name, const QString &description, QgsProcessingParameterNumber::Type type, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mDataType( type )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterRange::clone() const
{
return new QgsProcessingParameterRange( *this );
}
bool QgsProcessingParameterRange::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( input.type() == QVariant::String )
{
QStringList list = input.toString().split( ',' );
if ( list.count() != 2 )
return mFlags & FlagOptional;
bool ok = false;
list.at( 0 ).toDouble( &ok );
bool ok2 = false;
list.at( 1 ).toDouble( &ok2 );
if ( !ok || !ok2 )
return mFlags & FlagOptional;
return true;
}
else if ( input.type() == QVariant::List )
{
if ( input.toList().count() != 2 )
return mFlags & FlagOptional;
bool ok = false;
input.toList().at( 0 ).toDouble( &ok );
bool ok2 = false;
input.toList().at( 1 ).toDouble( &ok2 );
if ( !ok || !ok2 )
return mFlags & FlagOptional;
return true;
}
return false;
}
QString QgsProcessingParameterRange::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), value );
QList< double > parts = QgsProcessingParameters::parameterAsRange( this, p, context );
QStringList stringParts;
Q_FOREACH ( double v, parts )
{
stringParts << QString::number( v );
}
return stringParts.join( ',' ).prepend( '[' ).append( ']' );
}
QgsProcessingParameterNumber::Type QgsProcessingParameterRange::dataType() const
{
return mDataType;
}
void QgsProcessingParameterRange::setDataType( QgsProcessingParameterNumber::Type dataType )
{
mDataType = dataType;
}
QVariantMap QgsProcessingParameterRange::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "data_type" ), mDataType );
return map;
}
bool QgsProcessingParameterRange::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mDataType = static_cast< QgsProcessingParameterNumber::Type >( map.value( QStringLiteral( "data_type" ) ).toInt() );
return true;
}
QgsProcessingParameterRange *QgsProcessingParameterRange::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterRange( name, description, QgsProcessingParameterNumber::Double, definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingParameterRasterLayer::QgsProcessingParameterRasterLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterRasterLayer::clone() const
{
return new QgsProcessingParameterRasterLayer( *this );
}
bool QgsProcessingParameterRasterLayer::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( qobject_cast< QgsRasterLayer * >( qvariant_cast<QObject *>( input ) ) )
return true;
if ( input.type() != QVariant::String || input.toString().isEmpty() )
return mFlags & FlagOptional;
if ( !context )
{
// that's as far as we can get without a context
return true;
}
// try to load as layer
if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context, true, QgsProcessingUtils::Raster ) )
return true;
return false;
}
QString QgsProcessingParameterRasterLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
{
if ( !val.isValid() )
return QStringLiteral( "None" );
if ( val.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), val );
QgsRasterLayer *layer = QgsProcessingParameters::parameterAsRasterLayer( this, p, context );
return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
: QgsProcessingUtils::stringToPythonLiteral( val.toString() );
}
QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterRasterLayer( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingParameterEnum::QgsProcessingParameterEnum( const QString &name, const QString &description, const QStringList &options, bool allowMultiple, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mOptions( options )
, mAllowMultiple( allowMultiple )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterEnum::clone() const
{
return new QgsProcessingParameterEnum( *this );
}
bool QgsProcessingParameterEnum::checkValueIsAcceptable( const QVariant &value, QgsProcessingContext * ) const
{
QVariant input = value;
if ( !input.isValid() )
{
if ( !defaultValue().isValid() )
return mFlags & FlagOptional;
input = defaultValue();
}
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( input.type() == QVariant::List )
{
if ( !mAllowMultiple )
return false;
const QVariantList values = input.toList();
if ( values.empty() && !( mFlags & FlagOptional ) )
return false;
for ( const QVariant &val : values )
{
bool ok = false;
int res = val.toInt( &ok );
if ( !ok )
return false;
else if ( res < 0 || res >= mOptions.count() )
return false;
}
return true;
}
else if ( input.type() == QVariant::String )
{
QStringList parts = input.toString().split( ',' );
if ( parts.count() > 1 && !mAllowMultiple )
return false;
Q_FOREACH ( const QString &part, parts )
{
bool ok = false;
int res = part.toInt( &ok );
if ( !ok )
return false;
else if ( res < 0 || res >= mOptions.count() )
return false;
}
return true;
}
else if ( input.type() == QVariant::Int || input.type() == QVariant::Double )
{
bool ok = false;
int res = input.toInt( &ok );
if ( !ok )
return false;
else if ( res >= 0 && res < mOptions.count() )
return true;
}
return false;
}
QString QgsProcessingParameterEnum::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.type() == QVariant::List )
{
QStringList parts;
Q_FOREACH ( const QVariant &val, value.toList() )
{
parts << QString::number( static_cast< int >( val.toDouble() ) );
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
else if ( value.type() == QVariant::String )
{
QStringList parts = value.toString().split( ',' );
if ( parts.count() > 1 )
{
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
}
return QString::number( static_cast< int >( value.toDouble() ) );
}
QString QgsProcessingParameterEnum::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "enum " );
if ( mAllowMultiple )
code += QStringLiteral( "multiple " );
code += mOptions.join( ';' ) + ' ';
code += mDefault.toString();
return code.trimmed();
}
QStringList QgsProcessingParameterEnum::options() const
{
return mOptions;
}
void QgsProcessingParameterEnum::setOptions( const QStringList &options )
{
mOptions = options;
}
bool QgsProcessingParameterEnum::allowMultiple() const
{
return mAllowMultiple;
}
void QgsProcessingParameterEnum::setAllowMultiple( bool allowMultiple )
{
mAllowMultiple = allowMultiple;
}
QVariantMap QgsProcessingParameterEnum::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "options" ), mOptions );
map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
return map;
}
bool QgsProcessingParameterEnum::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mOptions = map.value( QStringLiteral( "options" ) ).toStringList();
mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
return true;
}
QgsProcessingParameterEnum *QgsProcessingParameterEnum::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString defaultVal;
bool multiple = false;
QString def = definition;
if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
{
multiple = true;
def = def.mid( 9 );
}
QRegularExpression re( QStringLiteral( "(.*)\\s+(.*?)$" ) );
QRegularExpressionMatch m = re.match( def );
QString values = def;
if ( m.hasMatch() )
{
values = m.captured( 1 ).trimmed();
defaultVal = m.captured( 2 );
}
return new QgsProcessingParameterEnum( name, description, values.split( ';' ), multiple, defaultVal.isEmpty() ? QVariant() : defaultVal, isOptional );
}
QgsProcessingParameterString::QgsProcessingParameterString( const QString &name, const QString &description, const QVariant &defaultValue, bool multiLine, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mMultiLine( multiLine )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterString::clone() const
{
return new QgsProcessingParameterString( *this );
}
QString QgsProcessingParameterString::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
QString s = value.toString();
return QgsProcessingUtils::stringToPythonLiteral( s );
}
QString QgsProcessingParameterString::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "string " );
if ( mMultiLine )
code += QStringLiteral( "long " );
code += mDefault.toString();
return code.trimmed();
}
bool QgsProcessingParameterString::multiLine() const
{
return mMultiLine;
}
void QgsProcessingParameterString::setMultiLine( bool multiLine )
{
mMultiLine = multiLine;
}
QVariantMap QgsProcessingParameterString::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "multiline" ), mMultiLine );
return map;
}
bool QgsProcessingParameterString::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mMultiLine = map.value( QStringLiteral( "multiline" ) ).toBool();
return true;
}
QgsProcessingParameterString *QgsProcessingParameterString::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString def = definition;
bool multiLine = false;
if ( def.startsWith( QLatin1String( "long" ), Qt::CaseInsensitive ) )
{
multiLine = true;
def = def.mid( 5 );
}
if ( def.startsWith( '"' ) || def.startsWith( '\'' ) )
def = def.mid( 1 );
if ( def.endsWith( '"' ) || def.endsWith( '\'' ) )
def.chop( 1 );
QVariant defaultValue = def;
if ( def == QStringLiteral( "None" ) )
defaultValue = QVariant();
return new QgsProcessingParameterString( name, description, defaultValue, multiLine, isOptional );
}
QgsProcessingParameterExpression::QgsProcessingParameterExpression( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mParentLayerParameterName( parentLayerParameterName )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterExpression::clone() const
{
return new QgsProcessingParameterExpression( *this );
}
QString QgsProcessingParameterExpression::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
QString s = value.toString();
return QgsProcessingUtils::stringToPythonLiteral( s );
}
QStringList QgsProcessingParameterExpression::dependsOnOtherParameters() const
{
QStringList depends;
if ( !mParentLayerParameterName.isEmpty() )
depends << mParentLayerParameterName;
return depends;
}
QString QgsProcessingParameterExpression::parentLayerParameterName() const
{
return mParentLayerParameterName;
}
void QgsProcessingParameterExpression::setParentLayerParameterName( const QString &parentLayerParameterName )
{
mParentLayerParameterName = parentLayerParameterName;
}
QVariantMap QgsProcessingParameterExpression::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
return map;
}
bool QgsProcessingParameterExpression::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
return true;
}
QgsProcessingParameterExpression *QgsProcessingParameterExpression::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterExpression( name, description, definition, QString(), isOptional );
}
QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, QgsProcessingParameterLimitedDataTypes( types )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterVectorLayer::clone() const
{
return new QgsProcessingParameterVectorLayer( *this );
}
bool QgsProcessingParameterVectorLayer::checkValueIsAcceptable( const QVariant &v, QgsProcessingContext *context ) const
{
if ( !v.isValid() )
return mFlags & FlagOptional;
QVariant var = v;
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
return true;
if ( var.type() != QVariant::String || var.toString().isEmpty() )
return mFlags & FlagOptional;
if ( !context )
{
// that's as far as we can get without a context
return true;
}
// try to load as layer
if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::Vector ) )
return true;
return false;
}
QString QgsProcessingParameterVectorLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
{
if ( !val.isValid() )
return QStringLiteral( "None" );
if ( val.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), val );
QgsVectorLayer *layer = QgsProcessingParameters::parameterAsVectorLayer( this, p, context );
return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) )
: QgsProcessingUtils::stringToPythonLiteral( val.toString() );
}
QList<int> QgsProcessingParameterLimitedDataTypes::dataTypes() const
{
return mDataTypes;
}
void QgsProcessingParameterLimitedDataTypes::setDataTypes( const QList<int> &types )
{
mDataTypes = types;
}
QVariantMap QgsProcessingParameterVectorLayer::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
QVariantList types;
Q_FOREACH ( int type, mDataTypes )
{
types << type;
}
map.insert( QStringLiteral( "data_types" ), types );
return map;
}
bool QgsProcessingParameterVectorLayer::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mDataTypes.clear();
QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
Q_FOREACH ( const QVariant &val, values )
{
mDataTypes << val.toInt();
}
return true;
}
QgsProcessingParameterVectorLayer *QgsProcessingParameterVectorLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterVectorLayer( name, description, QList< int>(), definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mParentLayerParameterName( parentLayerParameterName )
, mDataType( type )
, mAllowMultiple( allowMultiple )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterField::clone() const
{
return new QgsProcessingParameterField( *this );
}
bool QgsProcessingParameterField::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
{
if ( !mAllowMultiple )
return false;
if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
return false;
}
else if ( input.type() == QVariant::String )
{
if ( input.toString().isEmpty() )
return mFlags & FlagOptional;
QStringList parts = input.toString().split( ';' );
if ( parts.count() > 1 && !mAllowMultiple )
return false;
}
else
{
if ( input.toString().isEmpty() )
return mFlags & FlagOptional;
}
return true;
}
QString QgsProcessingParameterField::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.type() == QVariant::List )
{
QStringList parts;
Q_FOREACH ( const QVariant &val, value.toList() )
{
parts << QgsProcessingUtils::stringToPythonLiteral( val.toString() );
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
else if ( value.type() == QVariant::StringList )
{
QStringList parts;
Q_FOREACH ( QString s, value.toStringList() )
{
parts << QgsProcessingUtils::stringToPythonLiteral( s );
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}
QString QgsProcessingParameterField::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "field " );
switch ( mDataType )
{
case Numeric:
code += QStringLiteral( "numeric " );
break;
case String:
code += QStringLiteral( "string " );
break;
case DateTime:
code += QStringLiteral( "datetime " );
break;
case Any:
break;
}
if ( mAllowMultiple )
code += QStringLiteral( "multiple " );
code += mParentLayerParameterName + ' ';
code += mDefault.toString();
return code.trimmed();
}
QStringList QgsProcessingParameterField::dependsOnOtherParameters() const
{
QStringList depends;
if ( !mParentLayerParameterName.isEmpty() )
depends << mParentLayerParameterName;
return depends;
}
QString QgsProcessingParameterField::parentLayerParameterName() const
{
return mParentLayerParameterName;
}
void QgsProcessingParameterField::setParentLayerParameterName( const QString &parentLayerParameterName )
{
mParentLayerParameterName = parentLayerParameterName;
}
QgsProcessingParameterField::DataType QgsProcessingParameterField::dataType() const
{
return mDataType;
}
void QgsProcessingParameterField::setDataType( DataType dataType )
{
mDataType = dataType;
}
bool QgsProcessingParameterField::allowMultiple() const
{
return mAllowMultiple;
}
void QgsProcessingParameterField::setAllowMultiple( bool allowMultiple )
{
mAllowMultiple = allowMultiple;
}
QVariantMap QgsProcessingParameterField::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
map.insert( QStringLiteral( "data_type" ), mDataType );
map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
return map;
}
bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
mDataType = static_cast< DataType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
return true;
}
QgsProcessingParameterField *QgsProcessingParameterField::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString parent;
DataType type = Any;
bool allowMultiple = false;
QString def = definition;
if ( def.startsWith( QLatin1String( "numeric " ), Qt::CaseInsensitive ) )
{
type = Numeric;
def = def.mid( 8 );
}
else if ( def.startsWith( QLatin1String( "string " ), Qt::CaseInsensitive ) )
{
type = String;
def = def.mid( 7 );
}
else if ( def.startsWith( QLatin1String( "datetime " ), Qt::CaseInsensitive ) )
{
type = DateTime;
def = def.mid( 9 );
}
if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
{
allowMultiple = true;
def = def.mid( 8 ).trimmed();
}
QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
QRegularExpressionMatch m = re.match( def );
if ( m.hasMatch() )
{
parent = m.captured( 1 ).trimmed();
def = m.captured( 2 );
}
else
{
parent = def;
def.clear();
}
return new QgsProcessingParameterField( name, description, def.isEmpty() ? QVariant() : def, parent, type, allowMultiple, isOptional );
}
QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const QString &name, const QString &description, const QList<int> &types, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, QgsProcessingParameterLimitedDataTypes( types )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterFeatureSource::clone() const
{
return new QgsProcessingParameterFeatureSource( *this );
}
bool QgsProcessingParameterFeatureSource::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
var = fromVar.source;
}
else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
{
return true;
}
if ( var.type() != QVariant::String || var.toString().isEmpty() )
return mFlags & FlagOptional;
if ( !context )
{
// that's as far as we can get without a context
return true;
}
// try to load as layer
if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context, true, QgsProcessingUtils::Vector ) )
return true;
return false;
}
QString QgsProcessingParameterFeatureSource::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
if ( fromVar.source.propertyType() == QgsProperty::StaticProperty )
{
if ( fromVar.selectedFeaturesOnly )
{
return QStringLiteral( "QgsProcessingFeatureSourceDefinition('%1', True)" ).arg( fromVar.source.staticValue().toString() );
}
else
{
QString layerString = fromVar.source.staticValue().toString();
// prefer to use layer source instead of id if possible (since it's persistent)
if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::Vector ) ) )
layerString = layer->source();
return QgsProcessingUtils::stringToPythonLiteral( layerString );
}
}
else
{
if ( fromVar.selectedFeaturesOnly )
{
return QStringLiteral( "QgsProcessingFeatureSourceDefinition(QgsProperty.fromExpression('%1'), True)" ).arg( fromVar.source.asExpression() );
}
else
{
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.source.asExpression() );
}
}
}
else if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
{
return QgsProcessingUtils::stringToPythonLiteral( layer->source() );
}
QString layerString = value.toString();
// prefer to use layer source if possible (since it's persistent)
if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerString, context, true, QgsProcessingUtils::Vector ) ) )
layerString = layer->source();
return QgsProcessingUtils::stringToPythonLiteral( layerString );
}
QString QgsProcessingParameterFeatureSource::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "source " );
Q_FOREACH ( int type, mDataTypes )
{
switch ( type )
{
case QgsProcessing::TypeVectorPoint:
code += QStringLiteral( "point " );
break;
case QgsProcessing::TypeVectorLine:
code += QStringLiteral( "line " );
break;
case QgsProcessing::TypeVectorPolygon:
code += QStringLiteral( "polygon " );
break;
}
}
code += mDefault.toString();
return code.trimmed();
}
QgsProcessingParameterLimitedDataTypes::QgsProcessingParameterLimitedDataTypes( const QList<int> &types )
: mDataTypes( types )
{
}
QVariantMap QgsProcessingParameterFeatureSource::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
QVariantList types;
Q_FOREACH ( int type, mDataTypes )
{
types << type;
}
map.insert( QStringLiteral( "data_types" ), types );
return map;
}
bool QgsProcessingParameterFeatureSource::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mDataTypes.clear();
QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
Q_FOREACH ( const QVariant &val, values )
{
mDataTypes << val.toInt();
}
return true;
}
QgsProcessingParameterFeatureSource *QgsProcessingParameterFeatureSource::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QList< int > types;
QString def = definition;
while ( true )
{
if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
{
types << QgsProcessing::TypeVectorPoint;
def = def.mid( 6 );
continue;
}
else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
{
types << QgsProcessing::TypeVectorLine;
def = def.mid( 5 );
continue;
}
else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
{
types << QgsProcessing::TypeVectorPolygon;
def = def.mid( 8 );
continue;
}
break;
}
return new QgsProcessingParameterFeatureSource( name, description, types, def, isOptional );
}
QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
, mDataType( type )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterFeatureSink::clone() const
{
return new QgsProcessingParameterFeatureSink( *this );
}
bool QgsProcessingParameterFeatureSink::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( var.type() != QVariant::String )
return false;
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
QString QgsProcessingParameterFeatureSink::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
{
return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
}
else
{
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
}
}
return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}
QString QgsProcessingParameterFeatureSink::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "sink " );
switch ( mDataType )
{
case QgsProcessing::TypeVectorPoint:
code += QStringLiteral( "point " );
break;
case QgsProcessing::TypeVectorLine:
code += QStringLiteral( "line " );
break;
case QgsProcessing::TypeVectorPolygon:
code += QStringLiteral( "polygon " );
break;
case QgsProcessing::TypeVector:
code += QStringLiteral( "table " );
break;
default:
break;
}
code += mDefault.toString();
return code.trimmed();
}
QgsProcessingOutputDefinition *QgsProcessingParameterFeatureSink::toOutputDefinition() const
{
return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
}
QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
{
if ( originalProvider() )
{
return originalProvider()->defaultVectorFileExtension( hasGeometry() );
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->defaultVectorFileExtension( hasGeometry() );
}
else
{
QgsSettings settings;
if ( hasGeometry() )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
}
else
{
return QStringLiteral( "dbf" );
}
}
}
QStringList QgsProcessingParameterFeatureSink::supportedOutputVectorLayerExtensions() const
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputVectorLayerExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputVectorLayerExtensions();
}
else
{
return QgsVectorFileWriter::supportedFormatExtensions();
}
}
QgsProcessing::SourceType QgsProcessingParameterFeatureSink::dataType() const
{
return mDataType;
}
bool QgsProcessingParameterFeatureSink::hasGeometry() const
{
switch ( mDataType )
{
case QgsProcessing::TypeMapLayer:
case QgsProcessing::TypeVectorAnyGeometry:
case QgsProcessing::TypeVectorPoint:
case QgsProcessing::TypeVectorLine:
case QgsProcessing::TypeVectorPolygon:
case QgsProcessing::TypeVector:
return true;
case QgsProcessing::TypeRaster:
case QgsProcessing::TypeFile:
return false;
}
return true;
}
void QgsProcessingParameterFeatureSink::setDataType( QgsProcessing::SourceType type )
{
mDataType = type;
}
QVariantMap QgsProcessingParameterFeatureSink::toVariantMap() const
{
QVariantMap map = QgsProcessingDestinationParameter::toVariantMap();
map.insert( QStringLiteral( "data_type" ), mDataType );
return map;
}
bool QgsProcessingParameterFeatureSink::fromVariantMap( const QVariantMap &map )
{
QgsProcessingDestinationParameter::fromVariantMap( map );
mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
return true;
}
QString QgsProcessingParameterFeatureSink::generateTemporaryDestination() const
{
if ( supportsNonFileBasedOutput() )
return QStringLiteral( "memory:%1" ).arg( description() );
else
return QgsProcessingDestinationParameter::generateTemporaryDestination();
}
QgsProcessingParameterFeatureSink *QgsProcessingParameterFeatureSink::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QgsProcessing::SourceType type = QgsProcessing::TypeVectorAnyGeometry;
QString def = definition;
if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVectorPoint;
def = def.mid( 6 );
}
else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVectorLine;
def = def.mid( 5 );
}
else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVectorPolygon;
def = def.mid( 8 );
}
else if ( def.startsWith( QLatin1String( "table" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVector;
def = def.mid( 6 );
}
return new QgsProcessingParameterFeatureSink( name, description, type, definition, isOptional );
}
QgsProcessingParameterRasterDestination::QgsProcessingParameterRasterDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterRasterDestination::clone() const
{
return new QgsProcessingParameterRasterDestination( *this );
}
bool QgsProcessingParameterRasterDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( var.type() != QVariant::String )
return false;
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
QString QgsProcessingParameterRasterDestination::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
{
return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
}
else
{
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
}
}
return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}
QgsProcessingOutputDefinition *QgsProcessingParameterRasterDestination::toOutputDefinition() const
{
return new QgsProcessingOutputRasterLayer( name(), description() );
}
QString QgsProcessingParameterRasterDestination::defaultFileExtension() const
{
if ( originalProvider() )
{
return originalProvider()->defaultRasterFileExtension();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->defaultRasterFileExtension();
}
else
{
QgsSettings settings;
return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
}
}
QStringList QgsProcessingParameterRasterDestination::supportedOutputRasterLayerExtensions() const
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputRasterLayerExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputRasterLayerExtensions();
}
else
{
return QgsRasterFileWriter::supportedFormatExtensions();
}
}
QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingParameterFileDestination::QgsProcessingParameterFileDestination( const QString &name, const QString &description, const QString &fileFilter, const QVariant &defaultValue, bool optional, bool createByDefault )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
, mFileFilter( fileFilter.isEmpty() ? QObject::tr( "All files (*.*)" ) : fileFilter )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterFileDestination::clone() const
{
return new QgsProcessingParameterFileDestination( *this );
}
bool QgsProcessingParameterFileDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( var.type() != QVariant::String )
return false;
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;
// possible enhancement - check that value is compatible with file filter?
return true;
}
QString QgsProcessingParameterFileDestination::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
{
return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
}
else
{
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
}
}
return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}
QgsProcessingOutputDefinition *QgsProcessingParameterFileDestination::toOutputDefinition() const
{
if ( !mFileFilter.isEmpty() && mFileFilter.contains( QStringLiteral( "htm" ), Qt::CaseInsensitive ) )
{
return new QgsProcessingOutputHtml( name(), description() );
}
else
{
return new QgsProcessingOutputFile( name(), description() );
}
}
QString QgsProcessingParameterFileDestination::defaultFileExtension() const
{
if ( mFileFilter.isEmpty() || mFileFilter == QObject::tr( "All files (*.*)" ) )
return QStringLiteral( "file" );
// get first extension from filter
QRegularExpression rx( QStringLiteral( ".*?\\(\\*\\.([a-zA-Z0-9._]+).*" ) );
QRegularExpressionMatch match = rx.match( mFileFilter );
if ( !match.hasMatch() )
return QStringLiteral( "file" );
return match.captured( 1 );
}
QString QgsProcessingParameterFileDestination::fileFilter() const
{
return mFileFilter;
}
void QgsProcessingParameterFileDestination::setFileFilter( const QString &fileFilter )
{
mFileFilter = fileFilter;
}
QVariantMap QgsProcessingParameterFileDestination::toVariantMap() const
{
QVariantMap map = QgsProcessingDestinationParameter::toVariantMap();
map.insert( QStringLiteral( "file_filter" ), mFileFilter );
return map;
}
bool QgsProcessingParameterFileDestination::fromVariantMap( const QVariantMap &map )
{
QgsProcessingDestinationParameter::fromVariantMap( map );
mFileFilter = map.value( QStringLiteral( "file_filter" ) ).toString();
return true;
}
QgsProcessingParameterFileDestination *QgsProcessingParameterFileDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterFileDestination( name, description, QString(), definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingParameterFolderDestination::QgsProcessingParameterFolderDestination( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional )
{}
QgsProcessingParameterDefinition *QgsProcessingParameterFolderDestination::clone() const
{
return new QgsProcessingParameterFolderDestination( *this );
}
bool QgsProcessingParameterFolderDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( var.type() != QVariant::String )
return false;
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
QgsProcessingOutputDefinition *QgsProcessingParameterFolderDestination::toOutputDefinition() const
{
return new QgsProcessingOutputFolder( name(), description() );
}
QString QgsProcessingParameterFolderDestination::defaultFileExtension() const
{
return QString();
}
QgsProcessingParameterFolderDestination *QgsProcessingParameterFolderDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterFolderDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
}
QgsProcessingDestinationParameter::QgsProcessingDestinationParameter( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, bool createByDefault )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mCreateByDefault( createByDefault )
{
}
QVariantMap QgsProcessingDestinationParameter::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
return map;
}
bool QgsProcessingDestinationParameter::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
return true;
}
QString QgsProcessingDestinationParameter::generateTemporaryDestination() const
{
if ( defaultFileExtension().isEmpty() )
{
return QgsProcessingUtils::generateTempFilename( name() );
}
else
{
return QgsProcessingUtils::generateTempFilename( name() + '.' + defaultFileExtension() );
}
}
bool QgsProcessingDestinationParameter::createByDefault() const
{
return mCreateByDefault;
}
void QgsProcessingDestinationParameter::setCreateByDefault( bool createByDefault )
{
mCreateByDefault = createByDefault;
}
QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::SourceType type, const QVariant &defaultValue, bool optional, bool createByDefault )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional, createByDefault )
, mDataType( type )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterVectorDestination::clone() const
{
return new QgsProcessingParameterVectorDestination( *this );
}
bool QgsProcessingParameterVectorDestination::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
else
{
return true;
}
}
if ( var.type() != QVariant::String )
return false;
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
QString QgsProcessingParameterVectorDestination::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
{
return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() );
}
else
{
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( fromVar.sink.asExpression() );
}
}
return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
}
QString QgsProcessingParameterVectorDestination::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "vectorDestination " );
switch ( mDataType )
{
case QgsProcessing::TypeVectorPoint:
code += QStringLiteral( "point " );
break;
case QgsProcessing::TypeVectorLine:
code += QStringLiteral( "line " );
break;
case QgsProcessing::TypeVectorPolygon:
code += QStringLiteral( "polygon " );
break;
default:
break;
}
code += mDefault.toString();
return code.trimmed();
}
QgsProcessingOutputDefinition *QgsProcessingParameterVectorDestination::toOutputDefinition() const
{
return new QgsProcessingOutputVectorLayer( name(), description(), mDataType );
}
QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
{
if ( originalProvider() )
{
return originalProvider()->defaultVectorFileExtension( hasGeometry() );
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->defaultVectorFileExtension( hasGeometry() );
}
else
{
QgsSettings settings;
if ( hasGeometry() )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
}
else
{
return QStringLiteral( "dbf" );
}
}
}
QStringList QgsProcessingParameterVectorDestination::supportedOutputVectorLayerExtensions() const
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputVectorLayerExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputVectorLayerExtensions();
}
else
{
return QgsVectorFileWriter::supportedFormatExtensions();
}
}
QgsProcessing::SourceType QgsProcessingParameterVectorDestination::dataType() const
{
return mDataType;
}
bool QgsProcessingParameterVectorDestination::hasGeometry() const
{
switch ( mDataType )
{
case QgsProcessing::TypeMapLayer:
case QgsProcessing::TypeVectorAnyGeometry:
case QgsProcessing::TypeVectorPoint:
case QgsProcessing::TypeVectorLine:
case QgsProcessing::TypeVectorPolygon:
case QgsProcessing::TypeVector:
return true;
case QgsProcessing::TypeRaster:
case QgsProcessing::TypeFile:
return false;
}
return true;
}
void QgsProcessingParameterVectorDestination::setDataType( QgsProcessing::SourceType type )
{
mDataType = type;
}
QVariantMap QgsProcessingParameterVectorDestination::toVariantMap() const
{
QVariantMap map = QgsProcessingDestinationParameter::toVariantMap();
map.insert( QStringLiteral( "data_type" ), mDataType );
return map;
}
bool QgsProcessingParameterVectorDestination::fromVariantMap( const QVariantMap &map )
{
QgsProcessingDestinationParameter::fromVariantMap( map );
mDataType = static_cast< QgsProcessing::SourceType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
return true;
}
QgsProcessingParameterVectorDestination *QgsProcessingParameterVectorDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QgsProcessing::SourceType type = QgsProcessing::TypeVectorAnyGeometry;
QString def = definition;
if ( def.startsWith( QLatin1String( "point" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVectorPoint;
def = def.mid( 6 );
}
else if ( def.startsWith( QLatin1String( "line" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVectorLine;
def = def.mid( 5 );
}
else if ( def.startsWith( QLatin1String( "polygon" ), Qt::CaseInsensitive ) )
{
type = QgsProcessing::TypeVectorPolygon;
def = def.mid( 8 );
}
return new QgsProcessingParameterVectorDestination( name, description, type, definition, isOptional );
}
QgsProcessingParameterBand::QgsProcessingParameterBand( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, bool optional, bool allowMultiple )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mParentLayerParameterName( parentLayerParameterName )
, mAllowMultiple( allowMultiple )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterBand::clone() const
{
return new QgsProcessingParameterBand( *this );
}
bool QgsProcessingParameterBand::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.canConvert<QgsProperty>() )
{
return true;
}
if ( input.type() == QVariant::List || input.type() == QVariant::StringList )
{
if ( !mAllowMultiple )
return false;
if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
return false;
}
else
{
bool ok = false;
double res = input.toInt( &ok );
Q_UNUSED( res );
if ( !ok )
return mFlags & FlagOptional;
}
return true;
}
bool QgsProcessingParameterBand::allowMultiple() const
{
return mAllowMultiple;
}
void QgsProcessingParameterBand::setAllowMultiple( bool allowMultiple )
{
mAllowMultiple = allowMultiple;
}
QString QgsProcessingParameterBand::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( !value.isValid() )
return QStringLiteral( "None" );
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.type() == QVariant::List )
{
QStringList parts;
QVariantList values = value.toList();
for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
{
parts << QString::number( static_cast< int >( it->toDouble() ) );
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
else if ( value.type() == QVariant::StringList )
{
QStringList parts;
QStringList values = value.toStringList();
for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
{
parts << QString::number( static_cast< int >( it->toDouble() ) );
}
return parts.join( ',' ).prepend( '[' ).append( ']' );
}
return value.toString();
}
QString QgsProcessingParameterBand::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "band " );
if ( mAllowMultiple )
code += QStringLiteral( "multiple " );
code += mParentLayerParameterName + ' ';
code += mDefault.toString();
return code.trimmed();
}
QStringList QgsProcessingParameterBand::dependsOnOtherParameters() const
{
QStringList depends;
if ( !mParentLayerParameterName.isEmpty() )
depends << mParentLayerParameterName;
return depends;
}
QString QgsProcessingParameterBand::parentLayerParameterName() const
{
return mParentLayerParameterName;
}
void QgsProcessingParameterBand::setParentLayerParameterName( const QString &parentLayerParameterName )
{
mParentLayerParameterName = parentLayerParameterName;
}
QVariantMap QgsProcessingParameterBand::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
map.insert( QStringLiteral( "allow_multiple" ), mAllowMultiple );
return map;
}
bool QgsProcessingParameterBand::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
mAllowMultiple = map.value( QStringLiteral( "allow_multiple" ) ).toBool();
return true;
}
QgsProcessingParameterBand *QgsProcessingParameterBand::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString parent;
QString def = definition;
bool allowMultiple = false;
if ( def.startsWith( QLatin1String( "multiple" ), Qt::CaseInsensitive ) )
{
allowMultiple = true;
def = def.mid( 8 ).trimmed();
}
QRegularExpression re( QStringLiteral( "(.*?)\\s+(.*)$" ) );
QRegularExpressionMatch m = re.match( def );
if ( m.hasMatch() )
{
parent = m.captured( 1 ).trimmed();
def = m.captured( 2 );
}
else
{
parent = def;
def.clear();
}
return new QgsProcessingParameterBand( name, description, def.isEmpty() ? QVariant() : def, parent, isOptional, allowMultiple );
}
//
// QgsProcessingParameterDistance
//
QgsProcessingParameterDistance::QgsProcessingParameterDistance( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentParameterName, bool optional, double minValue, double maxValue )
: QgsProcessingParameterNumber( name, description, Double, defaultValue, optional, minValue, maxValue )
, mParentParameterName( parentParameterName )
{
}
QgsProcessingParameterDistance *QgsProcessingParameterDistance::clone() const
{
return new QgsProcessingParameterDistance( *this );
}
QString QgsProcessingParameterDistance::type() const
{
return typeName();
}
QStringList QgsProcessingParameterDistance::dependsOnOtherParameters() const
{
QStringList depends;
if ( !mParentParameterName.isEmpty() )
depends << mParentParameterName;
return depends;
}
QString QgsProcessingParameterDistance::parentParameterName() const
{
return mParentParameterName;
}
void QgsProcessingParameterDistance::setParentParameterName( const QString &parentParameterName )
{
mParentParameterName = parentParameterName;
}
QVariantMap QgsProcessingParameterDistance::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterNumber::toVariantMap();
map.insert( QStringLiteral( "parent" ), mParentParameterName );
return map;
}
bool QgsProcessingParameterDistance::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterNumber::fromVariantMap( map );
mParentParameterName = map.value( QStringLiteral( "parent" ) ).toString();
return true;
}