Skip to content

Commit 005a08e

Browse files
committedJun 5, 2017
Create class for encapsulating settings relating to a feature sink
input to a processing algorithm. This allows parameter inputs to encapsulate extra information relating to a feature sink input, such as destination file encoding and whether the sink layer should be loaded into the project on completion
1 parent 5b8affc commit 005a08e

File tree

8 files changed

+172
-20
lines changed

8 files changed

+172
-20
lines changed
 

‎python/core/processing/qgsprocessingalgorithm.sip

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,15 @@ class QgsProcessingAlgorithm
308308
%End
309309

310310
QgsFeatureSink *parameterAsSink( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context,
311-
const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
311+
const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
312312
QString &destinationIdentifier /Out/ ) const /Factory/;
313313
%Docstring
314314
Evaluates the parameter with matching ``name`` to a feature sink.
315315

316316
Sinks will either be taken from ``context``'s active project, or created from external
317317
providers and stored temporarily in the ``context``.
318318

319-
The ``encoding``, ``fields``, ``geometryType`` and ``crs`` parameters dictate the properties
319+
The ``fields``, ``geometryType`` and ``crs`` parameters dictate the properties
320320
of the resulting feature sink.
321321

322322
The ``destinationIdentifier`` argument will be set to a string which can be used to retrieve the layer corresponding

‎python/core/processing/qgsprocessingparameters.sip

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,45 @@
1111

1212

1313

14+
class QgsProcessingFeatureSink
15+
{
16+
%Docstring
17+
18+
Encapsulates settings relating to a feature sink input to a processing algorithm.
19+
20+
.. versionadded:: 3.0
21+
%End
22+
23+
%TypeHeaderCode
24+
#include "qgsprocessingparameters.h"
25+
%End
26+
public:
27+
28+
QgsProcessingFeatureSink( const QVariant &sink = QVariant(), bool loadIntoProject = false );
29+
%Docstring
30+
Constructor for QgsProcessingFeatureSink.
31+
%End
32+
33+
QVariant sink;
34+
%Docstring
35+
Sink definition. Usually set to the destination file name for the sink's layer.
36+
%End
37+
38+
bool loadIntoProject;
39+
%Docstring
40+
True if sink should be loaded into the current project when the algorithm completes.
41+
%End
42+
43+
QString fileEncoding;
44+
%Docstring
45+
Encoding for destination file.
46+
%End
47+
48+
};
49+
50+
51+
52+
1453

1554

1655
class QgsProcessingParameterDefinition
@@ -266,12 +305,12 @@ class QgsProcessingParameters
266305
%End
267306

268307
static QgsFeatureSink *parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters,
269-
const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
308+
const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
270309
QgsProcessingContext &context, QString &destinationIdentifier /Out/ ) /Factory/;
271310
%Docstring
272311
Evaluates the parameter with matching ``definition`` to a feature sink.
273312

274-
The ``encoding``, ``fields``, ``geometryType`` and ``crs`` parameters dictate the properties
313+
The ``fields``, ``geometryType`` and ``crs`` parameters dictate the properties
275314
of the resulting feature sink.
276315

277316
Sinks will either be taken from ``context``'s active project, or created from external

‎src/core/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ QVariantMap QgsCentroidAlgorithm::processAlgorithm( const QVariantMap &parameter
8383
return QVariantMap();
8484

8585
QString dest;
86-
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT_LAYER" ), context, QString(), layer->fields(), QgsWkbTypes::Point, layer->crs(), dest ) );
86+
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT_LAYER" ), context, layer->fields(), QgsWkbTypes::Point, layer->crs(), dest ) );
8787

8888
long count = QgsProcessingUtils::featureCount( layer, context );
8989
if ( count <= 0 )
@@ -156,7 +156,7 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
156156
return QVariantMap();
157157

158158
QString dest;
159-
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT_LAYER" ), context, QString(), layer->fields(), QgsWkbTypes::Polygon, layer->crs(), dest ) );
159+
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT_LAYER" ), context, layer->fields(), QgsWkbTypes::Polygon, layer->crs(), dest ) );
160160

161161
// fixed parameters
162162
//bool dissolve = QgsProcessingParameters::parameterAsBool( parameters, QStringLiteral( "DISSOLVE" ), context );

‎src/core/processing/qgsprocessingalgorithm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ bool QgsProcessingAlgorithm::parameterAsBool( const QVariantMap &parameters, con
210210
return QgsProcessingParameters::parameterAsBool( parameterDefinition( name ), parameters, context );
211211
}
212212

213-
QgsFeatureSink *QgsProcessingAlgorithm::parameterAsSink( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QString &destinationIdentifier ) const
213+
QgsFeatureSink *QgsProcessingAlgorithm::parameterAsSink( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QString &destinationIdentifier ) const
214214
{
215-
return QgsProcessingParameters::parameterAsSink( parameterDefinition( name ), parameters, encoding, fields, geometryType, crs, context, destinationIdentifier );
215+
return QgsProcessingParameters::parameterAsSink( parameterDefinition( name ), parameters, fields, geometryType, crs, context, destinationIdentifier );
216216
}
217217

218218
QgsMapLayer *QgsProcessingAlgorithm::parameterAsLayer( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const

‎src/core/processing/qgsprocessingalgorithm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ class CORE_EXPORT QgsProcessingAlgorithm
304304
* Sinks will either be taken from \a context's active project, or created from external
305305
* providers and stored temporarily in the \a context.
306306
*
307-
* The \a encoding, \a fields, \a geometryType and \a crs parameters dictate the properties
307+
* The \a fields, \a geometryType and \a crs parameters dictate the properties
308308
* of the resulting feature sink.
309309
*
310310
* The \a destinationIdentifier argument will be set to a string which can be used to retrieve the layer corresponding
@@ -313,7 +313,7 @@ class CORE_EXPORT QgsProcessingAlgorithm
313313
* This function creates a new object and the caller takes responsibility for deleting the returned object.
314314
*/
315315
QgsFeatureSink *parameterAsSink( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context,
316-
const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
316+
const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
317317
QString &destinationIdentifier SIP_OUT ) const SIP_FACTORY;
318318

319319
/**

‎src/core/processing/qgsprocessingparameters.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,48 @@ bool QgsProcessingParameters::parameterAsBool( const QgsProcessingParameterDefin
202202
return def.toBool();
203203
}
204204

205-
QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QString &encoding, const QgsFields &fields,
205+
QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsFields &fields,
206206
QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
207207
QgsProcessingContext &context, QString &destinationIdentifier )
208208
{
209-
QString dest = parameterAsString( definition, parameters, context );
209+
QVariant val;
210+
if ( definition )
211+
{
212+
val = parameters.value( definition->name() );
213+
}
214+
215+
bool loadIntoProject = false;
216+
QString encoding;
217+
if ( val.canConvert<QgsProcessingFeatureSink>() )
218+
{
219+
// input is a QgsProcessingFeatureSink - get extra properties from it
220+
QgsProcessingFeatureSink fromVar = qvariant_cast<QgsProcessingFeatureSink>( val );
221+
loadIntoProject = fromVar.loadIntoProject;
222+
encoding = fromVar.fileEncoding;
223+
val = fromVar.sink;
224+
}
225+
226+
QString dest;
227+
if ( val.canConvert<QgsProperty>() )
228+
{
229+
dest = val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
230+
}
231+
else if ( !val.isValid() || val.toString().isEmpty() )
232+
{
233+
// fall back to default
234+
dest = definition->defaultValue().toString();
235+
}
236+
else
237+
{
238+
dest = val.toString();
239+
}
240+
210241
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, encoding, fields, geometryType, crs, context ) );
211242
destinationIdentifier = dest;
212243

244+
if ( loadIntoProject )
245+
context.addLayerToLoadOnCompletion( destinationIdentifier );
246+
213247
return sink.release();
214248
}
215249

‎src/core/processing/qgsprocessingparameters.h

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,47 @@ class QgsRasterLayer;
3030
class QgsVectorLayer;
3131
class QgsFeatureSink;
3232

33+
/**
34+
* \class QgsProcessingFeatureSink
35+
* \ingroup core
36+
*
37+
* Encapsulates settings relating to a feature sink input to a processing algorithm.
38+
*
39+
* \since QGIS 3.0
40+
*/
41+
42+
class CORE_EXPORT QgsProcessingFeatureSink
43+
{
44+
public:
45+
46+
/**
47+
* Constructor for QgsProcessingFeatureSink.
48+
*/
49+
QgsProcessingFeatureSink( const QVariant &sink = QVariant(), bool loadIntoProject = false )
50+
: sink( sink )
51+
, loadIntoProject( loadIntoProject )
52+
{}
53+
54+
/**
55+
* Sink definition. Usually set to the destination file name for the sink's layer.
56+
*/
57+
QVariant sink;
58+
59+
/**
60+
* True if sink should be loaded into the current project when the algorithm completes.
61+
*/
62+
bool loadIntoProject;
63+
64+
/**
65+
* Encoding for destination file.
66+
*/
67+
QString fileEncoding;
68+
69+
};
70+
71+
Q_DECLARE_METATYPE( QgsProcessingFeatureSink )
72+
73+
3374

3475
//
3576
// Parameter definitions
@@ -285,7 +326,7 @@ class CORE_EXPORT QgsProcessingParameters
285326
/**
286327
* Evaluates the parameter with matching \a definition to a feature sink.
287328
*
288-
* The \a encoding, \a fields, \a geometryType and \a crs parameters dictate the properties
329+
* The \a fields, \a geometryType and \a crs parameters dictate the properties
289330
* of the resulting feature sink.
290331
*
291332
* Sinks will either be taken from \a context's active project, or created from external
@@ -296,7 +337,7 @@ class CORE_EXPORT QgsProcessingParameters
296337
* This function creates a new object and the caller takes responsibility for deleting the returned object.
297338
*/
298339
static QgsFeatureSink *parameterAsSink( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters,
299-
const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
340+
const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs,
300341
QgsProcessingContext &context, QString &destinationIdentifier SIP_OUT ) SIP_FACTORY;
301342

302343
/**

‎tests/src/core/testqgsprocessing.cpp

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ class TestQgsProcessing: public QObject
217217
void parameterOutputVectorLayer();
218218
void checkParamValues();
219219
void combineLayerExtent();
220+
void processingFeatureSink();
220221

221222
private:
222223

@@ -1062,15 +1063,15 @@ void TestQgsProcessing::parameters()
10621063
// make sure layer was loaded
10631064
QVERIFY( !context.temporaryLayerStore()->mapLayers().isEmpty() );
10641065

1065-
// as sink
1066-
QString encoding;
1066+
// parameters as sinks
1067+
10671068
QgsWkbTypes::Type wkbType = QgsWkbTypes::PolygonM;
1068-
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem( "epsg:3111" );
1069+
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem( QStringLiteral( "epsg:3111" ) );
10691070
QString destId;
10701071
def->setName( QStringLiteral( "string" ) );
10711072
params.insert( QStringLiteral( "string" ), QStringLiteral( "memory:mem" ) );
10721073
std::unique_ptr< QgsFeatureSink > sink;
1073-
sink.reset( QgsProcessingParameters::parameterAsSink( def, params, encoding, fields, wkbType, crs, context, destId ) );
1074+
sink.reset( QgsProcessingParameters::parameterAsSink( def, params, fields, wkbType, crs, context, destId ) );
10741075
QVERIFY( sink.get() );
10751076
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destId, context ) );
10761077
QVERIFY( layer );
@@ -1083,8 +1084,8 @@ void TestQgsProcessing::parameters()
10831084
// property defined sink destination
10841085
params.insert( QStringLiteral( "prop" ), QgsProperty::fromExpression( "'memory:mem2'" ) );
10851086
def->setName( QStringLiteral( "prop" ) );
1086-
crs = QgsCoordinateReferenceSystem( "epsg:3113" );
1087-
sink.reset( QgsProcessingParameters::parameterAsSink( def, params, encoding, fields, wkbType, crs, context, destId ) );
1087+
crs = QgsCoordinateReferenceSystem( QStringLiteral( "epsg:3113" ) );
1088+
sink.reset( QgsProcessingParameters::parameterAsSink( def, params, fields, wkbType, crs, context, destId ) );
10881089
QVERIFY( sink.get() );
10891090
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destId, context ) );
10901091
QVERIFY( layer );
@@ -1094,6 +1095,27 @@ void TestQgsProcessing::parameters()
10941095
QCOMPARE( layer->wkbType(), wkbType );
10951096
QCOMPARE( layer->crs(), crs );
10961097

1098+
// QgsProcessingFeatureSink as parameter
1099+
QgsProcessingFeatureSink fs( QStringLiteral( "test.shp" ) );
1100+
fs.loadIntoProject = true;
1101+
QVERIFY( context.layersToLoadOnCompletion().isEmpty() );
1102+
params.insert( QStringLiteral( "fs" ), QVariant::fromValue( fs ) );
1103+
def->setName( QStringLiteral( "fs" ) );
1104+
crs = QgsCoordinateReferenceSystem( QStringLiteral( "epsg:28356" ) );
1105+
sink.reset( QgsProcessingParameters::parameterAsSink( def, params, fields, wkbType, crs, context, destId ) );
1106+
QVERIFY( sink.get() );
1107+
QgsVectorFileWriter *writer = dynamic_cast< QgsVectorFileWriter *>( sink.get() );
1108+
QVERIFY( writer );
1109+
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destId, context ) );
1110+
QVERIFY( layer );
1111+
QVERIFY( layer->isValid() );
1112+
QCOMPARE( layer->wkbType(), wkbType );
1113+
QCOMPARE( layer->crs(), crs );
1114+
1115+
// make sure layer was automatically added to list to load on completion
1116+
QCOMPARE( context.layersToLoadOnCompletion().size(), 1 );
1117+
QCOMPARE( context.layersToLoadOnCompletion().at( 0 ), destId );
1118+
10971119
delete def;
10981120
}
10991121

@@ -2249,5 +2271,21 @@ void TestQgsProcessing::combineLayerExtent()
22492271
QGSCOMPARENEAR( ext.yMaximum(), 3536664, 10 );
22502272
}
22512273

2274+
void TestQgsProcessing::processingFeatureSink()
2275+
{
2276+
QVariant sink( QStringLiteral( "test.shp" ) );
2277+
QgsProcessingFeatureSink fs( sink, true );
2278+
QCOMPARE( fs.sink, sink );
2279+
QVERIFY( fs.loadIntoProject );
2280+
2281+
// test storing QgsProcessingFeatureSink in variant and retrieving
2282+
QVariant fsInVariant = QVariant::fromValue( fs );
2283+
QVERIFY( fsInVariant.isValid() );
2284+
2285+
QgsProcessingFeatureSink fromVar = qvariant_cast<QgsProcessingFeatureSink>( fsInVariant );
2286+
QCOMPARE( fromVar.sink, sink );
2287+
QVERIFY( fromVar.loadIntoProject );
2288+
}
2289+
22522290
QGSTEST_MAIN( TestQgsProcessing )
22532291
#include "testqgsprocessing.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.