QGIS API Documentation  3.20.0-Odense (decaadbb31)
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"
25 #include "qgsgeometrycollection.h"
27 #include "qgsvectorlayerexporter.h"
28 #include "qgsproviderregistry.h"
29 #include "qgsdatasourceuri.h"
30 #include "qgsexception.h"
31 #include "qgsvectordataprovider.h"
32 #include "qgsvectorlayer.h"
33 #include "qgsabstractgeometry.h"
34 
35 #include <QProgressDialog>
36 
38  const QString &uri,
39  const QgsFields &fields,
40  QgsWkbTypes::Type 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  QgsWkbTypes::Type 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 != QgsWkbTypes::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  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 ( 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  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  QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
170  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  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  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  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 
280 bool 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  QgsWkbTypes::Type 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  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 
372  QgsFeatureRequest req;
373  if ( wkbType == QgsWkbTypes::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  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 %1 errors" ).arg( 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  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  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  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 
528 QgsVectorLayerExporterTask::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 
542 QgsVectorLayerExporterTask *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();
552  QgsTask::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:316
A vector of attributes.
Definition: qgsattributes.h:58
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 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:237
QgsAttributes attributes
Definition: qgsfeature.h:65
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:210
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
Definition: qgsfeature.cpp:349
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:205
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:145
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:344
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:124
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
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 providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:76
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:832
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:736
#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.