QGIS API Documentation  3.23.0-Master (dd0cd13a00)
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 #include "qgscoordinatetransform.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 
281 bool 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 
373  QgsFeatureRequest req;
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 %1 errors" ).arg( 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 
529 QgsVectorLayerExporterTask::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 
543 QgsVectorLayerExporterTask *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();
553  QgsTask::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:361
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 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:255
QgsAttributes attributes
Definition: qgsfeature.h:65
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:228
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
Definition: qgsfeature.cpp:367
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:223
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:163
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:125
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: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:882
#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.