QGIS API Documentation 3.39.0-Master (52f98f8c831)
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 "qgsproviderregistry.h"
29#include "qgsexception.h"
31#include "qgsvectorlayer.h"
32#include "qgsabstractgeometry.h"
34
35#include <QProgressDialog>
36
38 const QString &uri,
39 const QgsFields &fields,
40 Qgis::WkbType geometryType,
41 const QgsCoordinateReferenceSystem &destCRS,
42 bool overwrite,
43 QMap<int, int> *oldToNewAttrIdx,
44 QString *errorMessage,
45 const QMap<QString, QVariant> *options
46);
47
48
50 const QString &providerKey,
51 const QgsFields &fields,
52 Qgis::WkbType geometryType,
54 bool overwrite,
55 const QMap<QString, QVariant> &options,
57 : mErrorCount( 0 )
58 , mAttributeCount( -1 )
59
60{
61 mProvider = nullptr;
62
63 QMap<QString, QVariant> modifiedOptions( options );
64
65 if ( providerKey == QLatin1String( "ogr" ) &&
66 options.contains( QStringLiteral( "driverName" ) ) &&
67 ( options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "GPKG" ), Qt::CaseInsensitive ) == 0 ||
68 options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "SQLite" ), Qt::CaseInsensitive ) == 0 ) )
69 {
70 if ( geometryType != Qgis::WkbType::NoGeometry )
71 {
72 // For GPKG/Spatialite, we explicitly ask not to create a spatial index at
73 // layer creation since this would slow down inserts. Defer its creation
74 // to end of exportLayer() or destruction of this object.
75 QStringList modifiedLayerOptions;
76 if ( options.contains( QStringLiteral( "layerOptions" ) ) )
77 {
78 const QStringList layerOptions = options.value( QStringLiteral( "layerOptions" ) ).toStringList();
79 for ( const QString &layerOption : layerOptions )
80 {
81 if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=YES" ), Qt::CaseInsensitive ) == 0 ||
82 layerOption.compare( QLatin1String( "SPATIAL_INDEX=ON" ), Qt::CaseInsensitive ) == 0 ||
83 layerOption.compare( QLatin1String( "SPATIAL_INDEX=TRUE" ), Qt::CaseInsensitive ) == 0 ||
84 layerOption.compare( QLatin1String( "SPATIAL_INDEX=1" ), Qt::CaseInsensitive ) == 0 )
85 {
86 // do nothing
87 }
88 else if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=NO" ), Qt::CaseInsensitive ) == 0 ||
89 layerOption.compare( QLatin1String( "SPATIAL_INDEX=OFF" ), Qt::CaseInsensitive ) == 0 ||
90 layerOption.compare( QLatin1String( "SPATIAL_INDEX=FALSE" ), Qt::CaseInsensitive ) == 0 ||
91 layerOption.compare( QLatin1String( "SPATIAL_INDEX=0" ), Qt::CaseInsensitive ) == 0 )
92 {
93 mCreateSpatialIndex = false;
94 }
95 else
96 {
97 modifiedLayerOptions << layerOption;
98 }
99 }
100 }
101 modifiedLayerOptions << QStringLiteral( "SPATIAL_INDEX=FALSE" );
102 modifiedOptions[ QStringLiteral( "layerOptions" ) ] = modifiedLayerOptions;
103 }
104 }
105
106 // create an empty layer
107 QString errMsg;
109 mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx,
110 errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr );
111
113 {
114 mErrorMessage = errMsg;
115 return;
116 }
117
118 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
119 for ( const int idx : constMOldToNewAttrIdx )
120 {
121 if ( idx > mAttributeCount )
122 mAttributeCount = idx;
123 }
124
125 mAttributeCount++;
126
127 QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 );
128
129 QString uriUpdated( uri );
130 // HACK sorry...
131 if ( providerKey == QLatin1String( "ogr" ) )
132 {
133 QString layerName;
134 if ( options.contains( QStringLiteral( "layerName" ) ) )
135 layerName = options.value( QStringLiteral( "layerName" ) ).toString();
136 if ( !layerName.isEmpty() )
137 {
138 uriUpdated += QLatin1String( "|layername=" );
139 uriUpdated += layerName;
140 }
141 }
142
143 // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need
144 // to force it in the uri
145 if ( providerKey == QLatin1String( "oracle" ) )
146 {
147 uriUpdated += QStringLiteral( " type=%1" ).arg( QgsWkbTypes::displayString( geometryType ) );
148 }
149
150 const QgsDataProvider::ProviderOptions providerOptions;
151 QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
152 if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 )
153 {
155 mErrorMessage = QObject::tr( "Loading of layer failed" );
156
157 delete vectorProvider;
158 return;
159 }
160
161 // If the result is a geopackage layer and there is already a field name FID requested which
162 // might contain duplicates, make sure to generate a new field with a unique name instead
163 // that will be filled by ogr with unique values.
164
165 // HACK sorry
166 const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
167 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
168 {
169 const QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
170 const int fidIdx = fields.lookupField( fidName );
171 if ( fidIdx != -1 )
172 {
173 mOldToNewAttrIdx.remove( fidIdx );
174 }
175 }
176
177 mProvider = vectorProvider;
179}
180
182{
183 flushBuffer();
184
185 if ( mCreateSpatialIndex )
186 {
187 createSpatialIndex();
188 }
189
190 delete mProvider;
191}
192
197
199{
200 return mErrorMessage;
201}
202
207
209{
210 QgsFeatureList::iterator fIt = features.begin();
211 bool result = true;
212 for ( ; fIt != features.end(); ++fIt )
213 {
214 result = result && addFeature( *fIt, flags );
215 }
216 return result;
217}
218
220{
221 const QgsAttributes attrs = feat.attributes();
222
223 QgsFeature newFeat;
224 if ( feat.hasGeometry() )
225 newFeat.setGeometry( feat.geometry() );
226
227 newFeat.initAttributes( mAttributeCount );
228
229 for ( int i = 0; i < attrs.count(); ++i )
230 {
231 // add only mapped attributes (un-mapped ones will not be present in the
232 // destination layer)
233 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
234 if ( dstIdx < 0 )
235 continue;
236
237 QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
238 newFeat.setAttribute( dstIdx, attrs.at( i ) );
239 }
240
241 mFeatureBuffer.append( newFeat );
242 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
243
244 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
245 {
246 return flushBuffer();
247 }
248
249 return true;
250}
251
253{
254 return mErrorMessage;
255}
256
258{
259 mFeatureBufferMemoryUsage = 0;
260 if ( mFeatureBuffer.count() <= 0 )
261 return true;
262
263 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
264 {
265 const QStringList errors = mProvider->errors();
266 mProvider->clearErrors();
267
268 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
269 .arg( mFeatureBuffer.first().id() )
270 .arg( mFeatureBuffer.last().id() )
271 .arg( errors.join( QLatin1Char( '\n' ) ) );
272
274 mErrorCount += mFeatureBuffer.count();
275
276 mFeatureBuffer.clear();
277 QgsDebugError( mErrorMessage );
278 return false;
279 }
280
281 mFeatureBuffer.clear();
282 return true;
283}
284
285bool QgsVectorLayerExporter::createSpatialIndex()
286{
287 mCreateSpatialIndex = false;
288 if ( mProvider && ( mProvider->capabilities() & QgsVectorDataProvider::CreateSpatialIndex ) != 0 )
289 {
290 return mProvider->createSpatialIndex();
291 }
292 else
293 {
294 return true;
295 }
296}
297
299 const QString &uri,
300 const QString &providerKey,
301 const QgsCoordinateReferenceSystem &destCRS,
302 bool onlySelected,
303 QString *errorMessage,
304 const QMap<QString, QVariant> &options,
305 QgsFeedback *feedback )
306{
309 bool shallTransform = false;
310
311 if ( !layer )
313
314 if ( destCRS.isValid() )
315 {
316 // This means we should transform
317 outputCRS = destCRS;
318 shallTransform = true;
319 }
320 else
321 {
322 // This means we shouldn't transform, use source CRS as output (if defined)
323 outputCRS = layer->crs();
324 }
325
326
327 bool overwrite = false;
328 bool forceSinglePartGeom = false;
329 QMap<QString, QVariant> providerOptions = options;
330 if ( !options.isEmpty() )
331 {
332 overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
333 forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
334 }
335
336 QgsFields fields = layer->fields();
337
338 Qgis::WkbType wkbType = layer->wkbType();
339
340 bool convertGeometryToSinglePart = false;
341 if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
342 {
343 wkbType = QgsWkbTypes::singleType( wkbType );
344 convertGeometryToSinglePart = true;
345 }
346
347 QgsVectorLayerExporter *writer =
348 new QgsVectorLayerExporter( uri, providerKey, fields, wkbType, outputCRS, overwrite, providerOptions );
349
350 // check whether file creation was successful
351 const Qgis::VectorExportResult err = writer->errorCode();
353 {
354 if ( errorMessage )
355 *errorMessage = writer->errorMessage();
356 delete writer;
357 return err;
358 }
359
360 if ( errorMessage )
361 {
362 errorMessage->clear();
363 }
364
365 QgsFeature fet;
366
368 if ( wkbType == Qgis::WkbType::NoGeometry )
370 if ( onlySelected )
371 req.setFilterFids( layer->selectedFeatureIds() );
372
373 QgsFeatureIterator fit = layer->getFeatures( req );
374
375 // Create our transform
376 if ( destCRS.isValid() )
377 {
378 ct = QgsCoordinateTransform( layer->crs(), destCRS, layer->transformContext() );
379 }
380
381 // Check for failure
382 if ( !ct.isValid() )
383 shallTransform = false;
384
385 long long n = 0;
386 const long long approxTotal = onlySelected ? layer->selectedFeatureCount() : layer->featureCount();
387
388 if ( errorMessage )
389 {
390 *errorMessage = QObject::tr( "Feature write errors:" );
391 }
392
393 bool canceled = false;
394
395 // write all features
396 while ( fit.nextFeature( fet ) )
397 {
398 if ( feedback && feedback->isCanceled() )
399 {
400 canceled = true;
401 if ( errorMessage )
402 {
403 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
404 }
405 break;
406 }
407
408 if ( writer->errorCount() > 1000 )
409 {
410 if ( errorMessage )
411 {
412 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
413 }
414 break;
415 }
416
417 if ( shallTransform )
418 {
419 try
420 {
421 if ( fet.hasGeometry() )
422 {
423 QgsGeometry g = fet.geometry();
424 g.transform( ct );
425 fet.setGeometry( g );
426 }
427 }
428 catch ( QgsCsException &e )
429 {
430 delete writer;
431
432 const QString msg = QObject::tr( "Failed to transform feature with ID '%1'. Writing stopped. (Exception: %2)" )
433 .arg( fet.id() ).arg( e.what() );
434 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
435 if ( errorMessage )
436 *errorMessage += '\n' + msg;
437
439 }
440 }
441
442 // Handles conversion to single-part
443 if ( convertGeometryToSinglePart && fet.geometry().isMultipart() )
444 {
445 QgsGeometry singlePartGeometry { fet.geometry() };
446 // We want a failure if the geometry cannot be converted to single-part without data loss!
447 // check if there are more than one part
448 const QgsGeometryCollection *c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
449 if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
450 {
451 delete writer;
452 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
453 .arg( fet.id() );
454 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
455 if ( errorMessage )
456 *errorMessage += '\n' + msg;
458 }
459 fet.setGeometry( singlePartGeometry );
460 }
461
462 if ( !writer->addFeature( fet ) )
463 {
465 {
466 *errorMessage += '\n' + writer->errorMessage();
467 }
468 }
469 n++;
470
471 if ( feedback )
472 {
473 feedback->setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
474 }
475
476 }
477
478 // flush the buffer to be sure that all features are written
479 if ( !writer->flushBuffer() )
480 {
482 {
483 *errorMessage += '\n' + writer->errorMessage();
484 }
485 }
486 const int errors = writer->errorCount();
487
488 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
489 {
491 {
492 *errorMessage += '\n' + writer->errorMessage();
493 }
494 }
495
496 delete writer;
497
498 if ( errorMessage )
499 {
500 if ( errors > 0 )
501 {
502 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
503 }
504 else
505 {
506 errorMessage->clear();
507 }
508 }
509
510 if ( canceled )
512 else if ( errors > 0 )
514
516}
517
518
519//
520// QgsVectorLayerExporterTask
521//
522
523QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
524 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
525 , mLayer( layer )
526 , mOwnsLayer( ownsLayer )
527 , mDestUri( uri )
528 , mDestProviderKey( providerKey )
529 , mDestCrs( destinationCrs )
530 , mOptions( options )
531 , mOwnedFeedback( new QgsFeedback() )
532{
533 if ( mLayer )
534 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
535}
536
537QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
538{
539 std::unique_ptr< QgsVectorLayerExporterTask > newTask( new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
540 newTask->mOwnsLayer = true;
541 return newTask.release();
542}
543
545{
546 mOwnedFeedback->cancel();
548}
549
551{
552 if ( !mLayer )
553 return false;
554
555 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
556
557
559 mLayer.data(), mDestUri, mDestProviderKey, mDestCrs, false, &mErrorMessage,
560 mOptions, mOwnedFeedback.get() );
561
562 return mError == Qgis::VectorExportResult::Success;
563}
564
566{
567 // QgsMapLayer has QTimer member, which must not be destroyed from another thread
568 if ( mOwnsLayer )
569 delete mLayer;
570
571 if ( result )
572 emit exportComplete();
573 else
574 emit errorOccurred( mError, mErrorMessage );
575}
VectorExportResult
Vector layer export result codes.
Definition qgis.h:806
@ 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:412
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:201
@ 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:82
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)
Adds a message to the log instance (and creates it if necessary).
A registry / canonical manager of data providers.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags flags=QgsDataProvider::ReadFlags())
Creates a new instance of a provider.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
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)
Creates new empty vector layer.
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.
@ CreateSpatialIndex
Allows creation of spatial index.
@ AddFeatures
Allows adding features.
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.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
virtual Q_INVOKABLE QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
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:39
#define QgsDebugError(str)
Definition qgslogger.h:38
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.