Skip to content

Commit

Permalink
[feature][processing] data types support for map layer parameter.
Browse files Browse the repository at this point in the history
Allow to define accepted layer types for map layer parameters, for
example vector points and rasters.
  • Loading branch information
alexbruy committed Mar 14, 2020
1 parent 465f8a5 commit 0181d10
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 72 deletions.
Expand Up @@ -1304,44 +1304,6 @@ Creates a new parameter using the definition from a script code.

};

class QgsProcessingParameterMapLayer : QgsProcessingParameterDefinition
{
%Docstring
A map layer parameter for processing algorithms.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsprocessingparameters.h"
%End
public:

QgsProcessingParameterMapLayer( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false );
%Docstring
Constructor for QgsProcessingParameterMapLayer.
%End

static QString typeName();
%Docstring
Returns the type name for the parameter class.
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;


static QgsProcessingParameterMapLayer *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) /Factory/;
%Docstring
Creates a new parameter using the definition from a script code.
%End

};

class QgsProcessingParameterExtent : QgsProcessingParameterDefinition
{
%Docstring
Expand Down Expand Up @@ -2421,6 +2383,54 @@ Creates a new parameter using the definition from a script code.
%End
};

class QgsProcessingParameterMapLayer : QgsProcessingParameterDefinition, QgsProcessingParameterLimitedDataTypes
{
%Docstring
A map layer parameter for processing algorithms.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsprocessingparameters.h"
%End
public:

QgsProcessingParameterMapLayer( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false,
const QList< int > &types = QList< int >() );
%Docstring
Constructor for QgsProcessingParameterMapLayer.
%End

static QString typeName();
%Docstring
Returns the type name for the parameter class.
%End
virtual QgsProcessingParameterDefinition *clone() const /Factory/;

virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;

virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;

virtual QString asScriptCode() const;

virtual QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const;


virtual QVariantMap toVariantMap() const;

virtual bool fromVariantMap( const QVariantMap &map );


static QgsProcessingParameterMapLayer *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) /Factory/;
%Docstring
Creates a new parameter using the definition from a script code.
%End

};

class QgsProcessingParameterField : QgsProcessingParameterDefinition
{
%Docstring
Expand Down
148 changes: 146 additions & 2 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -2212,8 +2212,9 @@ QgsProcessingParameterCrs *QgsProcessingParameterCrs::fromScriptCode( const QStr
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 )
QgsProcessingParameterMapLayer::QgsProcessingParameterMapLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional, const QList<int> &types )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, QgsProcessingParameterLimitedDataTypes( types )
{

}
Expand Down Expand Up @@ -2269,9 +2270,152 @@ QString QgsProcessingParameterMapLayer::valueAsPythonString( const QVariant &val
: QgsProcessingUtils::stringToPythonLiteral( val.toString() );
}

QString QgsProcessingParameterMapLayer::asScriptCode() const
{
QString code = QStringLiteral( "##%1=" ).arg( mName );
if ( mFlags & FlagOptional )
code += QStringLiteral( "optional " );
code += QStringLiteral( "layer " );

const auto constMDataTypes = mDataTypes;
for ( int type : constMDataTypes )
{
switch ( type )
{
case QgsProcessing::TypeVectorAnyGeometry:
code += QStringLiteral( "hasgeometry " );
break;

case QgsProcessing::TypeVectorPoint:
code += QStringLiteral( "point " );
break;

case QgsProcessing::TypeVectorLine:
code += QStringLiteral( "line " );
break;

case QgsProcessing::TypeVectorPolygon:
code += QStringLiteral( "polygon " );
break;

case QgsProcessing::TypeRaster:
code += QStringLiteral( "raster " );
break;

case QgsProcessing::TypeMesh:
code += QStringLiteral( "mesh " );
break;
}
}

code += mDefault.toString();
return code.trimmed();
}

QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterMapLayer( name, description, definition, isOptional );
QList< int > types;
QString def = definition;
while ( true )
{
if ( def.startsWith( QLatin1String( "hasgeometry" ), Qt::CaseInsensitive ) )
{
types << QgsProcessing::TypeVectorAnyGeometry;
def = def.mid( 12 );
continue;
}
else 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;
}
else if ( def.startsWith( QLatin1String( "raster" ), Qt::CaseInsensitive ) )
{
types << QgsProcessing::TypeRaster;
def = def.mid( 7 );
continue;
}
else if ( def.startsWith( QLatin1String( "mesh" ), Qt::CaseInsensitive ) )
{
types << QgsProcessing::TypeMesh;
def = def.mid( 5 );
continue;
}
break;
}

return new QgsProcessingParameterMapLayer( name, description, def, isOptional, types );
}

QString QgsProcessingParameterMapLayer::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
{
switch ( outputType )
{
case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
{
QString code = QStringLiteral( "QgsProcessingParameterMapLayer('%1', '%2'" ).arg( name(), description() );
if ( mFlags & FlagOptional )
code += QStringLiteral( ", optional=True" );

QgsProcessingContext c;
code += QStringLiteral( ", defaultValue=%1" ).arg( valueAsPythonString( mDefault, c ) );

if ( !mDataTypes.empty() )
{
QStringList options;
options.reserve( mDataTypes.size() );
for ( int t : mDataTypes )
options << QStringLiteral( "QgsProcessing.%1" ).arg( QgsProcessing::sourceTypeToString( static_cast< QgsProcessing::SourceType >( t ) ) );
code += QStringLiteral( ", types=[%1])" ).arg( options.join( ',' ) );
}
else
{
code += QStringLiteral( ")" );
}

return code;
}
}
return QString();
}

QVariantMap QgsProcessingParameterMapLayer::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
QVariantList types;
const auto constMDataTypes = mDataTypes;
for ( int type : constMDataTypes )
{
types << type;
}
map.insert( QStringLiteral( "data_types" ), types );
return map;
}

bool QgsProcessingParameterMapLayer::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mDataTypes.clear();
QVariantList values = map.value( QStringLiteral( "data_types" ) ).toList();
const auto constValues = values;
for ( const QVariant &val : constValues )
{
mDataTypes << val.toInt();
}
return true;
}

QgsProcessingParameterExtent::QgsProcessingParameterExtent( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
Expand Down
70 changes: 38 additions & 32 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -1327,38 +1327,6 @@ class CORE_EXPORT QgsProcessingParameterCrs : public QgsProcessingParameterDefin

};

/**
* \class QgsProcessingParameterMapLayer
* \ingroup core
* A map layer parameter for processing algorithms.
* \since QGIS 3.0
*/
class CORE_EXPORT QgsProcessingParameterMapLayer : public QgsProcessingParameterDefinition
{
public:

/**
* Constructor for QgsProcessingParameterMapLayer.
*/
QgsProcessingParameterMapLayer( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false );

/**
* Returns the type name for the parameter class.
*/
static QString typeName() { return QStringLiteral( "layer" ); }
QgsProcessingParameterDefinition *clone() const override SIP_FACTORY;
QString type() const override { return typeName(); }
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;

/**
* Creates a new parameter using the definition from a script code.
*/
static QgsProcessingParameterMapLayer *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;

};

/**
* \class QgsProcessingParameterExtent
* \ingroup core
Expand Down Expand Up @@ -2309,6 +2277,44 @@ class CORE_EXPORT QgsProcessingParameterMeshLayer : public QgsProcessingParamete
static QgsProcessingParameterMeshLayer *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;
};

/**
* \class QgsProcessingParameterMapLayer
* \ingroup core
* A map layer parameter for processing algorithms.
* \since QGIS 3.0
*/
class CORE_EXPORT QgsProcessingParameterMapLayer : public QgsProcessingParameterDefinition, public QgsProcessingParameterLimitedDataTypes
{
public:

/**
* Constructor for QgsProcessingParameterMapLayer.
*/
QgsProcessingParameterMapLayer( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false,
const QList< int > &types = QList< int >() );

/**
* Returns the type name for the parameter class.
*/
static QString typeName() { return QStringLiteral( "layer" ); }
QgsProcessingParameterDefinition *clone() const override SIP_FACTORY;
QString type() const override { return typeName(); }
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;
QString asScriptCode() const override;
QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const override;

QVariantMap toVariantMap() const override;
bool fromVariantMap( const QVariantMap &map ) override;

/**
* Creates a new parameter using the definition from a script code.
*/
static QgsProcessingParameterMapLayer *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;

};

/**
* \class QgsProcessingParameterField
* \ingroup core
Expand Down

0 comments on commit 0181d10

Please sign in to comment.