Skip to content

Commit

Permalink
[processing] Also accept QgsProcessingOutputLayerDefinition for
Browse files Browse the repository at this point in the history
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.