Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] Also accept QgsProcessingOutputLayerDefinition for
layer input values

Since these may result from the output of an earlier child algorithm running
in a processing model.

Fixes #19372
  • Loading branch information
nyalldawson committed Jul 12, 2018
1 parent 61cc8b5 commit 41825ca
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/core/processing/models/qgsprocessingmodelalgorithm.cpp
Expand Up @@ -580,6 +580,11 @@ QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingMode
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( value );
value = fromVar.source;
}
else if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
value = fromVar.sink;
}
if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( value ) ) )
{
featureSource = layer;
Expand Down
5 changes: 5 additions & 0 deletions src/core/processing/qgsprocessingalgorithm.cpp
Expand Up @@ -687,6 +687,11 @@ QString QgsProcessingAlgorithm::invalidSourceError( const QVariantMap &parameter
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
var = fromVar.source;
}
else if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
Expand Down
55 changes: 55 additions & 0 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -321,6 +321,12 @@ QString QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( const Qgs
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>() )
{
Expand Down Expand Up @@ -513,6 +519,12 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsP
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 )
{
Expand Down Expand Up @@ -589,6 +601,12 @@ QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingPara
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 )
{
Expand Down Expand Up @@ -696,6 +714,12 @@ QgsGeometry QgsProcessingParameters::parameterAsExtentGeometry( const QgsProcess
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 )
{
Expand Down Expand Up @@ -794,6 +818,12 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( cons
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 )
{
Expand Down Expand Up @@ -822,6 +852,12 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( cons
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 )
{
Expand Down Expand Up @@ -1451,6 +1487,10 @@ bool QgsProcessingParameterCrs::checkValueIsAcceptable( const QVariant &input, Q
{
return true;
}
else if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
{
return true;
}

if ( input.canConvert<QgsProperty>() )
{
Expand Down Expand Up @@ -1567,6 +1607,15 @@ bool QgsProcessingParameterExtent::checkValueIsAcceptable( const QVariant &input
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;
Expand Down Expand Up @@ -3097,6 +3146,12 @@ bool QgsProcessingParameterFeatureSource::checkValueIsAcceptable( const QVariant
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>() )
{
Expand Down
6 changes: 6 additions & 0 deletions src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -239,6 +239,12 @@ QgsProcessingFeatureSource *QgsProcessingUtils::variantToSource( const QVariant
selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
val = fromVar.source;
}
else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
{
// input is a QgsProcessingOutputLayerDefinition (e.g. an output from earlier in a model) - get extra properties from it
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
val = fromVar.sink;
}

if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) ) )
{
Expand Down
39 changes: 37 additions & 2 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -2111,6 +2111,7 @@ void TestQgsProcessing::parameterCrs()
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( r1->id() ) ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( QVariant::fromValue( r1 ) ) ) ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingOutputLayerDefinition( r1->id() ) ) );

// using map layer
QVariantMap params;
Expand Down Expand Up @@ -2149,6 +2150,8 @@ void TestQgsProcessing::parameterCrs()
QCOMPARE( QgsProcessingParameters::parameterAsCrs( def.get(), params, context ).authid(), QString( "EPSG:3111" ) );
params.insert( "non_optional", QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( QVariant::fromValue( v1 ) ) ) );
QCOMPARE( QgsProcessingParameters::parameterAsCrs( def.get(), params, context ).authid(), QString( "EPSG:3111" ) );
params.insert( "non_optional", QgsProcessingOutputLayerDefinition( v1->id() ) );
QCOMPARE( QgsProcessingParameters::parameterAsCrs( def.get(), params, context ).authid(), QString( "EPSG:3111" ) );

QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) );
QCOMPARE( def->valueAsPythonString( "EPSG:12003", context ), QStringLiteral( "'EPSG:12003'" ) );
Expand Down Expand Up @@ -2362,6 +2365,9 @@ void TestQgsProcessing::parameterExtent()
QVERIFY( !def->checkValueIsAcceptable( "1,2,3", &context ) );
QVERIFY( !def->checkValueIsAcceptable( "1,2,3,a", &context ) );

QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( r1->id() ) ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingOutputLayerDefinition( r1->id() ) ) );

// using map layer
QVariantMap params;
params.insert( "non_optional", r1->id() );
Expand Down Expand Up @@ -2428,6 +2434,22 @@ void TestQgsProcessing::parameterExtent()
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );

// using output layer definition, e.g. from a previous model child algorithm
params.insert( "non_optional", QgsProcessingOutputLayerDefinition( r1->id() ) );
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:4326" ) );
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:4326" ) );
QGSCOMPARENEAR( ext.xMinimum(), 1535375, 100 );
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 100 );
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );
gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:4326" ) );
QCOMPARE( gExt.constGet()->vertexCount(), 5 );
ext = gExt.boundingBox();
QGSCOMPARENEAR( ext.xMinimum(), 1535375, 100 );
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 100 );
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );

// string representing a non-project layer source
params.insert( "non_optional", raster2 );
QVERIFY( def->checkValueIsAcceptable( raster2 ) );
Expand Down Expand Up @@ -4454,7 +4476,8 @@ void TestQgsProcessing::parameterFeatureSource()
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: my prop layer not found" ) );
params.insert( QStringLiteral( "INPUT" ), QVariant::fromValue( v1 ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: invalid value" ) );

params.insert( QStringLiteral( "INPUT" ), QgsProcessingOutputLayerDefinition( QStringLiteral( "my prop layer" ) ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: my prop layer not found" ) );
}

void TestQgsProcessing::parameterFeatureSink()
Expand Down Expand Up @@ -5156,14 +5179,21 @@ void TestQgsProcessing::processingFeatureSource()
QVERIFY( source->getFeatures().nextFeature( f2 ) );
QCOMPARE( f2.geometry(), f.geometry() );


// next using property based definition
params.insert( QStringLiteral( "layer" ), QgsProcessingFeatureSourceDefinition( QgsProperty::fromExpression( QStringLiteral( "trim('%1' + ' ')" ).arg( layer->id() ) ), false ) );
source.reset( QgsProcessingParameters::parameterAsSource( def.get(), params, context ) );
// can't directly match it to layer, so instead just get the feature and test that it matches what we expect
QVERIFY( source.get() );
QVERIFY( source->getFeatures().nextFeature( f2 ) );
QCOMPARE( f2.geometry(), f.geometry() );

// we also must accept QgsProcessingOutputLayerDefinition - e.g. to allow outputs from earlier child algorithms in models
params.insert( QStringLiteral( "layer" ), QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( layer->id() ) ) );
source.reset( QgsProcessingParameters::parameterAsSource( def.get(), params, context ) );
// can't directly match it to layer, so instead just get the feature and test that it matches what we expect
QVERIFY( source.get() );
QVERIFY( source->getFeatures().nextFeature( f2 ) );
QCOMPARE( f2.geometry(), f.geometry() );
}

void TestQgsProcessing::processingFeatureSink()
Expand Down Expand Up @@ -6584,6 +6614,11 @@ void TestQgsProcessing::convertCompatible()
params.remove( QStringLiteral( "source" ) );
out = QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( def.get(), params, context, QStringList() << "shp", QString( "shp" ), &feedback );
QCOMPARE( out, layer->source() );

// output layer as input - e.g. from a previous model child
params.insert( QStringLiteral( "source" ), QgsProcessingOutputLayerDefinition( layer->id() ) );
out = QgsProcessingParameters::parameterAsCompatibleSourceLayerPath( def.get(), params, context, QStringList() << "shp", QString( "shp" ), &feedback );
QCOMPARE( out, layer->source() );
}

void TestQgsProcessing::create()
Expand Down

0 comments on commit 41825ca

Please sign in to comment.