QGIS API Documentation  3.17.0-Master (8af46bc54f)
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  if ( errorCode() )
112  {
113  mErrorMessage = errMsg;
114  return;
115  }
116 
117  const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
118  for ( int idx : constMOldToNewAttrIdx )
119  {
120  if ( idx > mAttributeCount )
121  mAttributeCount = idx;
122  }
123 
124  mAttributeCount++;
125 
126  QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 );
127 
128  QString uriUpdated( uri );
129  // HACK sorry...
130  if ( providerKey == QLatin1String( "ogr" ) )
131  {
132  QString layerName;
133  if ( options.contains( QStringLiteral( "layerName" ) ) )
134  layerName = options.value( QStringLiteral( "layerName" ) ).toString();
135  if ( !layerName.isEmpty() )
136  {
137  uriUpdated += QLatin1String( "|layername=" );
138  uriUpdated += layerName;
139  }
140  }
141 
142  QgsDataProvider::ProviderOptions providerOptions;
143  QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
144  if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 )
145  {
146  mError = ErrInvalidLayer;
147  mErrorMessage = QObject::tr( "Loading of layer failed" );
148 
149  delete vectorProvider;
150  return;
151  }
152 
153  // If the result is a geopackage layer and there is already a field name FID requested which
154  // might contain duplicates, make sure to generate a new field with a unique name instead
155  // that will be filled by ogr with unique values.
156 
157  // HACK sorry
158  const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
159  if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
160  {
161  QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
162  int fidIdx = fields.lookupField( fidName );
163  if ( fidIdx != -1 )
164  {
165  mOldToNewAttrIdx.remove( fidIdx );
166  }
167  }
168 
169  mProvider = vectorProvider;
170  mError = NoError;
171 }
172 
174 {
175  flushBuffer();
176 
177  if ( mCreateSpatialIndex )
178  {
179  createSpatialIndex();
180  }
181 
182  delete mProvider;
183 }
184 
186 {
187  return mError;
188 }
189 
191 {
192  return mErrorMessage;
193 }
194 
196 {
197  QgsFeatureList::iterator fIt = features.begin();
198  bool result = true;
199  for ( ; fIt != features.end(); ++fIt )
200  {
201  result = result && addFeature( *fIt, flags );
202  }
203  return result;
204 }
205 
207 {
208  QgsAttributes attrs = feat.attributes();
209 
210  QgsFeature newFeat;
211  if ( feat.hasGeometry() )
212  newFeat.setGeometry( feat.geometry() );
213 
214  newFeat.initAttributes( mAttributeCount );
215 
216  for ( int i = 0; i < attrs.count(); ++i )
217  {
218  // add only mapped attributes (un-mapped ones will not be present in the
219  // destination layer)
220  int dstIdx = mOldToNewAttrIdx.value( i, -1 );
221  if ( dstIdx < 0 )
222  continue;
223 
224  QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
225  newFeat.setAttribute( dstIdx, attrs.at( i ) );
226  }
227 
228  mFeatureBuffer.append( newFeat );
229  mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
230 
231  if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
232  {
233  return flushBuffer();
234  }
235 
236  return true;
237 }
238 
240 {
241  return mErrorMessage;
242 }
243 
245 {
246  mFeatureBufferMemoryUsage = 0;
247  if ( mFeatureBuffer.count() <= 0 )
248  return true;
249 
250  if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
251  {
252  QStringList errors = mProvider->errors();
253  mProvider->clearErrors();
254 
255  mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
256  .arg( mFeatureBuffer.first().id() )
257  .arg( mFeatureBuffer.last().id() )
258  .arg( errors.join( QLatin1Char( '\n' ) ) );
259 
260  mError = ErrFeatureWriteFailed;
261  mErrorCount += mFeatureBuffer.count();
262 
263  mFeatureBuffer.clear();
264  QgsDebugMsg( mErrorMessage );
265  return false;
266  }
267 
268  mFeatureBuffer.clear();
269  return true;
270 }
271 
272 bool QgsVectorLayerExporter::createSpatialIndex()
273 {
274  mCreateSpatialIndex = false;
275  if ( mProvider && ( mProvider->capabilities() & QgsVectorDataProvider::CreateSpatialIndex ) != 0 )
276  {
277  return mProvider->createSpatialIndex();
278  }
279  else
280  {
281  return true;
282  }
283 }
284 
287  const QString &uri,
288  const QString &providerKey,
289  const QgsCoordinateReferenceSystem &destCRS,
290  bool onlySelected,
291  QString *errorMessage,
292  const QMap<QString, QVariant> &options,
293  QgsFeedback *feedback )
294 {
297  bool shallTransform = false;
298 
299  if ( !layer )
300  return ErrInvalidLayer;
301 
302  if ( destCRS.isValid() )
303  {
304  // This means we should transform
305  outputCRS = destCRS;
306  shallTransform = true;
307  }
308  else
309  {
310  // This means we shouldn't transform, use source CRS as output (if defined)
311  outputCRS = layer->crs();
312  }
313 
314 
315  bool overwrite = false;
316  bool forceSinglePartGeom = false;
317  QMap<QString, QVariant> providerOptions = options;
318  if ( !options.isEmpty() )
319  {
320  overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
321  forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
322  }
323 
324  QgsFields fields = layer->fields();
325 
326  QgsWkbTypes::Type wkbType = layer->wkbType();
327 
328  // Special handling for Shapefiles
329  if ( layer->providerType() == QLatin1String( "ogr" ) && layer->storageType() == QLatin1String( "ESRI Shapefile" ) )
330  {
331  // convert field names to lowercase
332  for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
333  {
334  fields.rename( fldIdx, fields.at( fldIdx ).name().toLower() );
335  }
336  }
337 
338  bool convertGeometryToSinglePart = false;
339  if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
340  {
341  wkbType = QgsWkbTypes::singleType( wkbType );
342  convertGeometryToSinglePart = true;
343  }
344 
345  QgsVectorLayerExporter *writer =
346  new QgsVectorLayerExporter( uri, providerKey, fields, wkbType, outputCRS, overwrite, providerOptions );
347 
348  // check whether file creation was successful
349  ExportError err = writer->errorCode();
350  if ( err != NoError )
351  {
352  if ( errorMessage )
353  *errorMessage = writer->errorMessage();
354  delete writer;
355  return err;
356  }
357 
358  if ( errorMessage )
359  {
360  errorMessage->clear();
361  }
362 
363  QgsFeature fet;
364 
365  QgsFeatureRequest req;
366  if ( wkbType == QgsWkbTypes::NoGeometry )
368  if ( onlySelected )
369  req.setFilterFids( layer->selectedFeatureIds() );
370 
371  QgsFeatureIterator fit = layer->getFeatures( req );
372 
373  // Create our transform
374  if ( destCRS.isValid() )
375  {
376  ct = QgsCoordinateTransform( layer->crs(), destCRS, layer->transformContext() );
377  }
378 
379  // Check for failure
380  if ( !ct.isValid() )
381  shallTransform = false;
382 
383  long n = 0;
384  long approxTotal = onlySelected ? layer->selectedFeatureCount() : layer->featureCount();
385 
386  if ( errorMessage )
387  {
388  *errorMessage = QObject::tr( "Feature write errors:" );
389  }
390 
391  bool canceled = false;
392 
393  // write all features
394  while ( fit.nextFeature( fet ) )
395  {
396  if ( feedback && feedback->isCanceled() )
397  {
398  canceled = true;
399  if ( errorMessage )
400  {
401  *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
402  }
403  break;
404  }
405 
406  if ( writer->errorCount() > 1000 )
407  {
408  if ( errorMessage )
409  {
410  *errorMessage += '\n' + QObject::tr( "Stopping after %1 errors" ).arg( writer->errorCount() );
411  }
412  break;
413  }
414 
415  if ( shallTransform )
416  {
417  try
418  {
419  if ( fet.hasGeometry() )
420  {
421  QgsGeometry g = fet.geometry();
422  g.transform( ct );
423  fet.setGeometry( g );
424  }
425  }
426  catch ( QgsCsException &e )
427  {
428  delete writer;
429 
430  QString msg = QObject::tr( "Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
431  .arg( fet.id() ).arg( e.what() );
432  QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
433  if ( errorMessage )
434  *errorMessage += '\n' + msg;
435 
436  return ErrProjection;
437  }
438  }
439 
440  // Handles conversion to single-part
441  if ( convertGeometryToSinglePart && fet.geometry().isMultipart() )
442  {
443  QgsGeometry singlePartGeometry { fet.geometry() };
444  // We want a failure if the geometry cannot be converted to single-part without data loss!
445  // check if there are more than one part
446  const QgsGeometryCollection *c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
447  if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
448  {
449  delete writer;
450  QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
451  .arg( fet.id() );
452  QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
453  if ( errorMessage )
454  *errorMessage += '\n' + msg;
455  return ErrFeatureWriteFailed;
456  }
457  fet.setGeometry( singlePartGeometry );
458  }
459 
460  if ( !writer->addFeature( fet ) )
461  {
462  if ( writer->errorCode() && errorMessage )
463  {
464  *errorMessage += '\n' + writer->errorMessage();
465  }
466  }
467  n++;
468 
469  if ( feedback )
470  {
471  feedback->setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
472  }
473 
474  }
475 
476  // flush the buffer to be sure that all features are written
477  if ( !writer->flushBuffer() )
478  {
479  if ( writer->errorCode() && errorMessage )
480  {
481  *errorMessage += '\n' + writer->errorMessage();
482  }
483  }
484  int errors = writer->errorCount();
485 
486  if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
487  {
488  if ( writer->errorCode() && errorMessage )
489  {
490  *errorMessage += '\n' + writer->errorMessage();
491  }
492  }
493 
494  delete writer;
495 
496  if ( errorMessage )
497  {
498  if ( errors > 0 )
499  {
500  *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
501  }
502  else
503  {
504  errorMessage->clear();
505  }
506  }
507 
508  if ( canceled )
509  return ErrUserCanceled;
510  else if ( errors > 0 )
511  return ErrFeatureWriteFailed;
512 
513  return NoError;
514 }
515 
516 
517 //
518 // QgsVectorLayerExporterTask
519 //
520 
521 QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
522  : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
523  , mLayer( layer )
524  , mOwnsLayer( ownsLayer )
525  , mDestUri( uri )
526  , mDestProviderKey( providerKey )
527  , mDestCrs( destinationCrs )
528  , mOptions( options )
529  , mOwnedFeedback( new QgsFeedback() )
530 {
531  if ( mLayer )
532  setDependentLayers( QList< QgsMapLayer * >() << mLayer );
533 }
534 
535 QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
536 {
537  std::unique_ptr< QgsVectorLayerExporterTask > newTask( new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
538  newTask->mOwnsLayer = true;
539  return newTask.release();
540 }
541 
543 {
544  mOwnedFeedback->cancel();
545  QgsTask::cancel();
546 }
547 
549 {
550  if ( !mLayer )
551  return false;
552 
553  connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
554 
555 
557  mLayer.data(), mDestUri, mDestProviderKey, mDestCrs, false, &mErrorMessage,
558  mOptions, mOwnedFeedback.get() );
559 
560  return mError == QgsVectorLayerExporter::NoError;
561 }
562 
564 {
565  // QgsMapLayer has QTimer member, which must not be destroyed from another thread
566  if ( mOwnsLayer )
567  delete mLayer;
568 
569  if ( result )
570  emit exportComplete();
571  else
572  emit errorOccurred( mError, mErrorMessage );
573 }
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:344
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.
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
QString name
Definition: qgsfield.h:59
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.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:583
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:62
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:44
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:123
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:213
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
QString lastError() const override
Returns the most recent error encountered by the sink, 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
bool rename(int fieldIdx, const QString &name)
Renames a name of field.
Definition: qgsfields.cpp:72
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:199
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsVectorLayerExporter::ExportError 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.
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...
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
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
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:43
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
Allows creation of spatial index.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
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.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
Geometry collection.
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.
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:204
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)...
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
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...
void errorOccurred(int error, const QString &errorMessage)
Emitted when an error occurs which prevented the layer being exported (or if the task is canceled)...
A convenience class for exporting vector layers to a destination data provider.
A registry / canonical manager of data providers.
virtual void cancel()
Notifies the task that it should terminate.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
int partCount() const override
Returns count of parts contained in the geometry.
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:53
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.
This class represents a coordinate reference system (CRS).
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:139
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.
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.
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:832
QgsGeometry geometry
Definition: qgsfeature.h:67
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
static Type singleType(Type type) SIP_HOLDGIL
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:157
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
Definition: qgsfeature.cpp:311
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
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:90
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.