mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[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
This commit is contained in:
parent
ea2e477d91
commit
d7aa3f5f7c
@ -80,9 +80,12 @@ class QgsProcessingFeatureSink
|
||||
True if sink should be loaded into the current project when the algorithm completes.
|
||||
%End
|
||||
|
||||
QString fileEncoding;
|
||||
QVariantMap createOptions;
|
||||
%Docstring
|
||||
Encoding for destination file.
|
||||
Map of optional sink creation options, which
|
||||
are passed to the underlying provider when creating new layers. Known options also
|
||||
include 'fileEncoding', which is used to specify a file encoding to use for created
|
||||
files.
|
||||
%End
|
||||
|
||||
|
||||
|
@ -90,19 +90,22 @@ class QgsProcessingUtils
|
||||
static void createFeatureSinkPython(
|
||||
QgsFeatureSink **sink /Out,TransferBack/,
|
||||
QString &destination /In,Out/,
|
||||
const QString &encoding,
|
||||
QgsProcessingContext &context,
|
||||
const QgsFields &fields,
|
||||
QgsWkbTypes::Type geometryType,
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context ) /PyName=createFeatureSink/;
|
||||
const QVariantMap &createOptions = QVariantMap() ) /PyName=createFeatureSink/;
|
||||
%Docstring
|
||||
Creates a feature sink ready for adding features. The ``destination`` specifies a destination
|
||||
URI for the resultant layer. It may be updated in place to reflect the actual destination
|
||||
for the layer.
|
||||
|
||||
Sink parameters such as desired ``encoding``, ``fields``, ``geometryType`` and ``crs`` must be specified.
|
||||
Sink parameters such as desired ``fields``, ``geometryType`` and ``crs`` must be specified.
|
||||
|
||||
If the ``encoding`` is not specified, the default encoding from the ``context`` will be used.
|
||||
The ``createOptions`` map can be used to specify additional sink creation options, which
|
||||
are passed to the underlying provider when creating new layers. Known options also
|
||||
include 'fileEncoding', which is used to specify a file encoding to use for created
|
||||
files. If 'fileEncoding' is not specified, the default encoding from the ``context`` will be used.
|
||||
|
||||
If a layer is created for the feature sink, the layer will automatically be added to the ``context``'s
|
||||
temporary layer store.
|
||||
|
@ -87,7 +87,7 @@ class VectorSplit(QgisAlgorithm):
|
||||
for current, i in enumerate(uniqueValues):
|
||||
fName = u'{0}_{1}.shp'.format(baseName, str(i).strip())
|
||||
|
||||
writer, dest = QgsProcessingUtils.createFeatureSink(fName, None, fields, geomType, crs, context)
|
||||
writer, dest = QgsProcessingUtils.createFeatureSink(fName, context, fields, geomType, crs)
|
||||
for f in QgsProcessingUtils.getFeatures(layer, context):
|
||||
if f[fieldName] == i:
|
||||
writer.addFeature(f)
|
||||
|
@ -10,8 +10,7 @@ from qgis.core import QgsFeature, QgsField, QgsProcessingUtils
|
||||
layer = QgsProcessingUtils.mapLayerFromString(input, context)
|
||||
fields = layer.fields()
|
||||
fields.append(QgsField('UNIQ_COUNT', QVariant.Int))
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(N_unique_values, None, fields, layer.wkbType(), layer.crs(),
|
||||
context)
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(N_unique_values, context, fields, layer.wkbType(), layer.crs())
|
||||
|
||||
class_field_index = layer.fields().lookupField(class_field)
|
||||
value_field_index = layer.fields().lookupField(value_field)
|
||||
|
@ -369,7 +369,7 @@ class OutputVector(Output):
|
||||
settings = QgsSettings()
|
||||
self.encoding = settings.value('/Processing/encoding', 'System', str)
|
||||
|
||||
w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, self.encoding, fields, geomType, crs, context)
|
||||
w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, context, fields, geomType, crs, {'fileEncoding': self.encoding})
|
||||
self.value = w_dest
|
||||
return w
|
||||
|
||||
|
@ -8,8 +8,7 @@ from qgis.core import QgsWkbTypes, QgsProcessingUtils
|
||||
layer = QgsProcessingUtils.mapLayerFromString(INPUT_LAYER, context)
|
||||
fields = layer.fields()
|
||||
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, 'utf-8', fields, QgsWkbTypes.Point, layer.crs(),
|
||||
context)
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, context, fields, QgsWkbTypes.Point, layer.crs(), {'fileEncoding': 'utf-8'})
|
||||
|
||||
features = QgsProcessingUtils.getFeatures(layer, context)
|
||||
count = QgsProcessingUtils.featureCount(layer, context)
|
||||
|
@ -214,13 +214,13 @@ QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingPar
|
||||
}
|
||||
|
||||
bool loadIntoProject = false;
|
||||
QString encoding;
|
||||
QVariantMap createOptions;
|
||||
if ( val.canConvert<QgsProcessingFeatureSink>() )
|
||||
{
|
||||
// input is a QgsProcessingFeatureSink - get extra properties from it
|
||||
QgsProcessingFeatureSink fromVar = qvariant_cast<QgsProcessingFeatureSink>( val );
|
||||
loadIntoProject = fromVar.loadIntoProject;
|
||||
encoding = fromVar.fileEncoding;
|
||||
createOptions = fromVar.createOptions;
|
||||
val = fromVar.sink;
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ QgsFeatureSink *QgsProcessingParameters::parameterAsSink( const QgsProcessingPar
|
||||
dest = val.toString();
|
||||
}
|
||||
|
||||
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, encoding, fields, geometryType, crs, context ) );
|
||||
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( dest, context, fields, geometryType, crs, createOptions ) );
|
||||
destinationIdentifier = dest;
|
||||
|
||||
if ( loadIntoProject )
|
||||
|
@ -106,9 +106,12 @@ class CORE_EXPORT QgsProcessingFeatureSink
|
||||
bool loadIntoProject;
|
||||
|
||||
/**
|
||||
* Encoding for destination file.
|
||||
* Map of optional sink creation options, which
|
||||
* are passed to the underlying provider when creating new layers. Known options also
|
||||
* include 'fileEncoding', which is used to specify a file encoding to use for created
|
||||
* files.
|
||||
*/
|
||||
QString fileEncoding;
|
||||
QVariantMap createOptions;
|
||||
|
||||
|
||||
//! Allows direct construction of QVariants.
|
||||
|
@ -262,14 +262,14 @@ void parseDestinationString( QString &destination, QString &providerKey, QString
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context )
|
||||
QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions )
|
||||
{
|
||||
QString destEncoding = encoding;
|
||||
QVariantMap options = createOptions;
|
||||
QgsVectorLayer *layer = nullptr;
|
||||
if ( destEncoding.isEmpty() )
|
||||
if ( !options.contains( QStringLiteral( "fileEncoding" ) ) )
|
||||
{
|
||||
// no destination encoding specified, use default
|
||||
destEncoding = context.defaultEncoding().isEmpty() ? QStringLiteral( "system" ) : context.defaultEncoding();
|
||||
options.insert( QStringLiteral( "fileEncoding" ), context.defaultEncoding().isEmpty() ? QStringLiteral( "system" ) : context.defaultEncoding() );
|
||||
}
|
||||
|
||||
if ( destination.isEmpty() || destination.startsWith( QStringLiteral( "memory:" ) ) )
|
||||
@ -279,9 +279,6 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
|
||||
}
|
||||
else
|
||||
{
|
||||
QMap<QString, QVariant> options;
|
||||
options.insert( QStringLiteral( "fileEncoding" ), destEncoding );
|
||||
|
||||
QString providerKey;
|
||||
QString uri;
|
||||
QString format;
|
||||
@ -292,7 +289,7 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
|
||||
// use QgsVectorFileWriter for OGR destinations instead of QgsVectorLayerImport, as that allows
|
||||
// us to use any OGR format which supports feature addition
|
||||
QString finalFileName;
|
||||
QgsVectorFileWriter *writer = new QgsVectorFileWriter( destination, destEncoding, fields, geometryType, crs, format, QgsVectorFileWriter::defaultDatasetOptions( format ),
|
||||
QgsVectorFileWriter *writer = new QgsVectorFileWriter( destination, options.value( QStringLiteral( "fileEncoding" ) ).toString(), fields, geometryType, crs, format, QgsVectorFileWriter::defaultDatasetOptions( format ),
|
||||
QgsVectorFileWriter::defaultLayerOptions( format ), &finalFileName );
|
||||
destination = finalFileName;
|
||||
return writer;
|
||||
@ -329,9 +326,9 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
|
||||
return new QgsProxyFeatureSink( layer->dataProvider() );
|
||||
}
|
||||
|
||||
void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString &destination, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context )
|
||||
void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &options )
|
||||
{
|
||||
*sink = createFeatureSink( destination, encoding, fields, geometryType, crs, context );
|
||||
*sink = createFeatureSink( destination, context, fields, geometryType, crs, options );
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ class QgsProcessingContext;
|
||||
class QgsMapLayerStore;
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
/**
|
||||
* \class QgsProcessingUtils
|
||||
@ -106,7 +107,10 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
*
|
||||
* Sink parameters such as desired \a encoding, \a fields, \a geometryType and \a crs must be specified.
|
||||
*
|
||||
* If the \a encoding is not specified, the default encoding from the \a context will be used.
|
||||
* The \a createOptions map can be used to specify additional sink creation options, which
|
||||
* are passed to the underlying provider when creating new layers. Known options also
|
||||
* include 'fileEncoding', which is used to specify a file encoding to use for created
|
||||
* files. If 'fileEncoding' is not specified, the default encoding from the \a context will be used.
|
||||
*
|
||||
* If a layer is created for the feature sink, the layer will automatically be added to the \a context's
|
||||
* temporary layer store.
|
||||
@ -116,11 +120,11 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
#ifndef SIP_RUN
|
||||
static QgsFeatureSink *createFeatureSink(
|
||||
QString &destination,
|
||||
const QString &encoding,
|
||||
QgsProcessingContext &context,
|
||||
const QgsFields &fields,
|
||||
QgsWkbTypes::Type geometryType,
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context ) SIP_FACTORY;
|
||||
const QVariantMap &createOptions = QVariantMap() ) SIP_FACTORY;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -128,9 +132,12 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
* URI for the resultant layer. It may be updated in place to reflect the actual destination
|
||||
* for the layer.
|
||||
*
|
||||
* Sink parameters such as desired \a encoding, \a fields, \a geometryType and \a crs must be specified.
|
||||
* Sink parameters such as desired \a fields, \a geometryType and \a crs must be specified.
|
||||
*
|
||||
* If the \a encoding is not specified, the default encoding from the \a context will be used.
|
||||
* The \a createOptions map can be used to specify additional sink creation options, which
|
||||
* are passed to the underlying provider when creating new layers. Known options also
|
||||
* include 'fileEncoding', which is used to specify a file encoding to use for created
|
||||
* files. If 'fileEncoding' is not specified, the default encoding from the \a context will be used.
|
||||
*
|
||||
* If a layer is created for the feature sink, the layer will automatically be added to the \a context's
|
||||
* temporary layer store.
|
||||
@ -142,11 +149,11 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
static void createFeatureSinkPython(
|
||||
QgsFeatureSink **sink SIP_OUT SIP_TRANSFERBACK,
|
||||
QString &destination SIP_INOUT,
|
||||
const QString &encoding,
|
||||
QgsProcessingContext &context,
|
||||
const QgsFields &fields,
|
||||
QgsWkbTypes::Type geometryType,
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context ) SIP_PYNAME( createFeatureSink );
|
||||
const QVariantMap &createOptions = QVariantMap() ) SIP_PYNAME( createFeatureSink );
|
||||
|
||||
/**
|
||||
* Combines the extent of several map \a layers. If specified, the target \a crs
|
||||
|
@ -921,7 +921,7 @@ void TestQgsProcessing::createFeatureSink()
|
||||
QgsVectorLayer *layer = nullptr;
|
||||
|
||||
// should create a memory layer
|
||||
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context ) );
|
||||
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( destination, context, QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem() ) );
|
||||
QVERIFY( sink.get() );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
|
||||
QVERIFY( layer );
|
||||
@ -938,7 +938,7 @@ void TestQgsProcessing::createFeatureSink()
|
||||
|
||||
// specific memory layer output
|
||||
destination = QStringLiteral( "memory:mylayer" );
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context ) );
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem() ) );
|
||||
QVERIFY( sink.get() );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
|
||||
QVERIFY( layer );
|
||||
@ -957,7 +957,7 @@ void TestQgsProcessing::createFeatureSink()
|
||||
destination = QStringLiteral( "memory:mylayer" );
|
||||
QgsFields fields;
|
||||
fields.append( QgsField( QStringLiteral( "my_field" ), QVariant::String, QString(), 100 ) );
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context ) );
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) );
|
||||
QVERIFY( sink.get() );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
|
||||
QVERIFY( layer );
|
||||
@ -980,7 +980,7 @@ void TestQgsProcessing::createFeatureSink()
|
||||
// non memory layer output
|
||||
destination = QDir::tempPath() + "/create_feature_sink.tab";
|
||||
QString prevDest = destination;
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Polygon, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context ) );
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::Polygon, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) );
|
||||
QVERIFY( sink.get() );
|
||||
f = QgsFeature( fields );
|
||||
f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Polygon((0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
|
||||
@ -1001,7 +1001,7 @@ void TestQgsProcessing::createFeatureSink()
|
||||
// no extension, should default to shp
|
||||
destination = QDir::tempPath() + "/create_feature_sink2";
|
||||
prevDest = QDir::tempPath() + "/create_feature_sink2.shp";
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Point25D, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context ) );
|
||||
sink.reset( QgsProcessingUtils::createFeatureSink( destination, context, fields, QgsWkbTypes::Point25D, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ) ) );
|
||||
QVERIFY( sink.get() );
|
||||
f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "PointZ(1 2 3)" ) ) );
|
||||
QVERIFY( sink->addFeature( f ) );
|
||||
|
Loading…
x
Reference in New Issue
Block a user