mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[processing] Cleanup some layer/writer related handling
Ensure that layers created by QgsProcessingUtils::createFeatureSink can always be retrieved using QgsProcessingUtils::mapLayerFromString
This commit is contained in:
parent
cb23ebed65
commit
6aa10c6817
@ -130,8 +130,7 @@ class QgsProcessingUtils
|
||||
const QgsFields &fields,
|
||||
QgsWkbTypes::Type geometryType,
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context,
|
||||
QgsVectorLayer **outputLayer /Out/ ) /PyName=createFeatureSink/;
|
||||
QgsProcessingContext &context ) /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
|
||||
@ -142,7 +141,7 @@ class QgsProcessingUtils
|
||||
If the ``encoding`` 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, and the ``outputLayer`` argument updated to point at this newly created layer.
|
||||
temporary layer store.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -86,7 +86,7 @@ class VectorSplit(GeoAlgorithm):
|
||||
for current, i in enumerate(uniqueValues):
|
||||
fName = u'{0}_{1}.shp'.format(baseName, str(i).strip())
|
||||
|
||||
writer, dest, _layer = QgsProcessingUtils.createFeatureSink(fName, None, fields, geomType, crs, context)
|
||||
writer, dest = QgsProcessingUtils.createFeatureSink(fName, None, fields, geomType, crs, context)
|
||||
for f in QgsProcessingUtils.getFeatures(layer, context):
|
||||
if f[fieldName] == i:
|
||||
writer.addFeature(f)
|
||||
|
@ -10,8 +10,8 @@ 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, writer_layer = QgsProcessingUtils.createFeatureSink(N_unique_values, None, fields, layer.wkbType(), layer.crs(),
|
||||
context)
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(N_unique_values, None, fields, layer.wkbType(), layer.crs(),
|
||||
context)
|
||||
|
||||
class_field_index = layer.fields().lookupField(class_field)
|
||||
value_field_index = layer.fields().lookupField(value_field)
|
||||
|
@ -385,8 +385,7 @@ class OutputVector(Output):
|
||||
settings = QgsSettings()
|
||||
self.encoding = settings.value('/Processing/encoding', 'System', str)
|
||||
|
||||
w, w_dest, w_layer = QgsProcessingUtils.createFeatureSink(self.value, self.encoding, fields, geomType, crs, context)
|
||||
self.layer = w_layer
|
||||
w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, self.encoding, fields, geomType, crs, context)
|
||||
self.value = w_dest
|
||||
return w
|
||||
|
||||
|
@ -61,11 +61,10 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True):
|
||||
continue
|
||||
if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
|
||||
try:
|
||||
if hasattr(out, "layer") and out.layer is not None:
|
||||
out.layer.setName(out.description)
|
||||
QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(out.layer))
|
||||
# temporary hack to work around mutable outputs
|
||||
out.layer = None
|
||||
layer = QgsProcessingUtils.mapLayerFromString(out.value, context)
|
||||
if layer:
|
||||
layer.setName(out.description)
|
||||
QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer))
|
||||
else:
|
||||
if ProcessingConfig.getSetting(
|
||||
ProcessingConfig.USE_FILENAME_AS_LAYER_NAME):
|
||||
|
@ -8,7 +8,7 @@ from qgis.core import QgsWkbTypes, QgsProcessingUtils
|
||||
layer = QgsProcessingUtils.mapLayerFromString(INPUT_LAYER, context)
|
||||
fields = layer.fields()
|
||||
|
||||
writer, writer_dest, writer_layer = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, 'utf-8', fields, QgsWkbTypes.Point, layer.crs(),
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, 'utf-8', fields, QgsWkbTypes.Point, layer.crs(),
|
||||
context)
|
||||
|
||||
features = QgsProcessingUtils.getFeatures(layer, context)
|
||||
|
@ -328,12 +328,10 @@ 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, QgsVectorLayer *&outputLayer )
|
||||
QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context )
|
||||
{
|
||||
outputLayer = nullptr;
|
||||
QgsVectorLayer *layer = nullptr;
|
||||
|
||||
QString destEncoding = encoding;
|
||||
QgsVectorLayer *layer = nullptr;
|
||||
if ( destEncoding.isEmpty() )
|
||||
{
|
||||
// no destination encoding specified, use default
|
||||
@ -344,8 +342,6 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
|
||||
{
|
||||
// memory provider cannot be used with QgsVectorLayerImport - so create layer manually
|
||||
layer = QgsMemoryProviderUtils::createMemoryLayer( destination, fields, geometryType, crs );
|
||||
if ( layer && layer->isValid() )
|
||||
destination = layer->id();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -376,6 +372,7 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// use destination string as layer name (eg "postgis:..." )
|
||||
layer = new QgsVectorLayer( uri, destination, providerKey );
|
||||
}
|
||||
}
|
||||
@ -389,19 +386,18 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, con
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// update destination to layer ID
|
||||
destination = layer->id();
|
||||
|
||||
context.temporaryLayerStore()->addMapLayer( layer );
|
||||
|
||||
outputLayer = layer;
|
||||
// this is a factory, so we need to return a proxy
|
||||
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, QgsVectorLayer **outputLayer )
|
||||
void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString &destination, const QString &encoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context )
|
||||
{
|
||||
QgsVectorLayer *layer = nullptr;
|
||||
*sink = createFeatureSink( destination, encoding, fields, geometryType, crs, context, layer );
|
||||
if ( outputLayer )
|
||||
*outputLayer = layer;
|
||||
*sink = createFeatureSink( destination, encoding, fields, geometryType, crs, context );
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,7 +141,7 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
* If the \a encoding 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, and the \a outputLayer argument updated to point at this newly created layer.
|
||||
* temporary layer store.
|
||||
*
|
||||
* The caller takes responsibility for deleting the returned sink.
|
||||
*/
|
||||
@ -152,8 +152,7 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
const QgsFields &fields,
|
||||
QgsWkbTypes::Type geometryType,
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context,
|
||||
QgsVectorLayer *&outputLayer ) SIP_FACTORY;
|
||||
QgsProcessingContext &context ) SIP_FACTORY;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -166,7 +165,7 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
* If the \a encoding 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, and the \a outputLayer argument updated to point at this newly created layer.
|
||||
* temporary layer store.
|
||||
*
|
||||
* \note this version of the createFeatureSink() function has an API designed around use from the
|
||||
* SIP bindings. c++ code should call the other createFeatureSink() version.
|
||||
@ -179,8 +178,7 @@ class CORE_EXPORT QgsProcessingUtils
|
||||
const QgsFields &fields,
|
||||
QgsWkbTypes::Type geometryType,
|
||||
const QgsCoordinateReferenceSystem &crs,
|
||||
QgsProcessingContext &context,
|
||||
QgsVectorLayer **outputLayer SIP_OUT ) SIP_PYNAME( createFeatureSink );
|
||||
QgsProcessingContext &context ) SIP_PYNAME( createFeatureSink );
|
||||
|
||||
|
||||
private:
|
||||
|
@ -748,8 +748,9 @@ void TestQgsProcessing::createFeatureSink()
|
||||
QgsVectorLayer *layer = nullptr;
|
||||
|
||||
// should create a memory layer
|
||||
QgsFeatureSink *sink = QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context, layer );
|
||||
QgsFeatureSink *sink = QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context );
|
||||
QVERIFY( sink );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
|
||||
QVERIFY( layer );
|
||||
QCOMPARE( static_cast< QgsProxyFeatureSink *>( sink )->destinationSink(), layer->dataProvider() );
|
||||
QCOMPARE( layer->dataProvider()->name(), QStringLiteral( "memory" ) );
|
||||
@ -765,8 +766,9 @@ void TestQgsProcessing::createFeatureSink()
|
||||
|
||||
// specific memory layer output
|
||||
destination = QStringLiteral( "memory:mylayer" );
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context, layer );
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), QgsFields(), QgsWkbTypes::Point, QgsCoordinateReferenceSystem(), context );
|
||||
QVERIFY( sink );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
|
||||
QVERIFY( layer );
|
||||
QCOMPARE( static_cast< QgsProxyFeatureSink *>( sink )->destinationSink(), layer->dataProvider() );
|
||||
QCOMPARE( layer->dataProvider()->name(), QStringLiteral( "memory" ) );
|
||||
@ -784,8 +786,9 @@ void TestQgsProcessing::createFeatureSink()
|
||||
destination = QStringLiteral( "memory:mylayer" );
|
||||
QgsFields fields;
|
||||
fields.append( QgsField( QStringLiteral( "my_field" ), QVariant::String, QString(), 100 ) );
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context, layer );
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::PointZM, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context );
|
||||
QVERIFY( sink );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, false ) );
|
||||
QVERIFY( layer );
|
||||
QCOMPARE( static_cast< QgsProxyFeatureSink *>( sink )->destinationSink(), layer->dataProvider() );
|
||||
QCOMPARE( layer->dataProvider()->name(), QStringLiteral( "memory" ) );
|
||||
@ -807,16 +810,15 @@ void TestQgsProcessing::createFeatureSink()
|
||||
// non memory layer output
|
||||
destination = QDir::tempPath() + "/create_feature_sink.tab";
|
||||
QString prevDest = destination;
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Polygon, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context, layer );
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Polygon, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context );
|
||||
QVERIFY( sink );
|
||||
f = QgsFeature( fields );
|
||||
f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Polygon((0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
|
||||
f.setAttributes( QgsAttributes() << "val" );
|
||||
QVERIFY( sink->addFeature( f ) );
|
||||
QVERIFY( !layer );
|
||||
QCOMPARE( destination, prevDest );
|
||||
delete sink;
|
||||
layer = new QgsVectorLayer( destination, "test_layer", "ogr" );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, true ) );
|
||||
QVERIFY( layer->isValid() );
|
||||
QCOMPARE( layer->crs().authid(), QStringLiteral( "EPSG:3111" ) );
|
||||
QCOMPARE( layer->fields().size(), 1 );
|
||||
@ -829,14 +831,14 @@ void TestQgsProcessing::createFeatureSink()
|
||||
// no extension, should default to shp
|
||||
destination = QDir::tempPath() + "/create_feature_sink2";
|
||||
prevDest = QDir::tempPath() + "/create_feature_sink2.shp";
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Point25D, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context, layer );
|
||||
sink = QgsProcessingUtils::createFeatureSink( destination, QString(), fields, QgsWkbTypes::Point25D, QgsCoordinateReferenceSystem::fromEpsgId( 3111 ), context );
|
||||
QVERIFY( sink );
|
||||
f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "PointZ(1 2 3)" ) ) );
|
||||
QVERIFY( sink->addFeature( f ) );
|
||||
QVERIFY( !layer );
|
||||
QCOMPARE( destination, prevDest );
|
||||
delete sink;
|
||||
layer = new QgsVectorLayer( destination, "test_layer", "ogr" );
|
||||
layer = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( destination, context, true ) );
|
||||
QCOMPARE( layer->wkbType(), QgsWkbTypes::Point25D );
|
||||
QCOMPARE( layer->crs().authid(), QStringLiteral( "EPSG:3111" ) );
|
||||
QCOMPARE( layer->fields().size(), 1 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user