Skip to content

Commit

Permalink
Move variant to CRS resolution out to QgsProcessingUtils for wider
Browse files Browse the repository at this point in the history
usability
  • Loading branch information
nyalldawson committed Dec 20, 2019
1 parent fe622dd commit 3e9aaaa
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 57 deletions.
10 changes: 10 additions & 0 deletions python/core/auto_generated/processing/qgsprocessingutils.sip.in
Expand Up @@ -125,6 +125,16 @@ The optional ``fallbackValue`` can be used to specify a "default" value which is
if ``value`` cannot be successfully converted to a source.

This function creates a new object and the caller takes responsibility for deleting the returned object.
%End

static QgsCoordinateReferenceSystem variantToCrs( const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue = QVariant() );
%Docstring
Converts a variant ``value`` to a coordinate reference system.

The optional ``fallbackValue`` can be used to specify a "default" value which is used
if ``value`` cannot be successfully converted to a CRS.

.. versionadded:: 3.12
%End

static QString normalizeLayerSource( const QString &source );
Expand Down
58 changes: 1 addition & 57 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -782,63 +782,7 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsP
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;
return QgsProcessingUtils::variantToCrs( value, context, definition->defaultValue() );
}

QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context,
Expand Down
61 changes: 61 additions & 0 deletions src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -338,6 +338,67 @@ QgsProcessingFeatureSource *QgsProcessingUtils::variantToSource( const QVariant
}
}

QgsCoordinateReferenceSystem QgsProcessingUtils::variantToCrs( const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue )
{
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(), fallbackValue.toString() );

if ( !val.isValid() )
{
// fall back to default
val = fallbackValue;
}

QString crsText = val.toString();
if ( crsText.isEmpty() )
crsText = fallbackValue.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;
}

bool QgsProcessingUtils::canUseLayer( const QgsMeshLayer *layer )
{
return layer && layer->dataProvider();
Expand Down
10 changes: 10 additions & 0 deletions src/core/processing/qgsprocessingutils.h
Expand Up @@ -144,6 +144,16 @@ class CORE_EXPORT QgsProcessingUtils
*/
static QgsProcessingFeatureSource *variantToSource( const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue = QVariant() ) SIP_FACTORY;

/**
* Converts a variant \a value to a coordinate reference system.
*
* The optional \a fallbackValue can be used to specify a "default" value which is used
* if \a value cannot be successfully converted to a CRS.
*
* \since QGIS 3.12
*/
static QgsCoordinateReferenceSystem variantToCrs( const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue = QVariant() );

/**
* Normalizes a layer \a source string for safe comparison across different
* operating system environments.
Expand Down

0 comments on commit 3e9aaaa

Please sign in to comment.