QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 #include "qgsfields.h"
19 #include "qgsfeature.h"
20 #include "qgsfeatureiterator.h"
21 #include "qgsgeometry.h"
22 #include "qgslogger.h"
23 #include "qgsmessagelog.h"
25 #include "qgsvectorlayerexporter.h"
26 #include "qgsproviderregistry.h"
27 #include "qgsdatasourceuri.h"
28 #include "qgsexception.h"
29 #include "qgsvectordataprovider.h"
30 #include "qgsvectorlayer.h"
31 
32 #include <QProgressDialog>
33 
34 #define FEATURE_BUFFER_SIZE 200
35 
37  const QString &uri,
38  const QgsFields &fields,
39  QgsWkbTypes::Type geometryType,
40  const QgsCoordinateReferenceSystem &destCRS,
41  bool overwrite,
42  QMap<int, int> *oldToNewAttrIdx,
43  QString *errorMessage,
44  const QMap<QString, QVariant> *options
45 );
46 
47 
49  const QString &providerKey,
50  const QgsFields &fields,
51  QgsWkbTypes::Type geometryType,
53  bool overwrite,
54  const QMap<QString, QVariant> &options,
55  QgsFeatureSink::SinkFlags sinkFlags )
56  : mErrorCount( 0 )
57  , mAttributeCount( -1 )
58 
59 {
60  mProvider = nullptr;
61 
63 
64  std::unique_ptr< QLibrary > myLib( pReg->createProviderLibrary( providerKey ) );
65  if ( !myLib )
66  {
67  mError = ErrInvalidProvider;
68  mErrorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
69  return;
70  }
71 
72  createEmptyLayer_t *pCreateEmpty = reinterpret_cast< createEmptyLayer_t * >( cast_to_fptr( myLib->resolve( "createEmptyLayer" ) ) );
73  if ( !pCreateEmpty )
74  {
76  mErrorMessage = QObject::tr( "Provider %1 has no %2 method" ).arg( providerKey, QStringLiteral( "createEmptyLayer" ) );
77  return;
78  }
79 
80  // create an empty layer
81  QString errMsg;
82  mError = pCreateEmpty( uri, fields, geometryType, crs, overwrite, &mOldToNewAttrIdx, &errMsg, !options.isEmpty() ? &options : nullptr );
83  if ( errorCode() )
84  {
85  mErrorMessage = errMsg;
86  return;
87  }
88 
89  const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
90  for ( int idx : constMOldToNewAttrIdx )
91  {
92  if ( idx > mAttributeCount )
93  mAttributeCount = idx;
94  }
95 
96  mAttributeCount++;
97 
98  QgsDebugMsg( QStringLiteral( "Created empty layer" ) );
99 
100  QString uriUpdated( uri );
101  // HACK sorry...
102  if ( providerKey == QLatin1String( "ogr" ) )
103  {
104  QString layerName;
105  if ( options.contains( QStringLiteral( "layerName" ) ) )
106  layerName = options.value( QStringLiteral( "layerName" ) ).toString();
107  if ( !layerName.isEmpty() )
108  {
109  uriUpdated += QLatin1String( "|layername=" );
110  uriUpdated += layerName;
111  }
112  }
113 
114  QgsDataProvider::ProviderOptions providerOptions;
115  QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
116  if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 )
117  {
118  mError = ErrInvalidLayer;
119  mErrorMessage = QObject::tr( "Loading of layer failed" );
120 
121  delete vectorProvider;
122  return;
123  }
124 
125  // If the result is a geopackage layer and there is already a field name FID requested which
126  // might contain duplicates, make sure to generate a new field with a unique name instead
127  // that will be filled by ogr with unique values.
128 
129  // HACK sorry
130  const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
131  if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
132  {
133  QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
134  int fidIdx = vectorProvider->fields().lookupField( fidName );
135  if ( fidIdx != -1 )
136  {
137  mOldToNewAttrIdx.remove( fidIdx );
138  }
139  }
140 
141  mProvider = vectorProvider;
142  mError = NoError;
143 }
144 
146 {
147  flushBuffer();
148  delete mProvider;
149 }
150 
152 {
153  return mError;
154 }
155 
157 {
158  return mErrorMessage;
159 }
160 
162 {
163  QgsFeatureList::iterator fIt = features.begin();
164  bool result = true;
165  for ( ; fIt != features.end(); ++fIt )
166  {
167  result = result && addFeature( *fIt, flags );
168  }
169  return result;
170 }
171 
173 {
174  QgsAttributes attrs = feat.attributes();
175 
176  QgsFeature newFeat;
177  if ( feat.hasGeometry() )
178  newFeat.setGeometry( feat.geometry() );
179 
180  newFeat.initAttributes( mAttributeCount );
181 
182  for ( int i = 0; i < attrs.count(); ++i )
183  {
184  // add only mapped attributes (un-mapped ones will not be present in the
185  // destination layer)
186  int dstIdx = mOldToNewAttrIdx.value( i, -1 );
187  if ( dstIdx < 0 )
188  continue;
189 
190  QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
191  newFeat.setAttribute( dstIdx, attrs.at( i ) );
192  }
193 
194  mFeatureBuffer.append( newFeat );
195 
196  if ( mFeatureBuffer.count() >= FEATURE_BUFFER_SIZE )
197  {
198  return flushBuffer();
199  }
200 
201  return true;
202 }
203 
205 {
206  if ( mFeatureBuffer.count() <= 0 )
207  return true;
208 
209  if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
210  {
211  QStringList errors = mProvider->errors();
212  mProvider->clearErrors();
213 
214  mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
215  .arg( mFeatureBuffer.first().id() )
216  .arg( mFeatureBuffer.last().id() )
217  .arg( errors.join( QStringLiteral( "\n" ) ) );
218 
219  mError = ErrFeatureWriteFailed;
220  mErrorCount += mFeatureBuffer.count();
221 
222  mFeatureBuffer.clear();
223  QgsDebugMsg( mErrorMessage );
224  return false;
225  }
226 
227  mFeatureBuffer.clear();
228  return true;
229 }
230 
231 bool QgsVectorLayerExporter::createSpatialIndex()
232 {
233  if ( mProvider && ( mProvider->capabilities() & QgsVectorDataProvider::CreateSpatialIndex ) != 0 )
234  {
235  return mProvider->createSpatialIndex();
236  }
237  else
238  {
239  return true;
240  }
241 }
242 
245  const QString &uri,
246  const QString &providerKey,
247  const QgsCoordinateReferenceSystem &destCRS,
248  bool onlySelected,
249  QString *errorMessage,
250  const QMap<QString, QVariant> &options,
251  QgsFeedback *feedback )
252 {
255  bool shallTransform = false;
256 
257  if ( !layer )
258  return ErrInvalidLayer;
259 
260  if ( destCRS.isValid() )
261  {
262  // This means we should transform
263  outputCRS = destCRS;
264  shallTransform = true;
265  }
266  else
267  {
268  // This means we shouldn't transform, use source CRS as output (if defined)
269  outputCRS = layer->crs();
270  }
271 
272 
273  bool overwrite = false;
274  bool forceSinglePartGeom = false;
275  QMap<QString, QVariant> providerOptions = options;
276  if ( !options.isEmpty() )
277  {
278  overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
279  forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
280  }
281 
282  QgsFields fields = layer->fields();
283  QgsWkbTypes::Type wkbType = layer->wkbType();
284 
285  // Special handling for Shapefiles
286  if ( layer->providerType() == QLatin1String( "ogr" ) && layer->storageType() == QLatin1String( "ESRI Shapefile" ) )
287  {
288  // convert field names to lowercase
289  for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
290  {
291  fields[fldIdx].setName( fields.at( fldIdx ).name().toLower() );
292  }
293 
294  if ( !forceSinglePartGeom )
295  {
296  // convert wkbtype to multipart (see #5547)
297  switch ( wkbType )
298  {
299  case QgsWkbTypes::Point:
300  wkbType = QgsWkbTypes::MultiPoint;
301  break;
304  break;
306  wkbType = QgsWkbTypes::MultiPolygon;
307  break;
309  wkbType = QgsWkbTypes::MultiPoint25D;
310  break;
313  break;
316  break;
317  default:
318  break;
319  }
320  }
321  }
322 
323  QgsVectorLayerExporter *writer =
324  new QgsVectorLayerExporter( uri, providerKey, fields, wkbType, outputCRS, overwrite, providerOptions );
325 
326  // check whether file creation was successful
327  ExportError err = writer->errorCode();
328  if ( err != NoError )
329  {
330  if ( errorMessage )
331  *errorMessage = writer->errorMessage();
332  delete writer;
333  return err;
334  }
335 
336  if ( errorMessage )
337  {
338  errorMessage->clear();
339  }
340 
341  QgsFeature fet;
342 
343  QgsFeatureRequest req;
344  if ( wkbType == QgsWkbTypes::NoGeometry )
346  if ( onlySelected )
347  req.setFilterFids( layer->selectedFeatureIds() );
348 
349  QgsFeatureIterator fit = layer->getFeatures( req );
350 
351  // Create our transform
352  if ( destCRS.isValid() )
353  {
354  ct = QgsCoordinateTransform( layer->crs(), destCRS, layer->transformContext() );
355  }
356 
357  // Check for failure
358  if ( !ct.isValid() )
359  shallTransform = false;
360 
361  long n = 0;
362  long approxTotal = onlySelected ? layer->selectedFeatureCount() : layer->featureCount();
363 
364  if ( errorMessage )
365  {
366  *errorMessage = QObject::tr( "Feature write errors:" );
367  }
368 
369  bool canceled = false;
370 
371  // write all features
372  while ( fit.nextFeature( fet ) )
373  {
374  if ( feedback && feedback->isCanceled() )
375  {
376  canceled = true;
377  if ( errorMessage )
378  {
379  *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
380  }
381  break;
382  }
383 
384  if ( writer->errorCount() > 1000 )
385  {
386  if ( errorMessage )
387  {
388  *errorMessage += '\n' + QObject::tr( "Stopping after %1 errors" ).arg( writer->errorCount() );
389  }
390  break;
391  }
392 
393  if ( shallTransform )
394  {
395  try
396  {
397  if ( fet.hasGeometry() )
398  {
399  QgsGeometry g = fet.geometry();
400  g.transform( ct );
401  fet.setGeometry( g );
402  }
403  }
404  catch ( QgsCsException &e )
405  {
406  delete writer;
407 
408  QString msg = QObject::tr( "Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
409  .arg( fet.id() ).arg( e.what() );
410  QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
411  if ( errorMessage )
412  *errorMessage += '\n' + msg;
413 
414  return ErrProjection;
415  }
416  }
417  if ( !writer->addFeature( fet ) )
418  {
419  if ( writer->errorCode() && errorMessage )
420  {
421  *errorMessage += '\n' + writer->errorMessage();
422  }
423  }
424  n++;
425 
426  if ( feedback )
427  {
428  feedback->setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
429  }
430 
431  }
432 
433  // flush the buffer to be sure that all features are written
434  if ( !writer->flushBuffer() )
435  {
436  if ( writer->errorCode() && errorMessage )
437  {
438  *errorMessage += '\n' + writer->errorMessage();
439  }
440  }
441  int errors = writer->errorCount();
442 
443  if ( !writer->createSpatialIndex() )
444  {
445  if ( writer->errorCode() && errorMessage )
446  {
447  *errorMessage += '\n' + writer->errorMessage();
448  }
449  }
450 
451  delete writer;
452 
453  if ( errorMessage )
454  {
455  if ( errors > 0 )
456  {
457  *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
458  }
459  else
460  {
461  errorMessage->clear();
462  }
463  }
464 
465  if ( canceled )
466  return ErrUserCanceled;
467  else if ( errors > 0 )
468  return ErrFeatureWriteFailed;
469 
470  return NoError;
471 }
472 
473 
474 //
475 // QgsVectorLayerExporterTask
476 //
477 
478 QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
479  : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
480  , mLayer( layer )
481  , mOwnsLayer( ownsLayer )
482  , mDestUri( uri )
483  , mDestProviderKey( providerKey )
484  , mDestCrs( destinationCrs )
485  , mOptions( options )
486  , mOwnedFeedback( new QgsFeedback() )
487 {
488  if ( mLayer )
489  setDependentLayers( QList< QgsMapLayer * >() << mLayer );
490 }
491 
492 QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
493 {
494  std::unique_ptr< QgsVectorLayerExporterTask > newTask( new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
495  newTask->mOwnsLayer = true;
496  return newTask.release();
497 }
498 
500 {
501  mOwnedFeedback->cancel();
502  QgsTask::cancel();
503 }
504 
506 {
507  if ( !mLayer )
508  return false;
509 
510  connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
511 
512 
514  mLayer.data(), mDestUri, mDestProviderKey, mDestCrs, false, &mErrorMessage,
515  mOptions, mOwnedFeedback.get() );
516 
517  return mError == QgsVectorLayerExporter::NoError;
518 }
519 
521 {
522  // QgsMapLayer has QTimer member, which must not be destroyed from another thread
523  if ( mOwnsLayer )
524  delete mLayer;
525 
526  if ( result )
527  emit exportComplete();
528  else
529  emit errorOccurred( mError, mErrorMessage );
530 }
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
QgsFeatureId id
Definition: qgsfeature.h:64
Wrapper for iterator of features from vector data provider or vector layer.
Could not access newly created destination layer.
bool flushBuffer() override
Flushes any internal buffer which may exist in the sink, causing any buffered features to be added to...
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
void setProgress(double progress)
Sets the task&#39;s current progress.
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=nullptr)
Constructor for QgsVectorLayerExporter.
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
QString name
Definition: qgsfield.h:58
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:571
#define FEATURE_BUFFER_SIZE
static ExportError 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 selectedFeatureCount() const
Returns the number of features that are selected in this layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
QString errorMessage() const
Returns any error message encountered during the export.
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. ...
void setDependentLayers(const QList< QgsMapLayer *> &dependentLayers)
Sets a list of layers on which the task depends.
Container of fields for a vector layer.
Definition: qgsfields.h:42
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:211
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
const QgsCoordinateReferenceSystem & crs
Could not find a matching provider key.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
ExportError errorCode() const
Returns any encountered error code, or false if no error was encountered.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
QString what() const
Definition: qgsexception.h:48
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions())
Creates a new instance of a provider.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:44
Allows creation of spatial index.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QLibrary * createProviderLibrary(const QString &providerKey) const
Returns a new QLibrary for the specified providerKey.
virtual bool isValid() const =0
Returns true if this is a valid layer.
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.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:202
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Abstract base class for long running background tasks.
QStringList errors() const
Gets recorded errors.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
An error occurred while writing a feature to the destination.
void clearErrors()
Clear recorded errors.
QgsTask task which performs a QgsVectorLayerExporter layer export operation as a background task...
An error occurred while reprojecting features to destination CRS.
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
#define cast_to_fptr(f)
Definition: qgis.h:158
void errorOccurred(int error, const QString &errorMessage)
Emitted when an error occurs which prevented the layer being exported (or if the task is canceled)...
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
A convenience class for exporting vector layers to a destination data provider.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a single feature to the sink.
A registry / canonical manager of data providers.
virtual void cancel()
Notifies the task that it should terminate.
Setting options for creating vector data providers.
~QgsVectorLayerExporter() override
Finalizes the export and closes the new created layer.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
int errorCount() const
Returns the number of error messages encountered during the export.
This class represents a coordinate reference system (CRS).
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
Class for doing transforms between two map coordinate systems.
void cancel() override
Notifies the task that it should terminate.
No errors were encountered.
bool run() override
Performs the task&#39;s operation.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsGeometry geometry
Definition: qgsfeature.h:67
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
A vector of attributes.
Definition: qgsattributes.h:57
Represents a vector layer which manages a vector based data sets.
void finished(bool result) override
If the task is managed by a QgsTaskManager, this will be called after the task has finished (whether ...
QgsAttributes attributes
Definition: qgsfeature.h:65
Provider does not support creation of empty layers.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:85
QgsVectorLayerExporter::ExportError 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)
void exportComplete()
Emitted when exporting the layer is successfully completed.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.