Skip to content

Commit d7aa3f5

Browse files
committedJun 5, 2017
[processing] Change explicit encoding string parameters to more
flexible QVariantMap creatOptions parameters which include an optional fileEncoding value More flexible, allows sinks to be created using any creation option which is passed to the underlying provider
1 parent ea2e477 commit d7aa3f5

File tree

11 files changed

+50
-39
lines changed

11 files changed

+50
-39
lines changed
 

‎python/core/processing/qgsprocessingparameters.sip

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,12 @@ class QgsProcessingFeatureSink
8080
True if sink should be loaded into the current project when the algorithm completes.
8181
%End
8282

83-
QString fileEncoding;
83+
QVariantMap createOptions;
8484
%Docstring
85-
Encoding for destination file.
85+
Map of optional sink creation options, which
86+
are passed to the underlying provider when creating new layers. Known options also
87+
include 'fileEncoding', which is used to specify a file encoding to use for created
88+
files.
8689
%End
8790

8891

‎python/core/processing/qgsprocessingutils.sip

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,22 @@ class QgsProcessingUtils
9090
static void createFeatureSinkPython(
9191
QgsFeatureSink **sink /Out,TransferBack/,
9292
QString &destination /In,Out/,
93-
const QString &encoding,
93+
QgsProcessingContext &context,
9494
const QgsFields &fields,
9595
QgsWkbTypes::Type geometryType,
9696
const QgsCoordinateReferenceSystem &crs,
97-
QgsProcessingContext &context ) /PyName=createFeatureSink/;
97+
const QVariantMap &createOptions = QVariantMap() ) /PyName=createFeatureSink/;
9898
%Docstring
9999
Creates a feature sink ready for adding features. The ``destination`` specifies a destination
100100
URI for the resultant layer. It may be updated in place to reflect the actual destination
101101
for the layer.
102102

103-
Sink parameters such as desired ``encoding``, ``fields``, ``geometryType`` and ``crs`` must be specified.
103+
Sink parameters such as desired ``fields``, ``geometryType`` and ``crs`` must be specified.
104104

105-
If the ``encoding`` is not specified, the default encoding from the ``context`` will be used.
105+
The ``createOptions`` map can be used to specify additional sink creation options, which
106+
are passed to the underlying provider when creating new layers. Known options also
107+
include 'fileEncoding', which is used to specify a file encoding to use for created
108+
files. If 'fileEncoding' is not specified, the default encoding from the ``context`` will be used.
106109

107110
If a layer is created for the feature sink, the layer will automatically be added to the ``context``'s
108111
temporary layer store.

‎python/plugins/processing/algs/qgis/VectorSplit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def processAlgorithm(self, parameters, context, feedback):
8787
for current, i in enumerate(uniqueValues):
8888
fName = u'{0}_{1}.shp'.format(baseName, str(i).strip())
8989

90-
writer, dest = QgsProcessingUtils.createFeatureSink(fName, None, fields, geomType, crs, context)
90+
writer, dest = QgsProcessingUtils.createFeatureSink(fName, context, fields, geomType, crs)
9191
for f in QgsProcessingUtils.getFeatures(layer, context):
9292
if f[fieldName] == i:
9393
writer.addFeature(f)

‎python/plugins/processing/algs/qgis/scripts/Number_of_unique_values_in_classes.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
layer = QgsProcessingUtils.mapLayerFromString(input, context)
1111
fields = layer.fields()
1212
fields.append(QgsField('UNIQ_COUNT', QVariant.Int))
13-
writer, writer_dest = QgsProcessingUtils.createFeatureSink(N_unique_values, None, fields, layer.wkbType(), layer.crs(),
14-
context)
13+
writer, writer_dest = QgsProcessingUtils.createFeatureSink(N_unique_values, context, fields, layer.wkbType(), layer.crs())
1514

1615
class_field_index = layer.fields().lookupField(class_field)
1716
value_field_index = layer.fields().lookupField(value_field)

‎python/plugins/processing/core/outputs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ def getVectorWriter(self, fields, geomType, crs, context):
369369
settings = QgsSettings()
370370
self.encoding = settings.value('/Processing/encoding', 'System', str)
371371

372-
w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, self.encoding, fields, geomType, crs, context)
372+
w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, context, fields, geomType, crs, {'fileEncoding': self.encoding})
373373
self.value = w_dest
374374
return w
375375

‎python/plugins/processing/tests/testdata/scripts/centroids.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
layer = QgsProcessingUtils.mapLayerFromString(INPUT_LAYER, context)
99
fields = layer.fields()
1010

11-
writer, writer_dest = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, 'utf-8', fields, QgsWkbTypes.Point, layer.crs(),
12-
context)
11+
writer, writer_dest = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, context, fields, QgsWkbTypes.Point, layer.crs(), {'fileEncoding': 'utf-8'})
1312

1413
features = QgsProcessingUtils.getFeatures(layer, context)
1514
count = QgsProcessingUtils.featureCount(layer, context)

‎src/core/processing/qgsprocessingparameters.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,13 @@ QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingPar
214214
}
215215

216216
bool loadIntoProject = false;
217-
QString encoding;
217+
QVariantMap createOptions;
218218
if ( val.canConvert<QgsProcessingFeatureSink>() )
219219
{
220220
// input is a QgsProcessingFeatureSink - get extra properties from it
221221
QgsProcessingFeatureSink fromVar = qvariant_cast<QgsProcessingFeatureSink>( val );
222222
loadIntoProject = fromVar.loadIntoProject;
223-
encoding = fromVar.fileEncoding;
223+
createOptions = fromVar.createOptions;
224224
val = fromVar.sink;
225225
}
226226

@@ -239,7 +239,7 @@ QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingPar
239239
dest = val.toString();
240240
}
241241

242-
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, encoding, fields, geometryType, crs, context ) );
242+
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, createOptions ) );
243243
destinationIdentifier = dest;
244244

245245
if ( loadIntoProject )

‎src/core/processing/qgsprocessingparameters.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ class CORE_EXPORT QgsProcessingFeatureSink
106106
bool loadIntoProject;
107107

108108
/**
109-
* Encoding for destination file.
109+
* Map of optional sink creation options, which
110+
* are passed to the underlying provider when creating new layers. Known options also
111+
* include 'fileEncoding', which is used to specify a file encoding to use for created
112+
* files.
110113
*/
111-
QString fileEncoding;
114+
QVariantMap createOptions;
112115

113116

114117
//! Allows direct construction of QVariants.

‎src/core/processing/qgsprocessingutils.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,14 @@ void parseDestinationString( QString &destination, QString &providerKey, QString
262262
}
263263
}
264264

265-
QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context )
265+
QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions )
266266
{
267-
QString destEncoding = encoding;
267+
QVariantMap options = createOptions;
268268
QgsVectorLayer *layer = nullptr;
269-
if ( destEncoding.isEmpty() )
269+
if ( !options.contains( QStringLiteral( "fileEncoding" ) ) )
270270
{
271271
// no destination encoding specified, use default
272-
destEncoding = context.defaultEncoding().isEmpty() ? QStringLiteral( "system" ) : context.defaultEncoding();
272+
options.insert( QStringLiteral( "fileEncoding" ), context.defaultEncoding().isEmpty() ? QStringLiteral( "system" ) : context.defaultEncoding() );
273273
}
274274

275275
if ( destination.isEmpty() || destination.startsWith( QStringLiteral( "memory:" ) ) )
@@ -279,9 +279,6 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
279279
}
280280
else
281281
{
282-
QMap<QString, QVariant> options;
283-
options.insert( QStringLiteral( "fileEncoding" ), destEncoding );
284-
285282
QString providerKey;
286283
QString uri;
287284
QString format;
@@ -292,7 +289,7 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
292289
// use QgsVectorFileWriter for OGR destinations instead of QgsVectorLayerImport, as that allows
293290
// us to use any OGR format which supports feature addition
294291
QString finalFileName;
295-
QgsVectorFileWriter *writer = new QgsVectorFileWriter( destination, destEncoding, fields, geometryType, crs, format, QgsVectorFileWriter::defaultDatasetOptions( format ),
292+
QgsVectorFileWriter *writer = new QgsVectorFileWriter( destination, options.value( QStringLiteral( "fileEncoding" ) ).toString(), fields, geometryType, crs, format, QgsVectorFileWriter::defaultDatasetOptions( format ),
296293
QgsVectorFileWriter::defaultLayerOptions( format ), &finalFileName );
297294
destination = finalFileName;
298295
return writer;
@@ -329,9 +326,9 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
329326
return new QgsProxyFeatureSink( layer->dataProvider() );
330327
}
331328

332-
void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString &destination, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context )
329+
void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &options )
333330
{
334-
*sink = createFeatureSink( destination, encoding, fields, geometryType, crs, context );
331+
*sink = createFeatureSink( destination, context, fields, geometryType, crs, options );
335332
}
336333

337334

‎src/core/processing/qgsprocessingutils.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class QgsProcessingContext;
3030
class QgsMapLayerStore;
3131

3232
#include <QString>
33+
#include <QVariant>
3334

3435
/**
3536
* \class QgsProcessingUtils
@@ -106,7 +107,10 @@ class CORE_EXPORT QgsProcessingUtils
106107
*
107108
* Sink parameters such as desired \a encoding, \a fields, \a geometryType and \a crs must be specified.
108109
*
109-
* If the \a encoding is not specified, the default encoding from the \a context will be used.
110+
* The \a createOptions map can be used to specify additional sink creation options, which
111+
* are passed to the underlying provider when creating new layers. Known options also
112+
* include 'fileEncoding', which is used to specify a file encoding to use for created
113+
* files. If 'fileEncoding' is not specified, the default encoding from the \a context will be used.
110114
*
111115
* If a layer is created for the feature sink, the layer will automatically be added to the \a context's
112116
* temporary layer store.
@@ -116,21 +120,24 @@ class CORE_EXPORT QgsProcessingUtils
116120
#ifndef SIP_RUN
117121
static QgsFeatureSink *createFeatureSink(
118122
QString &destination,
119-
const QString &encoding,
123+
QgsProcessingContext &context,
120124
const QgsFields &fields,
121125
QgsWkbTypes::Type geometryType,
122126
const QgsCoordinateReferenceSystem &crs,
123-
QgsProcessingContext &context ) SIP_FACTORY;
127+
const QVariantMap &createOptions = QVariantMap() ) SIP_FACTORY;
124128
#endif
125129

126130
/**
127131
* Creates a feature sink ready for adding features. The \a destination specifies a destination
128132
* URI for the resultant layer. It may be updated in place to reflect the actual destination
129133
* for the layer.
130134
*
131-
* Sink parameters such as desired \a encoding, \a fields, \a geometryType and \a crs must be specified.
135+
* Sink parameters such as desired \a fields, \a geometryType and \a crs must be specified.
132136
*
133-
* If the \a encoding is not specified, the default encoding from the \a context will be used.
137+
* The \a createOptions map can be used to specify additional sink creation options, which
138+
* are passed to the underlying provider when creating new layers. Known options also
139+
* include 'fileEncoding', which is used to specify a file encoding to use for created
140+
* files. If 'fileEncoding' is not specified, the default encoding from the \a context will be used.
134141
*
135142
* If a layer is created for the feature sink, the layer will automatically be added to the \a context's
136143
* temporary layer store.
@@ -142,11 +149,11 @@ class CORE_EXPORT QgsProcessingUtils
142149
static void createFeatureSinkPython(
143150
QgsFeatureSink **sink SIP_OUT SIP_TRANSFERBACK,
144151
QString &destination SIP_INOUT,
145-
const QString &encoding,
152+
QgsProcessingContext &context,
146153
const QgsFields &fields,
147154
QgsWkbTypes::Type geometryType,
148155
const QgsCoordinateReferenceSystem &crs,
149-
QgsProcessingContext &context ) SIP_PYNAME( createFeatureSink );
156+
const QVariantMap &createOptions = QVariantMap() ) SIP_PYNAME( createFeatureSink );
150157

151158
/**
152159
* Combines the extent of several map \a layers. If specified, the target \a crs

‎tests/src/core/testqgsprocessing.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ void TestQgsProcessing::createFeatureSink()
921921
QgsVectorLayer *layer = nullptr;
922922

923923
// should create a memory layer
924-
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context ) );
924+
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( destination, context, QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem() ) );
925925
QVERIFY( sink.get() );
926926
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
927927
QVERIFY( layer );
@@ -938,7 +938,7 @@ void TestQgsProcessing::createFeatureSink()
938938

939939
// specific memory layer output
940940
destination = QStringLiteral( "memory:mylayer" );
941-
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context ) );
941+
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem() ) );
942942
QVERIFY( sink.get() );
943943
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
944944
QVERIFY( layer );
@@ -957,7 +957,7 @@ void TestQgsProcessing::createFeatureSink()
957957
destination = QStringLiteral( "memory:mylayer" );
958958
QgsFields fields;
959959
fields.append( QgsField( QStringLiteral( "my_field" ), QVariant::String, QString(), 100 ) );
960-
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context ) );
960+
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) );
961961
QVERIFY( sink.get() );
962962
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
963963
QVERIFY( layer );
@@ -980,7 +980,7 @@ void TestQgsProcessing::createFeatureSink()
980980
// non memory layer output
981981
destination = QDir::tempPath() + "/create_feature_sink.tab";
982982
QString prevDest = destination;
983-
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Polygon, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context ) );
983+
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::Polygon, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) );
984984
QVERIFY( sink.get() );
985985
f = QgsFeature( fields );
986986
f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Polygon((0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
@@ -1001,7 +1001,7 @@ void TestQgsProcessing::createFeatureSink()
10011001
// no extension, should default to shp
10021002
destination = QDir::tempPath() + "/create_feature_sink2";
10031003
prevDest = QDir::tempPath() + "/create_feature_sink2.shp";
1004-
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Point25D, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context ) );
1004+
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::Point25D, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) );
10051005
QVERIFY( sink.get() );
10061006
f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "PointZ(1 2 3)" ) ) );
10071007
QVERIFY( sink->addFeature( f ) );

0 commit comments

Comments
 (0)
Please sign in to comment.