Skip to content

Commit

Permalink
Only accept QgsPropertys in QgsProcessingFeatureSourceDefinition/
Browse files Browse the repository at this point in the history
QgsProcessingFeatureSink, not all QVariant types

Only strings/QgsPropertys are valid anyway, so instead of strings
use static properties. This makes it clearer what possible
values are permitted for the underlying source/sink definition.
  • Loading branch information
nyalldawson committed Jun 5, 2017
1 parent d7aa3f5 commit 72be86d
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 24 deletions.
26 changes: 18 additions & 8 deletions python/core/processing/qgsprocessingparameters.sip
Expand Up @@ -26,14 +26,19 @@ class QgsProcessingFeatureSourceDefinition
%End
public:

QgsProcessingFeatureSourceDefinition( const QVariant &source = QVariant(), bool selectedFeaturesOnly = false );
QgsProcessingFeatureSourceDefinition( const QString &source = QString(), bool selectedFeaturesOnly = false );
%Docstring
Constructor for QgsProcessingFeatureSourceDefinition.
Constructor for QgsProcessingFeatureSourceDefinition, accepting a static string source.
%End

QVariant source;
QgsProcessingFeatureSourceDefinition( const QgsProperty &source, bool selectedFeaturesOnly = false );
%Docstring
Source definition. Usually set to a source layer's ID or file name.
Constructor for QgsProcessingFeatureSourceDefinition, accepting a QgsProperty source.
%End

QgsProperty source;
%Docstring
Source definition. Usually a static property set to a source layer's ID or file name.
%End

bool selectedFeaturesOnly;
Expand Down Expand Up @@ -65,14 +70,19 @@ class QgsProcessingFeatureSink
%End
public:

QgsProcessingFeatureSink( const QVariant &sink = QVariant(), bool loadIntoProject = false );
QgsProcessingFeatureSink( const QString &sink = QString(), bool loadIntoProject = false );
%Docstring
Constructor for QgsProcessingFeatureSink, accepting a static string sink.
%End

QgsProcessingFeatureSink( const QgsProperty &sink, bool loadIntoProject = false );
%Docstring
Constructor for QgsProcessingFeatureSink.
Constructor for QgsProcessingFeatureSink, accepting a QgsProperty sink.
%End

QVariant sink;
QgsProperty sink;
%Docstring
Sink definition. Usually set to the destination file name for the sink's layer.
Sink definition. Usually a static property set to the destination file name for the sink's layer.
%End

bool loadIntoProject;
Expand Down
32 changes: 24 additions & 8 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -46,17 +46,25 @@ class CORE_EXPORT QgsProcessingFeatureSourceDefinition
public:

/**
* Constructor for QgsProcessingFeatureSourceDefinition.
* Constructor for QgsProcessingFeatureSourceDefinition, accepting a static string source.
*/
QgsProcessingFeatureSourceDefinition( const QVariant &source = QVariant(), bool selectedFeaturesOnly = false )
QgsProcessingFeatureSourceDefinition( const QString &source = QString(), bool selectedFeaturesOnly = false )
: source( QgsProperty::fromValue( source ) )
, selectedFeaturesOnly( selectedFeaturesOnly )
{}

/**
* Constructor for QgsProcessingFeatureSourceDefinition, accepting a QgsProperty source.
*/
QgsProcessingFeatureSourceDefinition( const QgsProperty &source, bool selectedFeaturesOnly = false )
: source( source )
, selectedFeaturesOnly( selectedFeaturesOnly )
{}

/**
* Source definition. Usually set to a source layer's ID or file name.
* Source definition. Usually a static property set to a source layer's ID or file name.
*/
QVariant source;
QgsProperty source;

/**
* True if only selected features in the source should be used by algorithms.
Expand Down Expand Up @@ -88,17 +96,25 @@ class CORE_EXPORT QgsProcessingFeatureSink
public:

/**
* Constructor for QgsProcessingFeatureSink.
* Constructor for QgsProcessingFeatureSink, accepting a static string sink.
*/
QgsProcessingFeatureSink( const QString &sink = QString(), bool loadIntoProject = false )
: sink( QgsProperty::fromValue( sink ) )
, loadIntoProject( loadIntoProject )
{}

/**
* Constructor for QgsProcessingFeatureSink, accepting a QgsProperty sink.
*/
QgsProcessingFeatureSink( const QVariant &sink = QVariant(), bool loadIntoProject = false )
QgsProcessingFeatureSink( const QgsProperty &sink, bool loadIntoProject = false )
: sink( sink )
, loadIntoProject( loadIntoProject )
{}

/**
* Sink definition. Usually set to the destination file name for the sink's layer.
* Sink definition. Usually a static property set to the destination file name for the sink's layer.
*/
QVariant sink;
QgsProperty sink;

/**
* True if sink should be loaded into the current project when the algorithm completes.
Expand Down
70 changes: 62 additions & 8 deletions tests/src/core/testqgsprocessing.cpp
Expand Up @@ -2329,34 +2329,88 @@ void TestQgsProcessing::combineLayerExtent()

void TestQgsProcessing::processingFeatureSource()
{
QVariant source( QStringLiteral( "test.shp" ) );
QgsProcessingFeatureSourceDefinition fs( source, true );
QCOMPARE( fs.source, source );
QString sourceString = QStringLiteral( "test.shp" );
QgsProcessingFeatureSourceDefinition fs( sourceString, true );
QCOMPARE( fs.source.staticValue().toString(), sourceString );
QVERIFY( fs.selectedFeaturesOnly );

// test storing QgsProcessingFeatureSource in variant and retrieving
QVariant fsInVariant = QVariant::fromValue( fs );
QVERIFY( fsInVariant.isValid() );

QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( fsInVariant );
QCOMPARE( fromVar.source, source );
QCOMPARE( fromVar.source.staticValue().toString(), sourceString );
QVERIFY( fromVar.selectedFeaturesOnly );

// test evaluating parameter as source
QgsVectorLayer *layer = new QgsVectorLayer( "Point", "v1", "memory" );
QgsFeature f( 10001 );
f.setGeometry( QgsGeometry( new QgsPoint( 1, 2 ) ) );
layer->dataProvider()->addFeatures( QgsFeatureList() << f );

QgsProject p;
p.addMapLayer( layer );
QgsProcessingContext context;
context.setProject( &p );

// first using static string definition
QgsProcessingParameterDefinition *def = new QgsProcessingParameterString( QStringLiteral( "layer" ) );
QVariantMap params;
params.insert( QStringLiteral( "layer" ), QgsProcessingFeatureSourceDefinition( layer->id(), false ) );
std::unique_ptr< QgsFeatureSource > source( QgsProcessingParameters::parameterAsSource( def, params, context ) );
// can't directly match it to layer, so instead just get the feature and test that it matches what we expect
QgsFeature f2;
QVERIFY( source.get() );
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, 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()
{
QVariant sink( QStringLiteral( "test.shp" ) );
QgsProcessingFeatureSink fs( sink, true );
QCOMPARE( fs.sink, sink );
QString sinkString( QStringLiteral( "test.shp" ) );
QgsProcessingFeatureSink fs( sinkString, true );
QCOMPARE( fs.sink.staticValue().toString(), sinkString );
QVERIFY( fs.loadIntoProject );

// test storing QgsProcessingFeatureSink in variant and retrieving
QVariant fsInVariant = QVariant::fromValue( fs );
QVERIFY( fsInVariant.isValid() );

QgsProcessingFeatureSink fromVar = qvariant_cast<QgsProcessingFeatureSink>( fsInVariant );
QCOMPARE( fromVar.sink, sink );
QCOMPARE( fromVar.sink.staticValue().toString(), sinkString );
QVERIFY( fromVar.loadIntoProject );

// test evaluating parameter as sink
QgsProject p;
QgsProcessingContext context;
context.setProject( &p );

// first using static string definition
QgsProcessingParameterDefinition *def = new QgsProcessingParameterString( QStringLiteral( "layer" ) );
QVariantMap params;
params.insert( QStringLiteral( "layer" ), QgsProcessingFeatureSink( "memory:test", false ) );
QString dest;
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingParameters::parameterAsSink( def, params, QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem( "EPSG:3111" ), context, dest ) );
QVERIFY( sink.get() );
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( dest, context, false ) );
QVERIFY( layer );
QCOMPARE( layer->crs().authid(), QStringLiteral( "EPSG:3111" ) );

// next using property based definition
params.insert( QStringLiteral( "layer" ), QgsProcessingFeatureSink( QgsProperty::fromExpression( QStringLiteral( "trim('memory' + ':test2')" ) ), false ) );
sink.reset( QgsProcessingParameters::parameterAsSink( def, params, QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem( "EPSG:3113" ), context, dest ) );
QVERIFY( sink.get() );
QgsVectorLayer *layer2 = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( dest, context, false ) );
QVERIFY( layer2 );
QCOMPARE( layer2->crs().authid(), QStringLiteral( "EPSG:3113" ) );
}

QGSTEST_MAIN( TestQgsProcessing )
Expand Down

0 comments on commit 72be86d

Please sign in to comment.