Skip to content

Commit

Permalink
Add geometry processing parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
dmarteau authored and nyalldawson committed Sep 14, 2020
1 parent cd04374 commit 4eb931e
Show file tree
Hide file tree
Showing 13 changed files with 638 additions and 0 deletions.
Expand Up @@ -235,6 +235,8 @@ their acceptable ranges, defaults, etc.
sipType = sipType_QgsProcessingParameterExtent;
else if ( sipCpp->type() == QgsProcessingParameterPoint::typeName() )
sipType = sipType_QgsProcessingParameterPoint;
else if ( sipCpp->type() == QgsProcessingParameterGeometry::typeName() )
sipType = sipType_QgsProcessingParameterGeometry;
else if ( sipCpp->type() == QgsProcessingParameterFile::typeName() )
sipType = sipType_QgsProcessingParameterFile;
else if ( sipCpp->type() == QgsProcessingParameterMatrix::typeName() )
Expand Down Expand Up @@ -1170,6 +1172,20 @@ Returns the coordinate reference system associated with an point parameter value
.. seealso:: :py:func:`parameterAsPoint`

.. versionadded:: 3.8
%End

static QgsGeometry parameterAsGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context );
%Docstring
Evaluates the parameter with matching ``definition`` to a geometry.

.. versionadded:: 3.16
%End

static QgsGeometry parameterAsGeometry( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context );
%Docstring
Evaluates the parameter with matching ``definition`` and ``value`` to a geometry.

.. versionadded:: 3.16
%End

static QString parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context );
Expand Down Expand Up @@ -1527,6 +1543,43 @@ Creates a new parameter using the definition from a script code.

};

class QgsProcessingParameterGeometry : QgsProcessingParameterDefinition
{
%Docstring
A geometry parameter for processing algorithms.

.. versionadded:: 3.16
%End

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

QgsProcessingParameterGeometry( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(), bool optional = false );
%Docstring
Constructor for QgsProcessingParameterGeometry.
%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 QgsProcessingParameterGeometry *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 QgsProcessingParameterFile : QgsProcessingParameterDefinition
{
%Docstring
Expand Down
5 changes: 5 additions & 0 deletions python/plugins/processing/core/parameters.py
Expand Up @@ -42,6 +42,7 @@
QgsProcessingParameterCrs,
QgsProcessingParameterRange,
QgsProcessingParameterPoint,
QgsProcessingParameterGeometry,
QgsProcessingParameterEnum,
QgsProcessingParameterExtent,
QgsProcessingParameterExpression,
Expand Down Expand Up @@ -74,6 +75,7 @@
PARAMETER_EXTENT = 'extent'
PARAMETER_FILE = 'file'
PARAMETER_POINT = 'point'
PARAMETER_GEOMETRY = 'geometry'
PARAMETER_CRS = 'crs'
PARAMETER_MULTIPLE = 'multilayer'
PARAMETER_BAND = 'band'
Expand Down Expand Up @@ -129,6 +131,9 @@ def getParameterFromString(s, context=''):
elif clazz == QgsProcessingParameterPoint:
if len(params) > 3:
params[3] = True if params[3].lower() == 'true' else False
elif clazz == QgsProcessingParameterGeometry:
if len(params) > 3:
params[3] = True if params[3].lower() == 'true' else False
elif clazz == QgsProcessingParameterCrs:
if len(params) > 3:
params[3] = True if params[3].lower() == 'true' else False
Expand Down
4 changes: 4 additions & 0 deletions python/processing/algfactory.py
Expand Up @@ -50,6 +50,7 @@
QgsProcessingParameterMatrix,
QgsProcessingParameterMultipleLayers,
QgsProcessingParameterPoint,
QgsProcessingParameterGeometry,
QgsProcessingParameterRange,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterVectorLayer,
Expand Down Expand Up @@ -326,6 +327,7 @@ class ProcessingAlgFactory():
FIELD = "FIELD",
MATRIX = "MATRIX",
POINT = "POINT",
GEOMETRY = "GEOMETRY",
RANGE = "RANGE",
AUTH_CFG = "AUTH_CFG"
SCALE = "SCALE"
Expand Down Expand Up @@ -462,6 +464,7 @@ def input(self, type, *args, **kwargs):
alg.MATRIX: QgsProcessingParameterMatrix
alg.MULTILAYER: QgsProcessingParameterMultipleLayers
alg.POINT: QgsProcessingParameterPoint
alg.GEOMETRY: QgsProcessingParameterGeometry
alg.RANGE: QgsProcessingParameterRange
alg.VECTOR_LAYER: QgsProcessingParameterVectorLayer
alg.AUTH_CFG: QgsProcessingParameterAuthConfig
Expand Down Expand Up @@ -519,6 +522,7 @@ def dec(f):
ProcessingAlgFactory.MATRIX: QgsProcessingParameterMatrix,
ProcessingAlgFactory.MULTILAYER: QgsProcessingParameterMultipleLayers,
ProcessingAlgFactory.POINT: QgsProcessingParameterPoint,
ProcessingAlgFactory.GEOMETRY: QgsProcessingParameterGeometry,
ProcessingAlgFactory.RANGE: QgsProcessingParameterRange,
ProcessingAlgFactory.VECTOR_LAYER: QgsProcessingParameterVectorLayer,
ProcessingAlgFactory.AUTH_CFG: QgsProcessingParameterAuthConfig,
Expand Down
1 change: 1 addition & 0 deletions src/core/processing/models/qgsprocessingmodelalgorithm.cpp
Expand Up @@ -851,6 +851,7 @@ QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingMode
<< QgsProcessingParameterCrs::typeName()
<< QgsProcessingParameterRange::typeName()
<< QgsProcessingParameterPoint::typeName()
<< QgsProcessingParameterGeometry::typeName()
<< QgsProcessingParameterFile::typeName()
<< QgsProcessingParameterFolderDestination::typeName()
<< QgsProcessingParameterBand::typeName()
Expand Down
102 changes: 102 additions & 0 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -1417,6 +1417,34 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsPointCrs( const
return QgsCoordinateReferenceSystem();
}

QgsGeometry QgsProcessingParameters::parameterAsGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
return QgsGeometry();

return parameterAsGeometry( definition, parameters.value( definition->name() ), context );
}

QgsGeometry QgsProcessingParameters::parameterAsGeometry( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
if ( !definition )
return QgsGeometry();

QVariant val = value;
if ( val.canConvert< QgsGeometry >() )
{
return val.value<QgsGeometry>();
}

QString valueAsString = parameterAsString( definition, value, context );
if ( !valueAsString.isEmpty() )
{
return QgsGeometry::fromWkt( valueAsString );
}

return QgsGeometry();
}

QString QgsProcessingParameters::parameterAsFile( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
if ( !definition )
Expand Down Expand Up @@ -2002,6 +2030,8 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromScriptCo
return QgsProcessingParameterExtent::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "point" ) )
return QgsProcessingParameterPoint::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "geometry" ) )
return QgsProcessingParameterGeometry::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "file" ) )
return QgsProcessingParameterFile::fromScriptCode( name, description, isOptional, definition, QgsProcessingParameterFile::File );
else if ( type == QStringLiteral( "folder" ) )
Expand Down Expand Up @@ -2770,6 +2800,78 @@ QgsProcessingParameterPoint *QgsProcessingParameterPoint::fromScriptCode( const
return new QgsProcessingParameterPoint( name, description, definition, isOptional );
}

QgsProcessingParameterGeometry::QgsProcessingParameterGeometry( const QString &name, const QString &description,
const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{

}

QgsProcessingParameterDefinition *QgsProcessingParameterGeometry::clone() const
{
return new QgsProcessingParameterGeometry( *this );
}

bool QgsProcessingParameterGeometry::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;

if ( input.canConvert<QgsProperty>() )
{
return true;
}

if ( input.canConvert< QgsGeometry >() )
{
return true;
}

if ( input.type() == QVariant::String )
{
if ( input.toString().isEmpty() )
return mFlags & FlagOptional;
}

QgsGeometry g = QgsGeometry::fromWkt( input.toString() );
if ( ! g.isNull() )
{
return true;
}
else
{
QgsMessageLog::logMessage( QObject::tr( "Error creating geometry: \"%1\"" ).arg( g.lastError() ), QObject::tr( "Processing" ) );
return false;
}

}

QString QgsProcessingParameterGeometry::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< QgsGeometry >() )
{
const QgsGeometry g = value.value<QgsGeometry>();
if ( !g.isNull() )
{
const QString wkt = g.asWkt();
return QStringLiteral( "QgsGeometry.fromWkt('%1')" ).arg( wkt );
}
}

return QgsProcessingParameterDefinition::valueAsPythonString( value, context );
}

QgsProcessingParameterGeometry *QgsProcessingParameterGeometry::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
return new QgsProcessingParameterGeometry( name, description, definition, isOptional );
}

QgsProcessingParameterFile::QgsProcessingParameterFile( const QString &name, const QString &description, Behavior behavior, const QString &extension, const QVariant &defaultValue, bool optional, const QString &fileFilter )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mBehavior( behavior )
Expand Down
47 changes: 47 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -342,6 +342,8 @@ class CORE_EXPORT QgsProcessingParameterDefinition
sipType = sipType_QgsProcessingParameterExtent;
else if ( sipCpp->type() == QgsProcessingParameterPoint::typeName() )
sipType = sipType_QgsProcessingParameterPoint;
else if ( sipCpp->type() == QgsProcessingParameterGeometry::typeName() )
sipType = sipType_QgsProcessingParameterGeometry;
else if ( sipCpp->type() == QgsProcessingParameterFile::typeName() )
sipType = sipType_QgsProcessingParameterFile;
else if ( sipCpp->type() == QgsProcessingParameterMatrix::typeName() )
Expand Down Expand Up @@ -1247,6 +1249,20 @@ class CORE_EXPORT QgsProcessingParameters
*/
static QgsCoordinateReferenceSystem parameterAsPointCrs( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context );

/**
* Evaluates the parameter with matching \a definition to a geometry.
*
* \since QGIS 3.16
*/
static QgsGeometry parameterAsGeometry( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context );

/**
* Evaluates the parameter with matching \a definition and \a value to a geometry.
*
* \since QGIS 3.16
*/
static QgsGeometry parameterAsGeometry( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context );

/**
* Evaluates the parameter with matching \a definition to a file/folder name.
*/
Expand Down Expand Up @@ -1568,6 +1584,37 @@ class CORE_EXPORT QgsProcessingParameterPoint : public QgsProcessingParameterDef

};

/**
* \class QgsProcessingParameterGeometry
* \ingroup core
* A geometry parameter for processing algorithms.
* \since QGIS 3.16
*/
class CORE_EXPORT QgsProcessingParameterGeometry : public QgsProcessingParameterDefinition
{
public:

/**
* Constructor for QgsProcessingParameterGeometry.
*/
QgsProcessingParameterGeometry( 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( "geometry" ); }
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 QgsProcessingParameterGeometry *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;

};

/**
* \class QgsProcessingParameterFile
* \ingroup core
Expand Down
52 changes: 52 additions & 0 deletions src/core/processing/qgsprocessingparametertypeimpl.h
Expand Up @@ -518,6 +518,58 @@ class CORE_EXPORT QgsProcessingParameterTypePoint : public QgsProcessingParamete
}
};

/**
* A geometry parameter for processing algorithms.
*
* \ingroup core
* \note No Python bindings available. Get your copy from QgsApplication.processingRegistry().parameterType('geometry')
* \since QGIS 3.16
*/
class CORE_EXPORT QgsProcessingParameterTypeGeometry : public QgsProcessingParameterType
{
QgsProcessingParameterDefinition *create( const QString &name ) const override SIP_FACTORY
{
return new QgsProcessingParameterGeometry( name );
}

QString description() const override
{
return QCoreApplication::translate( "Processing", "A geometry parameter." );
}

QString name() const override
{
return QCoreApplication::translate( "Processing", "Geometry" );
}

QString id() const override
{
return QStringLiteral( "geometry" );
}

QString pythonImportString() const override
{
return QStringLiteral( "from qgis.core import QgsProcessingParameterGeometry" );
}

QString className() const override
{
return QStringLiteral( "QgsProcessingParameterGeometry" );
}

QStringList acceptedPythonTypes() const override
{
return QStringList() << QObject::tr( "str: as Well-Known Text string (WKT)" )
<< QStringLiteral( "QgsGeometry" )
<< QStringLiteral( "QgsProperty" );
}

QStringList acceptedStringValues() const override
{
return QStringList() << QObject::tr( "Well-Known Text string (WKT)" );
}
};

/**
* An enum based parameter for processing algorithms, allowing for selection from predefined values.
*
Expand Down
1 change: 1 addition & 0 deletions src/core/processing/qgsprocessingregistry.cpp
Expand Up @@ -35,6 +35,7 @@ QgsProcessingRegistry::QgsProcessingRegistry( QObject *parent SIP_TRANSFERTHIS )
addParameterType( new QgsProcessingParameterTypeCrs() );
addParameterType( new QgsProcessingParameterTypeRange() );
addParameterType( new QgsProcessingParameterTypePoint() );
addParameterType( new QgsProcessingParameterTypeGeometry() );
addParameterType( new QgsProcessingParameterTypeEnum() );
addParameterType( new QgsProcessingParameterTypeExtent() );
addParameterType( new QgsProcessingParameterTypeMatrix() );
Expand Down

0 comments on commit 4eb931e

Please sign in to comment.