QGIS API Documentation 3.43.0-Master (ebb4087afc0)
Loading...
Searching...
No Matches
qgsvectorlayerexporter.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayerexporter.cpp
3 -------------------
4 begin : Thu Aug 25 2011
5 copyright : (C) 2011 by Giuseppe Sucameli
6 email : brush.tyler at gmail.com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18
19#include "qgsfields.h"
20#include "qgsfeature.h"
21#include "qgsfeatureiterator.h"
22#include "qgsgeometry.h"
23#include "qgslogger.h"
24#include "qgsmessagelog.h"
28#include "moc_qgsvectorlayerexporter.cpp"
29#include "qgsproviderregistry.h"
30#include "qgsexception.h"
32#include "qgsvectorlayer.h"
33#include "qgsabstractgeometry.h"
35
36#include <QProgressDialog>
37
39 const QString &uri,
40 const QgsFields &fields,
41 Qgis::WkbType geometryType,
42 const QgsCoordinateReferenceSystem &destCRS,
43 bool overwrite,
44 QMap<int, int> *oldToNewAttrIdx,
45 QString *errorMessage,
46 const QMap<QString, QVariant> *options
47);
48
49
51 const QString &providerKey,
52 const QgsFields &fields,
53 Qgis::WkbType geometryType,
55 bool overwrite,
56 const QMap<QString, QVariant> &options,
58 : mErrorCount( 0 )
59 , mAttributeCount( -1 )
60
61{
62 mProvider = nullptr;
63
64 QMap<QString, QVariant> modifiedOptions( options );
65
66 if ( providerKey == QLatin1String( "ogr" ) &&
67 options.contains( QStringLiteral( "driverName" ) ) &&
68 ( options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "GPKG" ), Qt::CaseInsensitive ) == 0 ||
69 options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "SQLite" ), Qt::CaseInsensitive ) == 0 ) )
70 {
71 if ( geometryType != Qgis::WkbType::NoGeometry )
72 {
73 // For GPKG/Spatialite, we explicitly ask not to create a spatial index at
74 // layer creation since this would slow down inserts. Defer its creation
75 // to end of exportLayer() or destruction of this object.
76 QStringList modifiedLayerOptions;
77 if ( options.contains( QStringLiteral( "layerOptions" ) ) )
78 {
79 const QStringList layerOptions = options.value( QStringLiteral( "layerOptions" ) ).toStringList();
80 for ( const QString &layerOption : layerOptions )
81 {
82 if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=YES" ), Qt::CaseInsensitive ) == 0 ||
83 layerOption.compare( QLatin1String( "SPATIAL_INDEX=ON" ), Qt::CaseInsensitive ) == 0 ||
84 layerOption.compare( QLatin1String( "SPATIAL_INDEX=TRUE" ), Qt::CaseInsensitive ) == 0 ||
85 layerOption.compare( QLatin1String( "SPATIAL_INDEX=1" ), Qt::CaseInsensitive ) == 0 )
86 {
87 // do nothing
88 }
89 else if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=NO" ), Qt::CaseInsensitive ) == 0 ||
90 layerOption.compare( QLatin1String( "SPATIAL_INDEX=OFF" ), Qt::CaseInsensitive ) == 0 ||
91 layerOption.compare( QLatin1String( "SPATIAL_INDEX=FALSE" ), Qt::CaseInsensitive ) == 0 ||
92 layerOption.compare( QLatin1String( "SPATIAL_INDEX=0" ), Qt::CaseInsensitive ) == 0 )
93 {
94 mCreateSpatialIndex = false;
95 }
96 else
97 {
98 modifiedLayerOptions << layerOption;
99 }
100 }
101 }
102 modifiedLayerOptions << QStringLiteral( "SPATIAL_INDEX=FALSE" );
103 modifiedOptions[ QStringLiteral( "layerOptions" ) ] = modifiedLayerOptions;
104 }
105 }
106
107 // create an empty layer
108 QString errMsg;
110 QString uriUpdated;
111 mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx,
112 errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr, uriUpdated );
113
115 {
116 mErrorMessage = errMsg;
117 return;
118 }
119
120 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
121 for ( const int idx : constMOldToNewAttrIdx )
122 {
123 if ( idx > mAttributeCount )
124 mAttributeCount = idx;
125 }
126
127 mAttributeCount++;
128
129 QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 );
130
131 // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need
132 // to force it in the uri
133 if ( providerKey == QLatin1String( "oracle" ) )
134 {
135 uriUpdated += QStringLiteral( " type=%1" ).arg( QgsWkbTypes::displayString( geometryType ) );
136 }
137
138 const QgsDataProvider::ProviderOptions providerOptions;
139 QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
140 if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & Qgis::VectorProviderCapability::AddFeatures ) == 0 )
141 {
143 mErrorMessage = QObject::tr( "Loading of layer failed" );
144
145 delete vectorProvider;
146 return;
147 }
148
149 // If the result is a geopackage layer and there is already a field name FID requested which
150 // might contain duplicates, make sure to generate a new field with a unique name instead
151 // that will be filled by ogr with unique values.
152
153 // HACK sorry
154 const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
155 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
156 {
157 const QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
158 const int fidIdx = fields.lookupField( fidName );
159 if ( fidIdx != -1 )
160 {
161 mOldToNewAttrIdx.remove( fidIdx );
162 }
163 }
164
165 mProvider = vectorProvider;
167}
168
170{
171 flushBuffer();
172
173 if ( mCreateSpatialIndex )
174 {
175 createSpatialIndex();
176 }
177
178 delete mProvider;
179}
180
185
187{
188 return mErrorMessage;
189}
190
195
197{
198 QgsFeatureList::iterator fIt = features.begin();
199 bool result = true;
200 for ( ; fIt != features.end(); ++fIt )
201 {
202 result = result && addFeature( *fIt, flags );
203 }
204 return result;
205}
206
208{
209 const QgsAttributes attrs = feat.attributes();
210
211 QgsFeature newFeat;
212 if ( feat.hasGeometry() )
213 newFeat.setGeometry( feat.geometry() );
214
215 newFeat.initAttributes( mAttributeCount );
216
217 for ( int i = 0; i < attrs.count(); ++i )
218 {
219 // add only mapped attributes (un-mapped ones will not be present in the
220 // destination layer)
221 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
222 if ( dstIdx < 0 )
223 continue;
224
225 QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
226 newFeat.setAttribute( dstIdx, attrs.at( i ) );
227 }
228
229 mFeatureBuffer.append( newFeat );
230 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
231
232 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
233 {
234 return flushBuffer();
235 }
236
237 return true;
238}
239
241{
242 return mErrorMessage;
243}
244
246{
247 mFeatureBufferMemoryUsage = 0;
248 if ( mFeatureBuffer.count() <= 0 )
249 return true;
250
251 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
252 {
253 const QStringList errors = mProvider->errors();
254 mProvider->clearErrors();
255
256 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors were: \n%3" )
257 .arg( mFeatureBuffer.first().id() )
258 .arg( mFeatureBuffer.last().id() )
259 .arg( errors.join( QLatin1Char( '\n' ) ) );
260
262 mErrorCount += mFeatureBuffer.count();
263
264 mFeatureBuffer.clear();
265 QgsDebugError( mErrorMessage );
266 return false;
267 }
268
269 mFeatureBuffer.clear();
270 return true;
271}
272
273bool QgsVectorLayerExporter::createSpatialIndex()
274{
275 mCreateSpatialIndex = false;
276 if ( mProvider && ( mProvider->capabilities() & Qgis::VectorProviderCapability::CreateSpatialIndex ) != 0 )
277 {
278 return mProvider->createSpatialIndex();
279 }
280 else
281 {
282 return true;
283 }
284}
285
287 const QString &uri,
288 const QString &providerKey,
289 const QgsCoordinateReferenceSystem &destCRS,
290 bool onlySelected,
291 QString *errorMessage,
292 const QMap<QString, QVariant> &options,
293 QgsFeedback *feedback )
294{
297 bool shallTransform = false;
298
299 if ( !layer )
301
302 if ( destCRS.isValid() )
303 {
304 // This means we should transform
305 outputCRS = destCRS;
306 shallTransform = true;
307 }
308 else
309 {
310 // This means we shouldn't transform, use source CRS as output (if defined)
311 outputCRS = layer->crs();
312 }
313
314
315 bool overwrite = false;
316 bool forceSinglePartGeom = false;
317 QMap<QString, QVariant> providerOptions = options;
318 if ( !options.isEmpty() )
319 {
320 overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
321 forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
322 }
323
324 QgsFields fields = layer->fields();
325
326 Qgis::WkbType wkbType = layer->wkbType();
327
328 bool convertGeometryToSinglePart = false;
329 if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
330 {
331 wkbType = QgsWkbTypes::singleType( wkbType );
332 convertGeometryToSinglePart = true;
333 }
334
335 QgsVectorLayerExporter *writer =
336 new QgsVectorLayerExporter( uri, providerKey, fields, wkbType, outputCRS, overwrite, providerOptions );
337
338 // check whether file creation was successful
339 const Qgis::VectorExportResult err = writer->errorCode();
341 {
342 if ( errorMessage )
343 *errorMessage = writer->errorMessage();
344 delete writer;
345 return err;
346 }
347
348 if ( errorMessage )
349 {
350 errorMessage->clear();
351 }
352
353 QgsFeature fet;
354
356 if ( wkbType == Qgis::WkbType::NoGeometry )
358 if ( onlySelected )
359 req.setFilterFids( layer->selectedFeatureIds() );
360
361 QgsFeatureIterator fit = layer->getFeatures( req );
362
363 // Create our transform
364 if ( destCRS.isValid() )
365 {
366 ct = QgsCoordinateTransform( layer->crs(), destCRS, layer->transformContext() );
367 }
368
369 // Check for failure
370 if ( !ct.isValid() )
371 shallTransform = false;
372
373 long long n = 0;
374 const long long approxTotal = onlySelected ? layer->selectedFeatureCount() : layer->featureCount();
375
376 if ( errorMessage )
377 {
378 *errorMessage = QObject::tr( "Feature write errors:" );
379 }
380
381 bool canceled = false;
382
383 // write all features
384 while ( fit.nextFeature( fet ) )
385 {
386 if ( feedback && feedback->isCanceled() )
387 {
388 canceled = true;
389 if ( errorMessage )
390 {
391 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
392 }
393 break;
394 }
395
396 if ( writer->errorCount() > 1000 )
397 {
398 if ( errorMessage )
399 {
400 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
401 }
402 break;
403 }
404
405 if ( shallTransform )
406 {
407 try
408 {
409 if ( fet.hasGeometry() )
410 {
411 QgsGeometry g = fet.geometry();
412 g.transform( ct );
413 fet.setGeometry( g );
414 }
415 }
416 catch ( QgsCsException &e )
417 {
418 delete writer;
419
420 const QString msg = QObject::tr( "Failed to transform feature with ID '%1'. Writing stopped. (Exception: %2)" )
421 .arg( fet.id() ).arg( e.what() );
422 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
423 if ( errorMessage )
424 *errorMessage += '\n' + msg;
425
427 }
428 }
429
430 // Handles conversion to single-part
431 if ( convertGeometryToSinglePart && fet.geometry().isMultipart() )
432 {
433 QgsGeometry singlePartGeometry { fet.geometry() };
434 // We want a failure if the geometry cannot be converted to single-part without data loss!
435 // check if there are more than one part
436 const QgsGeometryCollection *c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
437 if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
438 {
439 delete writer;
440 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
441 .arg( fet.id() );
442 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
443 if ( errorMessage )
444 *errorMessage += '\n' + msg;
446 }
447 fet.setGeometry( singlePartGeometry );
448 }
449
450 if ( !writer->addFeature( fet ) )
451 {
453 {
454 *errorMessage += '\n' + writer->errorMessage();
455 }
456 }
457 n++;
458
459 if ( feedback )
460 {
461 feedback->setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
462 }
463
464 }
465
466 // flush the buffer to be sure that all features are written
467 if ( !writer->flushBuffer() )
468 {
470 {
471 *errorMessage += '\n' + writer->errorMessage();
472 }
473 }
474 const int errors = writer->errorCount();
475
476 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
477 {
479 {
480 *errorMessage += '\n' + writer->errorMessage();
481 }
482 }
483
484 delete writer;
485
486 if ( errorMessage )
487 {
488 if ( errors > 0 )
489 {
490 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
491 }
492 else
493 {
494 errorMessage->clear();
495 }
496 }
497
498 if ( canceled )
500 else if ( errors > 0 )
502
504}
505
506
507//
508// QgsVectorLayerExporterTask
509//
510
511QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
512 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
513 , mLayer( layer )
514 , mOwnsLayer( ownsLayer )
515 , mDestUri( uri )
516 , mDestProviderKey( providerKey )
517 , mDestCrs( destinationCrs )
518 , mOptions( options )
519 , mOwnedFeedback( new QgsFeedback() )
520{
521 if ( mLayer )
522 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
523}
524
525QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
526{
527 auto newTask = std::make_unique<QgsVectorLayerExporterTask>( layer, uri, providerKey, destinationCrs, options );
528 newTask->mOwnsLayer = true;
529 return newTask.release();
530}
531
533{
534 mOwnedFeedback->cancel();
536}
537
539{
540 if ( !mLayer )
541 return false;
542
543 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
544
545
547 mLayer.data(), mDestUri, mDestProviderKey, mDestCrs, false, &mErrorMessage,
548 mOptions, mOwnedFeedback.get() );
549
550 return mError == Qgis::VectorExportResult::Success;
551}
552
554{
555 // QgsMapLayer has QTimer member, which must not be destroyed from another thread
556 if ( mOwnsLayer )
557 delete mLayer;
558
559 if ( result )
560 emit exportComplete();
561 else
562 emit errorOccurred( mError, mErrorMessage );
563}
@ AddFeatures
Allows adding features.
@ CreateSpatialIndex
Allows creation of spatial index.
VectorExportResult
Vector layer export result codes.
Definition qgis.h:1013
@ Success
No errors were encountered.
@ ErrorInvalidLayer
Could not access newly created destination layer.
@ ErrorFeatureWriteFailed
An error occurred while writing a feature to the destination.
@ UserCanceled
User canceled the export.
@ ErrorProjectingFeatures
An error occurred while reprojecting features to destination CRS.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QFlags< VectorDataProviderAttributeEditCapability > VectorDataProviderAttributeEditCapabilities
Attribute editing capabilities which may be supported by vector data providers.
Definition qgis.h:566
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ NoGeometry
No geometry.
A vector of attributes.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Class for doing transforms between two map coordinate systems.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Custom exception class for Coordinate Reference System related exceptions.
virtual bool isValid() const =0
Returns true if this is a valid layer.
QString what() const
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QFlags< SinkFlag > SinkFlags
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
QFlags< Flag > Flags
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
QgsAttributes attributes
Definition qgsfeature.h:67
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
QgsFeatureId id
Definition qgsfeature.h:66
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
QgsGeometry geometry
Definition qgsfeature.h:69
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
Container of fields for a vector layer.
Definition qgsfields.h:46
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:83
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
A registry / canonical manager of data providers.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, Qgis::WkbType wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options, QString &createdLayerName)
Creates new empty vector layer.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions(), Qgis::DataProviderReadFlags flags=Qgis::DataProviderReadFlags())
Creates a new instance of a provider.
Abstract base class for long running background tasks.
virtual void cancel()
Notifies the task that it should terminate.
void setDependentLayers(const QList< QgsMapLayer * > &dependentLayers)
Sets a list of layers on which the task depends.
void setProgress(double progress)
Sets the task's current progress.
This is the base class for vector data providers.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
void clearErrors()
Clear recorded errors.
QStringList errors() const
Gets recorded errors.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
virtual Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the provider's supported attribute editing capabilities.
QgsTask task which performs a QgsVectorLayerExporter layer export operation as a background task.
void finished(bool result) override
If the task is managed by a QgsTaskManager, this will be called after the task has finished (whether ...
QgsVectorLayerExporterTask(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), bool ownsLayer=false)
Constructor for QgsVectorLayerExporterTask.
void exportComplete()
Emitted when exporting the layer is successfully completed.
void errorOccurred(Qgis::VectorExportResult error, const QString &errorMessage)
Emitted when an error occurs which prevented the layer being exported (or if the task is canceled).
void cancel() override
Notifies the task that it should terminate.
static QgsVectorLayerExporterTask * withLayerOwnership(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >())
Creates a new QgsVectorLayerExporterTask which has ownership over a source layer.
bool run() override
Performs the task's operation.
A convenience class for exporting vector layers to a destination data provider.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
static Qgis::VectorExportResult exportLayer(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destCRS, bool onlySelected=false, QString *errorMessage=nullptr, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeedback *feedback=nullptr)
Writes the contents of vector layer to a different datasource.
int errorCount() const
Returns the number of error messages encountered during the export.
QString errorMessage() const
Returns any error message encountered during the export.
Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the attribute capabilities of the exporter.
~QgsVectorLayerExporter() override
Finalizes the export and closes the new created layer.
QString lastError() const override
Returns the most recent error encountered by the sink, e.g.
bool flushBuffer() override
Flushes any internal buffer which may exist in the sink, causing any buffered features to be added to...
Qgis::VectorExportResult errorCode() const
Returns any encountered error code, or false if no error was encountered.
QgsVectorLayerExporter(const QString &uri, const QString &provider, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &crs, bool overwrite=false, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Constructor for QgsVectorLayerExporter.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
Represents a vector layer which manages a vector based data sets.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
static bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
static QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
Definition qgswkbtypes.h:53
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QList< QgsFeature > QgsFeatureList
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:41
#define QgsDebugError(str)
Definition qgslogger.h:40
Qgis::VectorExportResult createEmptyLayer_t(const QString &uri, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &destCRS, bool overwrite, QMap< int, int > *oldToNewAttrIdx, QString *errorMessage, const QMap< QString, QVariant > *options)
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.