Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[API][processing] New parameter type for coordinate operations
Allows selection of the proj coordinate operation to use when
reprojecting between two CRSes
  • Loading branch information
nyalldawson committed Dec 20, 2019
1 parent c04d4fa commit fe622dd
Show file tree
Hide file tree
Showing 6 changed files with 535 additions and 0 deletions.
124 changes: 124 additions & 0 deletions python/core/auto_generated/processing/qgsprocessingparameters.sip.in
Expand Up @@ -191,6 +191,8 @@ their acceptable ranges, defaults, etc.
sipType = sipType_QgsProcessingParameterLayoutItem;
else if ( sipCpp->type() == QgsProcessingParameterColor::typeName() )
sipType = sipType_QgsProcessingParameterColor;
else if ( sipCpp->type() == QgsProcessingParameterCoordinateOperation::typeName() )
sipType = sipType_QgsProcessingParameterCoordinateOperation;
else
sipType = nullptr;
%End
Expand Down Expand Up @@ -3210,6 +3212,128 @@ Creates a new parameter using the definition from a script code.
};


class QgsProcessingParameterCoordinateOperation : QgsProcessingParameterDefinition
{
%Docstring
A coordinate operation parameter for processing algorithms, for selection between available
coordinate operations to use when projecting between a source and destination coordinate reference system.

.. versionadded:: 3.12
%End

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

QgsProcessingParameterCoordinateOperation( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
const QString &sourceCrsParameterName = QString(), const QString &destinationCrsParameterName = QString(),
const QVariant &staticSourceCrs = QVariant(), const QVariant &staticDestinationCrs = QVariant(),
bool optional = false );
%Docstring
Constructor for QgsProcessingParameterCoordinateOperation.
%End

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

virtual QString type() 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 QgsProcessingParameterCoordinateOperation *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

QString sourceCrsParameterName() const;
%Docstring
Returns the name of the source CRS parameter, or an empty string if this is not set.

.. seealso:: :py:func:`setSourceCrsParameterName`

.. seealso:: :py:func:`destinationCrsParameterName`
%End

void setSourceCrsParameterName( const QString &name );
%Docstring
Sets the ``name`` of the source CRS parameter. Use an empty string if this is not required.

.. seealso:: :py:func:`sourceCrsParameterName`

.. seealso:: :py:func:`setDestinationCrsParameterName`
%End

QString destinationCrsParameterName() const;
%Docstring
Returns the name of the destination CRS parameter, or an empty string if this is not set.

.. seealso:: :py:func:`setDestinationCrsParameterName`

.. seealso:: :py:func:`sourceCrsParameterName`
%End

void setDestinationCrsParameterName( const QString &name );
%Docstring
Sets the ``name`` of the destination CRS parameter. Use an empty string if this is not required.

.. seealso:: :py:func:`destinationCrsParameterName`

.. seealso:: :py:func:`setSourceCrsParameterName`
%End

QVariant sourceCrs() const;
%Docstring
Returns the static source CRS, or an invalid value if this is not set.

.. seealso:: :py:func:`setSourceCrs`

.. seealso:: :py:func:`destinationCrs`
%End

void setSourceCrs( const QVariant &crs );
%Docstring
Sets the static source ``crs``.

.. seealso:: :py:func:`sourceCrs`

.. seealso:: :py:func:`setDestinationCrs`
%End

QVariant destinationCrs() const;
%Docstring
Returns the static destination CRS, or an invalid value if this is not set.

.. seealso:: :py:func:`setDestinationCrs`

.. seealso:: :py:func:`sourceCrs`
%End

void setDestinationCrs( const QVariant &crs );
%Docstring
Sets the static destination ``crs``.

.. seealso:: :py:func:`destinationCrs`

.. seealso:: :py:func:`setSourceCrs`
%End

};





/************************************************************************
Expand Down
122 changes: 122 additions & 0 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -1747,6 +1747,8 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromVariantM
def.reset( new QgsProcessingParameterLayoutItem( name ) );
else if ( type == QgsProcessingParameterColor::typeName() )
def.reset( new QgsProcessingParameterColor( name ) );
else if ( type == QgsProcessingParameterCoordinateOperation::typeName() )
def.reset( new QgsProcessingParameterCoordinateOperation( name ) );
else
{
QgsProcessingParameterType *paramType = QgsApplication::instance()->processingRegistry()->parameterType( type );
Expand Down Expand Up @@ -1841,6 +1843,8 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromScriptCo
return QgsProcessingParameterLayoutItem::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "color" ) )
return QgsProcessingParameterColor::fromScriptCode( name, description, isOptional, definition );
else if ( type == QStringLiteral( "coordinateoperation" ) )
return QgsProcessingParameterCoordinateOperation::fromScriptCode( name, description, isOptional, definition );

return nullptr;
}
Expand Down Expand Up @@ -5923,3 +5927,121 @@ QgsProcessingParameterColor *QgsProcessingParameterColor::fromScriptCode( const

return new QgsProcessingParameterColor( name, description, defaultValue, allowOpacity, isOptional );
}

//
// QgsProcessingParameterCoordinateOperation
//
QgsProcessingParameterCoordinateOperation::QgsProcessingParameterCoordinateOperation( const QString &name, const QString &description, const QVariant &defaultValue, const QString &sourceCrsParameterName, const QString &destinationCrsParameterName, const QVariant &staticSourceCrs, const QVariant &staticDestinationCrs, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mSourceParameterName( sourceCrsParameterName )
, mDestParameterName( destinationCrsParameterName )
, mSourceCrs( staticSourceCrs )
, mDestCrs( staticDestinationCrs )
{

}

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

QString QgsProcessingParameterCoordinateOperation::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
{
if ( !value.isValid() || value.isNull() )
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() ) );

QString s = value.toString();
return QgsProcessingUtils::stringToPythonLiteral( s );
}

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

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

QString QgsProcessingParameterCoordinateOperation::asPythonString( QgsProcessing::PythonOutputType outputType ) const
{
switch ( outputType )
{
case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
{
QgsProcessingContext c;
QString code = QStringLiteral( "QgsProcessingParameterCoordinateOperation('%1', '%2'" ).arg( name(), description() );
if ( mFlags & FlagOptional )
code += QStringLiteral( ", optional=True" );
if ( !mSourceParameterName.isEmpty() )
code += QStringLiteral( ", sourceCrsParameterName=%1" ).arg( valueAsPythonString( mSourceParameterName, c ) );
if ( !mDestParameterName.isEmpty() )
code += QStringLiteral( ", destinationCrsParameterName=%1" ).arg( valueAsPythonString( mDestParameterName, c ) );

if ( mSourceCrs.isValid() )
code += QStringLiteral( ", staticSourceCrs=%1" ).arg( valueAsPythonString( mSourceCrs, c ) );
if ( mDestCrs.isValid() )
code += QStringLiteral( ", staticDestinationCrs=%1" ).arg( valueAsPythonString( mDestCrs, c ) );

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

QVariantMap QgsProcessingParameterCoordinateOperation::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "source_crs_parameter_name" ), mSourceParameterName );
map.insert( QStringLiteral( "dest_crs_parameter_name" ), mDestParameterName );
map.insert( QStringLiteral( "static_source_crs" ), mSourceCrs );
map.insert( QStringLiteral( "static_dest_crs" ), mDestCrs );
return map;
}

bool QgsProcessingParameterCoordinateOperation::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mSourceParameterName = map.value( QStringLiteral( "source_crs_parameter_name" ) ).toString();
mDestParameterName = map.value( QStringLiteral( "dest_crs_parameter_name" ) ).toString();
mSourceCrs = map.value( QStringLiteral( "static_source_crs" ) );
mDestCrs = map.value( QStringLiteral( "static_dest_crs" ) );
return true;
}

QgsProcessingParameterCoordinateOperation *QgsProcessingParameterCoordinateOperation::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
QString def = definition;

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 QgsProcessingParameterCoordinateOperation( name, description, defaultValue, QString(), QString(), QVariant(), QVariant(), isOptional );
}
106 changes: 106 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -268,6 +268,8 @@ class CORE_EXPORT QgsProcessingParameterDefinition
sipType = sipType_QgsProcessingParameterLayoutItem;
else if ( sipCpp->type() == QgsProcessingParameterColor::typeName() )
sipType = sipType_QgsProcessingParameterColor;
else if ( sipCpp->type() == QgsProcessingParameterCoordinateOperation::typeName() )
sipType = sipType_QgsProcessingParameterCoordinateOperation;
else
sipType = nullptr;
SIP_END
Expand Down Expand Up @@ -3001,6 +3003,110 @@ class CORE_EXPORT QgsProcessingParameterColor : public QgsProcessingParameterDef

};


/**
* \class QgsProcessingParameterCoordinateOperation
* \ingroup core
* A coordinate operation parameter for processing algorithms, for selection between available
* coordinate operations to use when projecting between a source and destination coordinate reference system.
* \since QGIS 3.12
*/
class CORE_EXPORT QgsProcessingParameterCoordinateOperation : public QgsProcessingParameterDefinition
{
public:

/**
* Constructor for QgsProcessingParameterCoordinateOperation.
*/
QgsProcessingParameterCoordinateOperation( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
const QString &sourceCrsParameterName = QString(), const QString &destinationCrsParameterName = QString(),
const QVariant &staticSourceCrs = QVariant(), const QVariant &staticDestinationCrs = QVariant(),
bool optional = false );

/**
* Returns the type name for the parameter class.
*/
static QString typeName() { return QStringLiteral( "coordinateoperation" ); }
QgsProcessingParameterDefinition *clone() const override SIP_FACTORY;
QString type() const override { return typeName(); }
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 QgsProcessingParameterCoordinateOperation *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;

/**
* Returns the name of the source CRS parameter, or an empty string if this is not set.
* \see setSourceCrsParameterName()
* \see destinationCrsParameterName()
*/
QString sourceCrsParameterName() const { return mSourceParameterName; }

/**
* Sets the \a name of the source CRS parameter. Use an empty string if this is not required.
* \see sourceCrsParameterName()
* \see setDestinationCrsParameterName()
*/
void setSourceCrsParameterName( const QString &name ) { mSourceParameterName = name; }

/**
* Returns the name of the destination CRS parameter, or an empty string if this is not set.
* \see setDestinationCrsParameterName()
* \see sourceCrsParameterName()
*/
QString destinationCrsParameterName() const { return mDestParameterName; }

/**
* Sets the \a name of the destination CRS parameter. Use an empty string if this is not required.
* \see destinationCrsParameterName()
* \see setSourceCrsParameterName()
*/
void setDestinationCrsParameterName( const QString &name ) { mDestParameterName = name; }

/**
* Returns the static source CRS, or an invalid value if this is not set.
* \see setSourceCrs()
* \see destinationCrs()
*/
QVariant sourceCrs() const { return mSourceCrs; }

/**
* Sets the static source \a crs.
* \see sourceCrs()
* \see setDestinationCrs()
*/
void setSourceCrs( const QVariant &crs ) { mSourceCrs = crs; }

/**
* Returns the static destination CRS, or an invalid value if this is not set.
* \see setDestinationCrs()
* \see sourceCrs()
*/
QVariant destinationCrs() const { return mDestCrs; }

/**
* Sets the static destination \a crs.
* \see destinationCrs()
* \see setSourceCrs()
*/
void setDestinationCrs( const QVariant &crs ) { mDestCrs = crs; }

private:

QString mSourceParameterName;
QString mDestParameterName;
QVariant mSourceCrs;
QVariant mDestCrs;

};


// clazy:excludeall=qstring-allocations

#endif // QGSPROCESSINGPARAMETERS_H
Expand Down

0 comments on commit fe622dd

Please sign in to comment.