QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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 "qgsdatasourceuri.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 QgsWkbTypes::Type 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 QgsWkbTypes::Type geometryType,
55 bool overwrite,
56 const QMap<QString, QVariant> &options,
57 QgsFeatureSink::SinkFlags sinkFlags )
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 != QgsWkbTypes::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 mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx,
111 errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr );
112
113 if ( errorCode() != Qgis::VectorExportResult::Success )
114 {
115 mErrorMessage = errMsg;
116 return;
117 }
118
119 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
120 for ( const int idx : constMOldToNewAttrIdx )
121 {
122 if ( idx > mAttributeCount )
123 mAttributeCount = idx;
124 }
125
126 mAttributeCount++;
127
128 QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 );
129
130 QString uriUpdated( uri );
131 // HACK sorry...
132 if ( providerKey == QLatin1String( "ogr" ) )
133 {
134 QString layerName;
135 if ( options.contains( QStringLiteral( "layerName" ) ) )
136 layerName = options.value( QStringLiteral( "layerName" ) ).toString();
137 if ( !layerName.isEmpty() )
138 {
139 uriUpdated += QLatin1String( "|layername=" );
140 uriUpdated += layerName;
141 }
142 }
143
144 // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need
145 // to force it in the uri
146 if ( providerKey == QLatin1String( "oracle" ) )
147 {
148 uriUpdated += QStringLiteral( " type=%1" ).arg( QgsWkbTypes::displayString( geometryType ) );
149 }
150
151 const QgsDataProvider::ProviderOptions providerOptions;
152 QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
153 if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 )
154 {
155 mError = Qgis::VectorExportResult::ErrorInvalidLayer;
156 mErrorMessage = QObject::tr( "Loading of layer failed" );
157
158 delete vectorProvider;
159 return;
160 }
161
162 // If the result is a geopackage layer and there is already a field name FID requested which
163 // might contain duplicates, make sure to generate a new field with a unique name instead
164 // that will be filled by ogr with unique values.
165
166 // HACK sorry
167 const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
168 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
169 {
170 const QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
171 const int fidIdx = fields.lookupField( fidName );
172 if ( fidIdx != -1 )
173 {
174 mOldToNewAttrIdx.remove( fidIdx );
175 }
176 }
177
178 mProvider = vectorProvider;
179 mError = Qgis::VectorExportResult::Success;
180}
181
183{
184 flushBuffer();
185
186 if ( mCreateSpatialIndex )
187 {
188 createSpatialIndex();
189 }
190
191 delete mProvider;
192}
193
195{
196 return mError;
197}
198
200{
201 return mErrorMessage;
202}
203
205{
206 QgsFeatureList::iterator fIt = features.begin();
207 bool result = true;
208 for ( ; fIt != features.end(); ++fIt )
209 {
210 result = result && addFeature( *fIt, flags );
211 }
212 return result;
213}
214
216{
217 const QgsAttributes attrs = feat.attributes();
218
219 QgsFeature newFeat;
220 if ( feat.hasGeometry() )
221 newFeat.setGeometry( feat.geometry() );
222
223 newFeat.initAttributes( mAttributeCount );
224
225 for ( int i = 0; i < attrs.count(); ++i )
226 {
227 // add only mapped attributes (un-mapped ones will not be present in the
228 // destination layer)
229 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
230 if ( dstIdx < 0 )
231 continue;
232
233 QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
234 newFeat.setAttribute( dstIdx, attrs.at( i ) );
235 }
236
237 mFeatureBuffer.append( newFeat );
238 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
239
240 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
241 {
242 return flushBuffer();
243 }
244
245 return true;
246}
247
249{
250 return mErrorMessage;
251}
252
254{
255 mFeatureBufferMemoryUsage = 0;
256 if ( mFeatureBuffer.count() <= 0 )
257 return true;
258
259 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
260 {
261 const QStringList errors = mProvider->errors();
262 mProvider->clearErrors();
263
264 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
265 .arg( mFeatureBuffer.first().id() )
266 .arg( mFeatureBuffer.last().id() )
267 .arg( errors.join( QLatin1Char( '\n' ) ) );
268
269 mError = Qgis::VectorExportResult::ErrorFeatureWriteFailed;
270 mErrorCount += mFeatureBuffer.count();
271
272 mFeatureBuffer.clear();
273 QgsDebugMsg( mErrorMessage );
274 return false;
275 }
276
277 mFeatureBuffer.clear();
278 return true;
279}
280
281bool QgsVectorLayerExporter::createSpatialIndex()
282{
283 mCreateSpatialIndex = false;
284 if ( mProvider && ( mProvider->capabilities() & QgsVectorDataProvider::CreateSpatialIndex ) != 0 )
285 {
286 return mProvider->createSpatialIndex();
287 }
288 else
289 {
290 return true;
291 }
292}
293
295 const QString &uri,
296 const QString &providerKey,
297 const QgsCoordinateReferenceSystem &destCRS,
298 bool onlySelected,
299 QString *errorMessage,
300 const QMap<QString, QVariant> &options,
301 QgsFeedback *feedback )
302{
305 bool shallTransform = false;
306
307 if ( !layer )
308 return Qgis::VectorExportResult::ErrorInvalidLayer;
309
310 if ( destCRS.isValid() )
311 {
312 // This means we should transform
313 outputCRS = destCRS;
314 shallTransform = true;
315 }
316 else
317 {
318 // This means we shouldn't transform, use source CRS as output (if defined)
319 outputCRS = layer->crs();
320 }
321
322
323 bool overwrite = false;
324 bool forceSinglePartGeom = false;
325 QMap<QString, QVariant> providerOptions = options;
326 if ( !options.isEmpty() )
327 {
328 overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
329 forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
330 }
331
332 QgsFields fields = layer->fields();
333
334 QgsWkbTypes::Type wkbType = layer->wkbType();
335
336 // Special handling for Shapefiles
337 if ( layer->providerType() == QLatin1String( "ogr" ) && layer->storageType() == QLatin1String( "ESRI Shapefile" ) )
338 {
339 // convert field names to lowercase
340 for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
341 {
342 fields.rename( fldIdx, fields.at( fldIdx ).name().toLower() );
343 }
344 }
345
346 bool convertGeometryToSinglePart = false;
347 if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
348 {
349 wkbType = QgsWkbTypes::singleType( wkbType );
350 convertGeometryToSinglePart = true;
351 }
352
353 QgsVectorLayerExporter *writer =
354 new QgsVectorLayerExporter( uri, providerKey, fields, wkbType, outputCRS, overwrite, providerOptions );
355
356 // check whether file creation was successful
357 const Qgis::VectorExportResult err = writer->errorCode();
358 if ( err != Qgis::VectorExportResult::Success )
359 {
360 if ( errorMessage )
361 *errorMessage = writer->errorMessage();
362 delete writer;
363 return err;
364 }
365
366 if ( errorMessage )
367 {
368 errorMessage->clear();
369 }
370
371 QgsFeature fet;
372
374 if ( wkbType == QgsWkbTypes::NoGeometry )
376 if ( onlySelected )
377 req.setFilterFids( layer->selectedFeatureIds() );
378
379 QgsFeatureIterator fit = layer->getFeatures( req );
380
381 // Create our transform
382 if ( destCRS.isValid() )
383 {
384 ct = QgsCoordinateTransform( layer->crs(), destCRS, layer->transformContext() );
385 }
386
387 // Check for failure
388 if ( !ct.isValid() )
389 shallTransform = false;
390
391 long long n = 0;
392 const long long approxTotal = onlySelected ? layer->selectedFeatureCount() : layer->featureCount();
393
394 if ( errorMessage )
395 {
396 *errorMessage = QObject::tr( "Feature write errors:" );
397 }
398
399 bool canceled = false;
400
401 // write all features
402 while ( fit.nextFeature( fet ) )
403 {
404 if ( feedback && feedback->isCanceled() )
405 {
406 canceled = true;
407 if ( errorMessage )
408 {
409 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
410 }
411 break;
412 }
413
414 if ( writer->errorCount() > 1000 )
415 {
416 if ( errorMessage )
417 {
418 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
419 }
420 break;
421 }
422
423 if ( shallTransform )
424 {
425 try
426 {
427 if ( fet.hasGeometry() )
428 {
429 QgsGeometry g = fet.geometry();
430 g.transform( ct );
431 fet.setGeometry( g );
432 }
433 }
434 catch ( QgsCsException &e )
435 {
436 delete writer;
437
438 const QString msg = QObject::tr( "Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
439 .arg( fet.id() ).arg( e.what() );
440 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
441 if ( errorMessage )
442 *errorMessage += '\n' + msg;
443
444 return Qgis::VectorExportResult::ErrorProjectingFeatures;
445 }
446 }
447
448 // Handles conversion to single-part
449 if ( convertGeometryToSinglePart && fet.geometry().isMultipart() )
450 {
451 QgsGeometry singlePartGeometry { fet.geometry() };
452 // We want a failure if the geometry cannot be converted to single-part without data loss!
453 // check if there are more than one part
454 const QgsGeometryCollection *c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
455 if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
456 {
457 delete writer;
458 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
459 .arg( fet.id() );
460 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
461 if ( errorMessage )
462 *errorMessage += '\n' + msg;
463 return Qgis::VectorExportResult::ErrorFeatureWriteFailed;
464 }
465 fet.setGeometry( singlePartGeometry );
466 }
467
468 if ( !writer->addFeature( fet ) )
469 {
470 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
471 {
472 *errorMessage += '\n' + writer->errorMessage();
473 }
474 }
475 n++;
476
477 if ( feedback )
478 {
479 feedback->setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
480 }
481
482 }
483
484 // flush the buffer to be sure that all features are written
485 if ( !writer->flushBuffer() )
486 {
487 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
488 {
489 *errorMessage += '\n' + writer->errorMessage();
490 }
491 }
492 const int errors = writer->errorCount();
493
494 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
495 {
496 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
497 {
498 *errorMessage += '\n' + writer->errorMessage();
499 }
500 }
501
502 delete writer;
503
504 if ( errorMessage )
505 {
506 if ( errors > 0 )
507 {
508 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
509 }
510 else
511 {
512 errorMessage->clear();
513 }
514 }
515
516 if ( canceled )
517 return Qgis::VectorExportResult::UserCanceled;
518 else if ( errors > 0 )
519 return Qgis::VectorExportResult::ErrorFeatureWriteFailed;
520
521 return Qgis::VectorExportResult::Success;
522}
523
524
525//
526// QgsVectorLayerExporterTask
527//
528
529QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
530 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
531 , mLayer( layer )
532 , mOwnsLayer( ownsLayer )
533 , mDestUri( uri )
534 , mDestProviderKey( providerKey )
535 , mDestCrs( destinationCrs )
536 , mOptions( options )
537 , mOwnedFeedback( new QgsFeedback() )
538{
539 if ( mLayer )
540 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
541}
542
543QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
544{
545 std::unique_ptr< QgsVectorLayerExporterTask > newTask( new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
546 newTask->mOwnsLayer = true;
547 return newTask.release();
548}
549
551{
552 mOwnedFeedback->cancel();
554}
555
557{
558 if ( !mLayer )
559 return false;
560
561 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
562
563
565 mLayer.data(), mDestUri, mDestProviderKey, mDestCrs, false, &mErrorMessage,
566 mOptions, mOwnedFeedback.get() );
567
568 return mError == Qgis::VectorExportResult::Success;
569}
570
572{
573 // QgsMapLayer has QTimer member, which must not be destroyed from another thread
574 if ( mOwnsLayer )
575 delete mLayer;
576
577 if ( result )
578 emit exportComplete();
579 else
580 emit errorOccurred( mError, mErrorMessage );
581}
VectorExportResult
Vector layer export result codes.
Definition: qgis.h:450
A vector of attributes.
Definition: qgsattributes.h:59
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.
Definition: qgsexception.h:66
virtual bool isValid() const =0
Returns true if this is a valid layer.
QString what() const
Definition: qgsexception.h:48
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
Definition: qgsfeature.cpp:265
QgsAttributes attributes
Definition: qgsfeature.h:65
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:238
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
Definition: qgsfeature.cpp:385
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:233
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
QString name
Definition: qgsfield.h:60
Container of fields for a vector layer.
Definition: qgsfields.h:45
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:349
bool rename(int fieldIdx, const QString &name)
Renames a name of field.
Definition: qgsfields.cpp:72
Geometry collection.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
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.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, QgsWkbTypes::Type wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options)
Creates new empty vector layer.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
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.
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.
QgsVectorLayerExporter(const QString &uri, const QString &provider, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, bool overwrite=false, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Constructor for QgsVectorLayerExporter.
QString errorMessage() const
Returns any error message encountered during the export.
~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.
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.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
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.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
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.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:862
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Type singleType(Type type) SIP_HOLDGIL
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:157
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
Definition: qgsfeature.h:922
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
Qgis::VectorExportResult createEmptyLayer_t(const QString &uri, const QgsFields &fields, QgsWkbTypes::Type 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.