Skip to content

Commit 84806b9

Browse files
committed
[processing] Fix cannot use feature source as input for model crs or extent parameters
1 parent 3b2f690 commit 84806b9

3 files changed

Lines changed: 126 additions & 5 deletions

File tree

src/core/processing/qgsprocessingparameters.cpp

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,32 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsP
506506

507507
QVariant val = parameters.value( definition->name() );
508508

509-
QString crsText = parameterAsString( definition, parameters, context );
509+
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
510+
{
511+
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
512+
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
513+
val = fromVar.source;
514+
}
515+
516+
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
517+
{
518+
val = val.value< QgsProperty >().staticValue();
519+
}
520+
521+
// maybe a map layer
522+
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
523+
return layer->crs();
524+
525+
if ( val.canConvert<QgsProperty>() )
526+
val = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
527+
528+
if ( !val.isValid() )
529+
{
530+
// fall back to default
531+
val = definition->defaultValue();
532+
}
533+
534+
QString crsText = val.toString();
510535
if ( crsText.isEmpty() )
511536
crsText = definition->defaultValue().toString();
512537

@@ -518,9 +543,7 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsCrs( const QgsP
518543
return context.project()->crs();
519544

520545
// maybe a map layer reference
521-
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
522-
return layer->crs();
523-
else if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( crsText, context ) )
546+
if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( crsText, context ) )
524547
return layer->crs();
525548

526549
// else CRS from string
@@ -559,6 +582,18 @@ QgsRectangle QgsProcessingParameters::parameterAsExtent( const QgsProcessingPara
559582
return rr;
560583
}
561584

585+
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
586+
{
587+
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
588+
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
589+
val = fromVar.source;
590+
}
591+
592+
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
593+
{
594+
val = val.value< QgsProperty >().staticValue();
595+
}
596+
562597
// maybe parameter is a direct layer value?
563598
QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) );
564599

@@ -654,6 +689,18 @@ QgsGeometry QgsProcessingParameters::parameterAsExtentGeometry( const QgsProcess
654689
}
655690
}
656691

692+
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
693+
{
694+
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
695+
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
696+
val = fromVar.source;
697+
}
698+
699+
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
700+
{
701+
val = val.value< QgsProperty >().staticValue();
702+
}
703+
657704
QString rectText;
658705
if ( val.canConvert<QgsProperty>() )
659706
rectText = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
@@ -740,9 +787,26 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( cons
740787
}
741788
}
742789

790+
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
791+
{
792+
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
793+
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
794+
val = fromVar.source;
795+
}
796+
797+
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
798+
{
799+
val = val.value< QgsProperty >().staticValue();
800+
}
801+
802+
QString valueAsString;
803+
if ( val.canConvert<QgsProperty>() )
804+
valueAsString = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
805+
else
806+
valueAsString = val.toString();
807+
743808
QRegularExpression rx( QStringLiteral( "^(.*?)\\s*,\\s*(.*?),\\s*(.*?),\\s*(.*?)\\s*(?:\\[(.*)\\])?\\s*$" ) );
744809

745-
QString valueAsString = parameterAsString( definition, parameters, context );
746810
QRegularExpressionMatch match = rx.match( valueAsString );
747811
if ( match.hasMatch() )
748812
{
@@ -751,6 +815,18 @@ QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( cons
751815
return crs;
752816
}
753817

818+
if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
819+
{
820+
// input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
821+
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
822+
val = fromVar.source;
823+
}
824+
825+
if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
826+
{
827+
val = val.value< QgsProperty >().staticValue();
828+
}
829+
754830
// try as layer crs
755831
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
756832
return layer->crs();
@@ -1370,6 +1446,11 @@ bool QgsProcessingParameterCrs::checkValueIsAcceptable( const QVariant &input, Q
13701446
if ( !input.isValid() )
13711447
return mFlags & FlagOptional;
13721448

1449+
if ( input.canConvert<QgsProcessingFeatureSourceDefinition>() )
1450+
{
1451+
return true;
1452+
}
1453+
13731454
if ( input.canConvert<QgsProperty>() )
13741455
{
13751456
return true;

src/core/processing/qgsprocessingparametertypeimpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ class CORE_EXPORT QgsProcessingParameterTypeCrs : public QgsProcessingParameterT
258258
<< QObject::tr( "str: layer name. CRS of layer is used." )
259259
<< QObject::tr( "str: layer source. CRS of layer is used." )
260260
<< QObject::tr( "QgsMapLayer: CRS of layer is used" )
261+
<< QObject::tr( "QgsProcessingFeatureSourceDefinition: CRS of source is used" )
261262
<< QStringLiteral( "QgsProperty" );
262263
}
263264
};
@@ -411,6 +412,7 @@ class CORE_EXPORT QgsProcessingParameterTypeExtent : public QgsProcessingParamet
411412
<< QObject::tr( "str: layer name. Extent of layer is used." )
412413
<< QObject::tr( "str: layer source. Extent of layer is used." )
413414
<< QObject::tr( "QgsMapLayer: Extent of layer is used" )
415+
<< QObject::tr( "QgsProcessingFeatureSourceDefinition: Extent of source is used" )
414416
<< QStringLiteral( "QgsProperty" )
415417
<< QStringLiteral( "QgsRectangle" )
416418
<< QStringLiteral( "QgsReferencedRectangle" );

tests/src/analysis/testqgsprocessing.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,8 @@ void TestQgsProcessing::parameterCrs()
20522052
QVERIFY( def->checkValueIsAcceptable( QVariant::fromValue( r1 ) ) );
20532053
QVERIFY( !def->checkValueIsAcceptable( "" ) );
20542054
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
2055+
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( r1->id() ) ) );
2056+
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( QVariant::fromValue( r1 ) ) ) ) );
20552057

20562058
// using map layer
20572059
QVariantMap params;
@@ -2085,6 +2087,12 @@ void TestQgsProcessing::parameterCrs()
20852087
params.insert( "non_optional", QString( "i'm not a crs, and nothing you can do will make me one" ) );
20862088
QVERIFY( !QgsProcessingParameters::parameterAsCrs( def.get(), params, context ).isValid() );
20872089

2090+
// using feature source definition
2091+
params.insert( "non_optional", QgsProcessingFeatureSourceDefinition( v1->id() ) );
2092+
QCOMPARE( QgsProcessingParameters::parameterAsCrs( def.get(), params, context ).authid(), QString( "EPSG:3111" ) );
2093+
params.insert( "non_optional", QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( QVariant::fromValue( v1 ) ) ) );
2094+
QCOMPARE( QgsProcessingParameters::parameterAsCrs( def.get(), params, context ).authid(), QString( "EPSG:3111" ) );
2095+
20882096
QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) );
20892097
QCOMPARE( def->valueAsPythonString( "EPSG:12003", context ), QStringLiteral( "'EPSG:12003'" ) );
20902098
QCOMPARE( def->valueAsPythonString( "ProjectCrs", context ), QStringLiteral( "'ProjectCrs'" ) );
@@ -2331,6 +2339,36 @@ void TestQgsProcessing::parameterExtent()
23312339
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
23322340
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );
23332341

2342+
// using feature source definition
2343+
params.insert( "non_optional", QgsProcessingFeatureSourceDefinition( r1->id() ) );
2344+
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:4326" ) );
2345+
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:4326" ) );
2346+
QGSCOMPARENEAR( ext.xMinimum(), 1535375, 100 );
2347+
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 100 );
2348+
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
2349+
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );
2350+
gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:4326" ) );
2351+
QCOMPARE( gExt.constGet()->vertexCount(), 5 );
2352+
ext = gExt.boundingBox();
2353+
QGSCOMPARENEAR( ext.xMinimum(), 1535375, 100 );
2354+
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 100 );
2355+
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
2356+
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );
2357+
params.insert( "non_optional", QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( QVariant::fromValue( r1 ) ) ) );
2358+
QCOMPARE( QgsProcessingParameters::parameterAsExtentCrs( def.get(), params, context ).authid(), QStringLiteral( "EPSG:4326" ) );
2359+
ext = QgsProcessingParameters::parameterAsExtent( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:4326" ) );
2360+
QGSCOMPARENEAR( ext.xMinimum(), 1535375, 100 );
2361+
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 100 );
2362+
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
2363+
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );
2364+
gExt = QgsProcessingParameters::parameterAsExtentGeometry( def.get(), params, context, QgsCoordinateReferenceSystem( "EPSG:4326" ) );
2365+
QCOMPARE( gExt.constGet()->vertexCount(), 5 );
2366+
ext = gExt.boundingBox();
2367+
QGSCOMPARENEAR( ext.xMinimum(), 1535375, 100 );
2368+
QGSCOMPARENEAR( ext.xMaximum(), 1535475, 100 );
2369+
QGSCOMPARENEAR( ext.yMinimum(), 5083255, 100 );
2370+
QGSCOMPARENEAR( ext.yMaximum(), 5083355, 100 );
2371+
23342372
// string representing a non-project layer source
23352373
params.insert( "non_optional", raster2 );
23362374
QVERIFY( def->checkValueIsAcceptable( raster2 ) );

0 commit comments

Comments
 (0)