QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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,
56 QgsFeatureSink::SinkFlags sinkFlags )
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
112 if ( errorCode() != Qgis::VectorExportResult::Success )
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 {
154 mError = Qgis::VectorExportResult::ErrorInvalidLayer;
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;
178 mError = Qgis::VectorExportResult::Success;
179}
180
182{
183 flushBuffer();
184
185 if ( mCreateSpatialIndex )
186 {
187 createSpatialIndex();
188 }
189
190 delete mProvider;
191}
192
194{
195 return mError;
196}
197
199{
200 return mErrorMessage;
201}
202
204{
205 QgsFeatureList::iterator fIt = features.begin();
206 bool result = true;
207 for ( ; fIt != features.end(); ++fIt )
208 {
209 result = result && addFeature( *fIt, flags );
210 }
211 return result;
212}
213
215{
216 const QgsAttributes attrs = feat.attributes();
217
218 QgsFeature newFeat;
219 if ( feat.hasGeometry() )
220 newFeat.setGeometry( feat.geometry() );
221
222 newFeat.initAttributes( mAttributeCount );
223
224 for ( int i = 0; i < attrs.count(); ++i )
225 {
226 // add only mapped attributes (un-mapped ones will not be present in the
227 // destination layer)
228 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
229 if ( dstIdx < 0 )
230 continue;
231
232 QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
233 newFeat.setAttribute( dstIdx, attrs.at( i ) );
234 }
235
236 mFeatureBuffer.append( newFeat );
237 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
238
239 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
240 {
241 return flushBuffer();
242 }
243
244 return true;
245}
246
248{
249 return mErrorMessage;
250}
251
253{
254 mFeatureBufferMemoryUsage = 0;
255 if ( mFeatureBuffer.count() <= 0 )
256 return true;
257
258 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
259 {
260 const QStringList errors = mProvider->errors();
261 mProvider->clearErrors();
262
263 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
264 .arg( mFeatureBuffer.first().id() )
265 .arg( mFeatureBuffer.last().id() )
266 .arg( errors.join( QLatin1Char( '\n' ) ) );
267
268 mError = Qgis::VectorExportResult::ErrorFeatureWriteFailed;
269 mErrorCount += mFeatureBuffer.count();
270
271 mFeatureBuffer.clear();
272 QgsDebugMsg( mErrorMessage );
273 return false;
274 }
275
276 mFeatureBuffer.clear();
277 return true;
278}
279
280bool QgsVectorLayerExporter::createSpatialIndex()
281{
282 mCreateSpatialIndex = false;
283 if ( mProvider && ( mProvider->capabilities() & QgsVectorDataProvider::CreateSpatialIndex ) != 0 )
284 {
285 return mProvider->createSpatialIndex();
286 }
287 else
288 {
289 return true;
290 }
291}
292
294 const QString &uri,
295 const QString &providerKey,
296 const QgsCoordinateReferenceSystem &destCRS,
297 bool onlySelected,
298 QString *errorMessage,
299 const QMap<QString, QVariant> &options,
300 QgsFeedback *feedback )
301{
304 bool shallTransform = false;
305
306 if ( !layer )
307 return Qgis::VectorExportResult::ErrorInvalidLayer;
308
309 if ( destCRS.isValid() )
310 {
311 // This means we should transform
312 outputCRS = destCRS;
313 shallTransform = true;
314 }
315 else
316 {
317 // This means we shouldn't transform, use source CRS as output (if defined)
318 outputCRS = layer->crs();
319 }
320
321
322 bool overwrite = false;
323 bool forceSinglePartGeom = false;
324 QMap<QString, QVariant> providerOptions = options;
325 if ( !options.isEmpty() )
326 {
327 overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
328 forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
329 }
330
331 QgsFields fields = layer->fields();
332
333 Qgis::WkbType wkbType = layer->wkbType();
334
335 // Special handling for Shapefiles
336 if ( layer->providerType() == QLatin1String( "ogr" ) && layer->storageType() == QLatin1String( "ESRI Shapefile" ) )
337 {
338 // convert field names to lowercase
339 for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
340 {
341 fields.rename( fldIdx, fields.at( fldIdx ).name().toLower() );
342 }
343 }
344
345 bool convertGeometryToSinglePart = false;
346 if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
347 {
348 wkbType = QgsWkbTypes::singleType( wkbType );
349 convertGeometryToSinglePart = true;
350 }
351
352 QgsVectorLayerExporter *writer =
353 new QgsVectorLayerExporter( uri, providerKey, fields, wkbType, outputCRS, overwrite, providerOptions );
354
355 // check whether file creation was successful
356 const Qgis::VectorExportResult err = writer->errorCode();
357 if ( err != Qgis::VectorExportResult::Success )
358 {
359 if ( errorMessage )
360 *errorMessage = writer->errorMessage();
361 delete writer;
362 return err;
363 }
364
365 if ( errorMessage )
366 {
367 errorMessage->clear();
368 }
369
370 QgsFeature fet;
371
373 if ( wkbType == Qgis::WkbType::NoGeometry )
375 if ( onlySelected )
376 req.setFilterFids( layer->selectedFeatureIds() );
377
378 QgsFeatureIterator fit = layer->getFeatures( req );
379
380 // Create our transform
381 if ( destCRS.isValid() )
382 {
383 ct = QgsCoordinateTransform( layer->crs(), destCRS, layer->transformContext() );
384 }
385
386 // Check for failure
387 if ( !ct.isValid() )
388 shallTransform = false;
389
390 long long n = 0;
391 const long long approxTotal = onlySelected ? layer->selectedFeatureCount() : layer->featureCount();
392
393 if ( errorMessage )
394 {
395 *errorMessage = QObject::tr( "Feature write errors:" );
396 }
397
398 bool canceled = false;
399
400 // write all features
401 while ( fit.nextFeature( fet ) )
402 {
403 if ( feedback && feedback->isCanceled() )
404 {
405 canceled = true;
406 if ( errorMessage )
407 {
408 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
409 }
410 break;
411 }
412
413 if ( writer->errorCount() > 1000 )
414 {
415 if ( errorMessage )
416 {
417 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
418 }
419 break;
420 }
421
422 if ( shallTransform )
423 {
424 try
425 {
426 if ( fet.hasGeometry() )
427 {
428 QgsGeometry g = fet.geometry();
429 g.transform( ct );
430 fet.setGeometry( g );
431 }
432 }
433 catch ( QgsCsException &e )
434 {
435 delete writer;
436
437 const QString msg = QObject::tr( "Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
438 .arg( fet.id() ).arg( e.what() );
439 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
440 if ( errorMessage )
441 *errorMessage += '\n' + msg;
442
443 return Qgis::VectorExportResult::ErrorProjectingFeatures;
444 }
445 }
446
447 // Handles conversion to single-part
448 if ( convertGeometryToSinglePart && fet.geometry().isMultipart() )
449 {
450 QgsGeometry singlePartGeometry { fet.geometry() };
451 // We want a failure if the geometry cannot be converted to single-part without data loss!
452 // check if there are more than one part
453 const QgsGeometryCollection *c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
454 if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
455 {
456 delete writer;
457 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
458 .arg( fet.id() );
459 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
460 if ( errorMessage )
461 *errorMessage += '\n' + msg;
462 return Qgis::VectorExportResult::ErrorFeatureWriteFailed;
463 }
464 fet.setGeometry( singlePartGeometry );
465 }
466
467 if ( !writer->addFeature( fet ) )
468 {
469 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
470 {
471 *errorMessage += '\n' + writer->errorMessage();
472 }
473 }
474 n++;
475
476 if ( feedback )
477 {
478 feedback->setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
479 }
480
481 }
482
483 // flush the buffer to be sure that all features are written
484 if ( !writer->flushBuffer() )
485 {
486 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
487 {
488 *errorMessage += '\n' + writer->errorMessage();
489 }
490 }
491 const int errors = writer->errorCount();
492
493 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
494 {
495 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
496 {
497 *errorMessage += '\n' + writer->errorMessage();
498 }
499 }
500
501 delete writer;
502
503 if ( errorMessage )
504 {
505 if ( errors > 0 )
506 {
507 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
508 }
509 else
510 {
511 errorMessage->clear();
512 }
513 }
514
515 if ( canceled )
516 return Qgis::VectorExportResult::UserCanceled;
517 else if ( errors > 0 )
518 return Qgis::VectorExportResult::ErrorFeatureWriteFailed;
519
520 return Qgis::VectorExportResult::Success;
521}
522
523
524//
525// QgsVectorLayerExporterTask
526//
527
528QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
529 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
530 , mLayer( layer )
531 , mOwnsLayer( ownsLayer )
532 , mDestUri( uri )
533 , mDestProviderKey( providerKey )
534 , mDestCrs( destinationCrs )
535 , mOptions( options )
536 , mOwnedFeedback( new QgsFeedback() )
537{
538 if ( mLayer )
539 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
540}
541
542QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
543{
544 std::unique_ptr< QgsVectorLayerExporterTask > newTask( new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
545 newTask->mOwnsLayer = true;
546 return newTask.release();
547}
548
550{
551 mOwnedFeedback->cancel();
553}
554
556{
557 if ( !mLayer )
558 return false;
559
560 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
561
562
564 mLayer.data(), mDestUri, mDestProviderKey, mDestCrs, false, &mErrorMessage,
565 mOptions, mOwnedFeedback.get() );
566
567 return mError == Qgis::VectorExportResult::Success;
568}
569
571{
572 // QgsMapLayer has QTimer member, which must not be destroyed from another thread
573 if ( mOwnsLayer )
574 delete mLayer;
575
576 if ( result )
577 emit exportComplete();
578 else
579 emit errorOccurred( mError, mErrorMessage );
580}
VectorExportResult
Vector layer export result codes.
Definition: qgis.h:620
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:155
@ NoGeometry
No geometry.
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:61
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:359
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.
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.
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.
~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.
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.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
static bool isMultiType(Qgis::WkbType type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:759
static Qgis::WkbType singleType(Qgis::WkbType type) SIP_HOLDGIL
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:54
static QString displayString(Qgis::WkbType type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
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:920
#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, 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.