28#include "moc_qgsvectorlayerexporter.cpp"
36#include <QProgressDialog>
44 QMap<int, int> *oldToNewAttrIdx,
45 QString *errorMessage,
46 const QMap<QString, QVariant> *options
51 const QString &providerKey,
56 const QMap<QString, QVariant> &options,
59 , mAttributeCount( -1 )
64 QMap<QString, QVariant> modifiedOptions( options );
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 ) )
76 QStringList modifiedLayerOptions;
77 if ( options.contains( QStringLiteral(
"layerOptions" ) ) )
79 const QStringList layerOptions = options.value( QStringLiteral(
"layerOptions" ) ).toStringList();
80 for (
const QString &layerOption : layerOptions )
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 )
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 )
94 mCreateSpatialIndex =
false;
98 modifiedLayerOptions << layerOption;
102 modifiedLayerOptions << QStringLiteral(
"SPATIAL_INDEX=FALSE" );
103 modifiedOptions[ QStringLiteral(
"layerOptions" ) ] = modifiedLayerOptions;
110 mError = pReg->
createEmptyLayer( providerKey, uri, fields, geometryType,
crs, overwrite, mOldToNewAttrIdx,
111 errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr );
115 mErrorMessage = errMsg;
119 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
120 for (
const int idx : constMOldToNewAttrIdx )
122 if ( idx > mAttributeCount )
123 mAttributeCount = idx;
130 QString uriUpdated( uri );
132 if ( providerKey == QLatin1String(
"ogr" ) )
135 if ( options.contains( QStringLiteral(
"layerName" ) ) )
136 layerName = options.value( QStringLiteral(
"layerName" ) ).toString();
137 if ( !layerName.isEmpty() )
139 uriUpdated += QLatin1String(
"|layername=" );
140 uriUpdated += layerName;
146 if ( providerKey == QLatin1String(
"oracle" ) )
156 mErrorMessage = QObject::tr(
"Loading of layer failed" );
158 delete vectorProvider;
170 const QString fidName = options.value( QStringLiteral(
"FID" ), QStringLiteral(
"FID" ) ).toString();
174 mOldToNewAttrIdx.remove( fidIdx );
178 mProvider = vectorProvider;
186 if ( mCreateSpatialIndex )
188 createSpatialIndex();
201 return mErrorMessage;
211 QgsFeatureList::iterator fIt = features.begin();
213 for ( ; fIt != features.end(); ++fIt )
230 for (
int i = 0; i < attrs.count(); ++i )
234 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
238 QgsDebugMsgLevel( QStringLiteral(
"moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
242 mFeatureBuffer.append( newFeat );
245 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
255 return mErrorMessage;
260 mFeatureBufferMemoryUsage = 0;
261 if ( mFeatureBuffer.count() <= 0 )
266 const QStringList errors = mProvider->
errors();
269 mErrorMessage = QObject::tr(
"Creation error for features from #%1 to #%2. Provider errors were: \n%3" )
270 .arg( mFeatureBuffer.first().id() )
271 .arg( mFeatureBuffer.last().id() )
272 .arg( errors.join( QLatin1Char(
'\n' ) ) );
275 mErrorCount += mFeatureBuffer.count();
277 mFeatureBuffer.clear();
282 mFeatureBuffer.clear();
286bool QgsVectorLayerExporter::createSpatialIndex()
288 mCreateSpatialIndex =
false;
301 const QString &providerKey,
304 QString *errorMessage,
305 const QMap<QString, QVariant> &options,
310 bool shallTransform =
false;
319 shallTransform =
true;
324 outputCRS = layer->
crs();
328 bool overwrite =
false;
329 bool forceSinglePartGeom =
false;
330 QMap<QString, QVariant> providerOptions = options;
331 if ( !options.isEmpty() )
333 overwrite = providerOptions.take( QStringLiteral(
"overwrite" ) ).toBool();
334 forceSinglePartGeom = providerOptions.take( QStringLiteral(
"forceSinglePartGeometryType" ) ).toBool();
341 bool convertGeometryToSinglePart =
false;
345 convertGeometryToSinglePart =
true;
384 shallTransform =
false;
394 bool canceled =
false;
404 *
errorMessage +=
'\n' + QObject::tr(
"Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
418 if ( shallTransform )
433 const QString msg = QObject::tr(
"Failed to transform feature with ID '%1'. Writing stopped. (Exception: %2)" )
434 .arg( fet.
id() ).arg( e.
what() );
449 const QgsGeometryCollection *
c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
450 if ( (
c &&
c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
453 const QString msg = QObject::tr(
"Failed to transform a feature with ID '%1' to single part. Writing stopped." )
474 feedback->
setProgress( 100.0 *
static_cast< double >( n ) / approxTotal );
489 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
503 *
errorMessage +=
'\n' + QObject::tr(
"Only %1 of %2 features written." ).arg( n - errors ).arg( n );
513 else if ( errors > 0 )
525 :
QgsTask( tr(
"Exporting %1" ).arg( layer->name() ),
QgsTask::CanCancel )
527 , mOwnsLayer( ownsLayer )
529 , mDestProviderKey( providerKey )
530 , mDestCrs( destinationCrs )
531 , mOptions( options )
540 std::unique_ptr< QgsVectorLayerExporterTask > newTask(
new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
541 newTask->mOwnsLayer =
true;
542 return newTask.release();
547 mOwnedFeedback->cancel();
560 mLayer.data(), mDestUri, mDestProviderKey, mDestCrs,
false, &mErrorMessage,
561 mOptions, mOwnedFeedback.get() );
@ AddFeatures
Allows adding features.
@ CreateSpatialIndex
Allows creation of spatial index.
VectorExportResult
Vector layer export result codes.
@ Success
No errors were encountered.
@ ErrorInvalidLayer
Could not access newly created destination layer.
@ ErrorFeatureWriteFailed
An error occurred while writing a feature to the destination.
@ UserCanceled
User canceled the export.
@ ErrorProjectingFeatures
An error occurred while reprojecting features to destination CRS.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QFlags< VectorDataProviderAttributeEditCapability > VectorDataProviderAttributeEditCapabilities
Attribute editing capabilities which may be supported by vector data providers.
WkbType
The WKB type describes the number of dimensions a geometry has.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Custom exception class for Coordinate Reference System related exceptions.
virtual bool isValid() const =0
Returns true if this is a valid layer.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QFlags< SinkFlag > SinkFlags
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
void setProgress(double progress)
Sets the current progress for the feedback object.
Container of fields for a vector layer.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsCoordinateReferenceSystem crs
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.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, Qgis::WkbType wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options)
Creates new empty vector layer.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions(), Qgis::DataProviderReadFlags flags=Qgis::DataProviderReadFlags())
Creates a new instance of a provider.
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.
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.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
virtual Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the provider's supported attribute editing capabilities.
QgsTask task which performs a QgsVectorLayerExporter layer export operation as a background task.
void finished(bool result) override
If the task is managed by a QgsTaskManager, this will be called after the task has finished (whether ...
QgsVectorLayerExporterTask(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), bool ownsLayer=false)
Constructor for QgsVectorLayerExporterTask.
void exportComplete()
Emitted when exporting the layer is successfully completed.
void errorOccurred(Qgis::VectorExportResult error, const QString &errorMessage)
Emitted when an error occurs which prevented the layer being exported (or if the task is canceled).
void cancel() override
Notifies the task that it should terminate.
static QgsVectorLayerExporterTask * withLayerOwnership(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >())
Creates a new QgsVectorLayerExporterTask which has ownership over a source layer.
bool run() override
Performs the task's operation.
A convenience class for exporting vector layers to a destination data provider.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
static Qgis::VectorExportResult exportLayer(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destCRS, bool onlySelected=false, QString *errorMessage=nullptr, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeedback *feedback=nullptr)
Writes the contents of vector layer to a different datasource.
int errorCount() const
Returns the number of error messages encountered during the export.
QString errorMessage() const
Returns any error message encountered during the export.
Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the attribute capabilities of the exporter.
~QgsVectorLayerExporter() override
Finalizes the export and closes the new created layer.
QString lastError() const override
Returns the most recent error encountered by the sink, e.g.
bool flushBuffer() override
Flushes any internal buffer which may exist in the sink, causing any buffered features to be added to...
Qgis::VectorExportResult errorCode() const
Returns any encountered error code, or false if no error was encountered.
QgsVectorLayerExporter(const QString &uri, const QString &provider, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &crs, bool overwrite=false, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Constructor for QgsVectorLayerExporter.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
Represents a vector layer which manages a vector based data sets.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
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.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
static bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
static QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
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
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
Qgis::VectorExportResult createEmptyLayer_t(const QString &uri, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &destCRS, bool overwrite, QMap< int, int > *oldToNewAttrIdx, QString *errorMessage, const QMap< QString, QVariant > *options)
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.