32 #include <QProgressDialog> 34 #define FEATURE_BUFFER_SIZE 200 42 QMap<int, int> *oldToNewAttrIdx,
43 QString *errorMessage,
44 const QMap<QString, QVariant> *options
49 const QString &providerKey,
54 const QMap<QString, QVariant> &options,
55 QgsFeatureSink::SinkFlags sinkFlags )
57 , mAttributeCount( -1 )
68 mErrorMessage = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
76 mErrorMessage = QObject::tr(
"Provider %1 has no %2 method" ).arg( providerKey, QStringLiteral(
"createEmptyLayer" ) );
82 mError = pCreateEmpty( uri, fields, geometryType, crs, overwrite, &mOldToNewAttrIdx, &errMsg, !options.isEmpty() ? &options : nullptr );
85 mErrorMessage = errMsg;
89 Q_FOREACH (
int idx, mOldToNewAttrIdx )
91 if ( idx > mAttributeCount )
92 mAttributeCount = idx;
97 QgsDebugMsg( QStringLiteral(
"Created empty layer" ) );
99 QString uriUpdated( uri );
101 if ( providerKey == QLatin1String(
"ogr" ) )
104 if ( options.contains( QStringLiteral(
"layerName" ) ) )
105 layerName = options.value( QStringLiteral(
"layerName" ) ).toString();
106 if ( !layerName.isEmpty() )
108 uriUpdated += QLatin1String(
"|layername=" );
109 uriUpdated += layerName;
118 mErrorMessage = QObject::tr(
"Loading of layer failed" );
120 delete vectorProvider;
130 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String(
".gpkg" ), Qt::CaseInsensitive ) )
132 QString fidName = options.value( QStringLiteral(
"FID" ), QStringLiteral(
"FID" ) ).toString();
136 mOldToNewAttrIdx.remove( fidIdx );
140 mProvider = vectorProvider;
157 return mErrorMessage;
162 QgsFeatureList::iterator fIt = features.begin();
164 for ( ; fIt != features.end(); ++fIt )
181 for (
int i = 0; i < attrs.count(); ++i )
185 int dstIdx = mOldToNewAttrIdx.value( i, -1 );
189 QgsDebugMsgLevel( QStringLiteral(
"moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
193 mFeatureBuffer.append( newFeat );
205 if ( mFeatureBuffer.count() <= 0 )
210 QStringList errors = mProvider->
errors();
213 mErrorMessage = QObject::tr(
"Creation error for features from #%1 to #%2. Provider errors was: \n%3" )
214 .arg( mFeatureBuffer.first().id() )
215 .arg( mFeatureBuffer.last().id() )
216 .arg( errors.join( QStringLiteral(
"\n" ) ) );
219 mErrorCount += mFeatureBuffer.count();
221 mFeatureBuffer.clear();
226 mFeatureBuffer.clear();
230 bool QgsVectorLayerExporter::createSpatialIndex()
245 const QString &providerKey,
249 const QMap<QString, QVariant> &options,
254 bool shallTransform =
false;
263 shallTransform =
true;
268 outputCRS = layer->
crs();
272 bool overwrite =
false;
273 bool forceSinglePartGeom =
false;
274 QMap<QString, QVariant> providerOptions = options;
275 if ( !options.isEmpty() )
277 overwrite = providerOptions.take( QStringLiteral(
"overwrite" ) ).toBool();
278 forceSinglePartGeom = providerOptions.take( QStringLiteral(
"forceSinglePartGeometryType" ) ).toBool();
285 if ( layer->
providerType() == QLatin1String(
"ogr" ) && layer->
storageType() == QLatin1String(
"ESRI Shapefile" ) )
288 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
290 fields[fldIdx].setName( fields.
at( fldIdx ).
name().toLower() );
293 if ( !forceSinglePartGeom )
337 errorMessage->clear();
360 shallTransform =
false;
367 *errorMessage = QObject::tr(
"Feature write errors:" );
370 bool canceled =
false;
380 *errorMessage +=
'\n' + QObject::tr(
"Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
389 *errorMessage +=
'\n' + QObject::tr(
"Stopping after %1 errors" ).arg( writer->
errorCount() );
394 if ( shallTransform )
409 QString msg = QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
410 .arg( fet.
id() ).arg( e.
what() );
413 *errorMessage +=
'\n' + msg;
429 feedback->
setProgress( 100.0 * static_cast< double >( n ) / approxTotal );
444 if ( !writer->createSpatialIndex() )
458 *errorMessage +=
'\n' + QObject::tr(
"Only %1 of %2 features written." ).arg( n - errors ).arg( n );
462 errorMessage->clear();
468 else if ( errors > 0 )
480 :
QgsTask( tr(
"Exporting %1" ).arg( layer->name() ),
QgsTask::CanCancel )
482 , mOwnsLayer( ownsLayer )
484 , mDestProviderKey( providerKey )
485 , mDestCrs( destinationCrs )
486 , mOptions( options )
495 std::unique_ptr< QgsVectorLayerExporterTask > newTask(
new QgsVectorLayerExporterTask( layer, uri, providerKey, destinationCrs, options ) );
496 newTask->mOwnsLayer =
true;
497 return newTask.release();
502 mOwnedFeedback->cancel();
515 mLayer.data(), mDestUri, mDestProviderKey, mDestCrs,
false, &mErrorMessage,
516 mOptions, mOwnedFeedback.get() );
Wrapper for iterator of features from vector data provider or vector layer.
Could not access newly created destination layer.
bool isCanceled() const
Tells whether the operation has been canceled already.
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's current progress.
QgsVectorLayerExporter(const QString &uri, const QString &provider, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, bool overwrite=false, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeatureSink::SinkFlags sinkFlags=nullptr)
Constructor for QgsVectorLayerExporter.
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.
int errorCount() const
Returns the number of error messages encountered during the export.
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
QList< QgsFeature > QgsFeatureList
#define FEATURE_BUFFER_SIZE
static ExportError exportLayer(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destCRS, bool onlySelected=false, QString *errorMessage=nullptr, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeedback *feedback=nullptr)
Writes the contents of vector layer to a different datasource.
void setProgress(double progress)
Sets the current progress for the feedback object.
void setDependentLayers(const QList< QgsMapLayer * > &dependentLayers)
Sets a list of layers on which the task depends.
#define Q_NOWARN_DEPRECATED_PUSH
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
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. ...
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
User canceled the export.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Returns the components (e.g.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
const QgsCoordinateReferenceSystem & crs
Could not find a matching provider key.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions())
Creates a new instance of a provider.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Allows creation of spatial index.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
Type
The WKB type describes the number of dimensions a geometry has.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString errorMessage() const
Returns any error message encountered during the export.
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.
#define QgsDebugMsgLevel(str, level)
virtual bool isValid() const =0
Returns true if this is a valid layer.
QgsVectorLayerExporterTask(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), bool ownsLayer=false)
Constructor for QgsVectorLayerExporterTask.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
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.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
An error occurred while writing a feature to the destination.
long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
void clearErrors()
Clear recorded errors.
int count() const
Returns number of items.
ExportError errorCode() const
Returns any encountered error code, or false if no error was encountered.
QgsTask task which performs a QgsVectorLayerExporter layer export operation as a background task...
An error occurred while reprojecting features to destination CRS.
const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QLibrary * createProviderLibrary(const QString &providerKey) const
Returns a new QLibrary for the specified providerKey.
void errorOccurred(int error, const QString &errorMessage)
Emitted when an error occurs which prevented the layer being exported (or if the task is canceled)...
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
A convenience class for exporting vector layers to a destination data provider.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a single feature to the sink.
A registry / canonical manager of data providers.
virtual void cancel()
Notifies the task that it should terminate.
#define Q_NOWARN_DEPRECATED_POP
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString providerType() const
Returns the provider type for this layer.
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.
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
This class represents a coordinate reference system (CRS).
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
QStringList errors() const
Gets recorded errors.
void cancel() override
Notifies the task that it should terminate.
No errors were encountered.
bool run() override
Performs the task's operation.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
Custom exception class for Coordinate Reference System related exceptions.
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.
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 ...
Provider does not support creation of empty layers.
QgsCoordinateReferenceSystem crs
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.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.