QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri, const QString &providerKey, const QgsFields& fields, QGis::WkbType geometryType, const QgsCoordinateReferenceSystem* crs, bool overwrite, const QMap<QString, QVariant> *options, QProgressDialog *progress ) : mErrorCount( 0 ) , mAttributeCount( -1 ) , mProgress( progress ) { mProvider = nullptr; QgsProviderRegistry * pReg = QgsProviderRegistry::instance(); QLibrary *myLib = pReg->providerLibrary( providerKey ); if ( !myLib ) { mError = ErrInvalidProvider; mErrorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey ); return; } createEmptyLayer_t * pCreateEmpty = reinterpret_cast< createEmptyLayer_t * >( cast_to_fptr( myLib->resolve( "createEmptyLayer" ) ) ); if ( !pCreateEmpty ) { delete myLib; mError = ErrProviderUnsupportedFeature; mErrorMessage = QObject::tr( "Provider %1 has no %2 method" ).arg( providerKey, "createEmptyLayer" ); return; } delete myLib; // create an empty layer QString errMsg; mError = pCreateEmpty( uri, fields, geometryType, crs, overwrite, &mOldToNewAttrIdx, &errMsg, options ); if ( hasError() ) { mErrorMessage = errMsg; return; } Q_FOREACH ( int idx, mOldToNewAttrIdx.values() ) { if ( idx > mAttributeCount ) mAttributeCount = idx; } mAttributeCount++; QgsDebugMsg( "Created empty layer" ); QgsVectorDataProvider *vectorProvider = dynamic_cast< QgsVectorDataProvider* >( pReg->provider( providerKey, uri ) ); if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 ) { mError = ErrInvalidLayer; mErrorMessage = QObject::tr( "Loading of layer failed" ); if ( vectorProvider ) delete vectorProvider; return; } mProvider = vectorProvider; mError = NoError; }
QgsVectorLayerExporter::QgsVectorLayerExporter( const QString &uri, const QString &providerKey, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, bool overwrite, const QMap<QString, QVariant> &options, QgsFeatureSink::SinkFlags sinkFlags ) : mErrorCount( 0 ) , mAttributeCount( -1 ) { mProvider = nullptr; QgsProviderRegistry *pReg = QgsProviderRegistry::instance(); std::unique_ptr< QLibrary > myLib( pReg->createProviderLibrary( providerKey ) ); if ( !myLib ) { mError = ErrInvalidProvider; mErrorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey ); return; } createEmptyLayer_t *pCreateEmpty = reinterpret_cast< createEmptyLayer_t * >( cast_to_fptr( myLib->resolve( "createEmptyLayer" ) ) ); if ( !pCreateEmpty ) { mError = ErrProviderUnsupportedFeature; mErrorMessage = QObject::tr( "Provider %1 has no %2 method" ).arg( providerKey, QStringLiteral( "createEmptyLayer" ) ); return; } // create an empty layer QString errMsg; mError = pCreateEmpty( uri, fields, geometryType, crs, overwrite, &mOldToNewAttrIdx, &errMsg, !options.isEmpty() ? &options : nullptr ); if ( errorCode() ) { mErrorMessage = errMsg; return; } Q_FOREACH ( int idx, mOldToNewAttrIdx ) { if ( idx > mAttributeCount ) mAttributeCount = idx; } mAttributeCount++; QgsDebugMsg( QStringLiteral( "Created empty layer" ) ); QString uriUpdated( uri ); // HACK sorry... if ( providerKey == QLatin1String( "ogr" ) ) { QString layerName; if ( options.contains( QStringLiteral( "layerName" ) ) ) layerName = options.value( QStringLiteral( "layerName" ) ).toString(); if ( !layerName.isEmpty() ) { uriUpdated += QLatin1String( "|layername=" ); uriUpdated += layerName; } } QgsDataProvider::ProviderOptions providerOptions; QgsVectorDataProvider *vectorProvider = dynamic_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) ); if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 ) { mError = ErrInvalidLayer; mErrorMessage = QObject::tr( "Loading of layer failed" ); delete vectorProvider; return; } // If the result is a geopackage layer and there is already a field name FID requested which // might contain duplicates, make sure to generate a new field with a unique name instead // that will be filled by ogr with unique values. // HACK sorry const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString(); if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) ) { QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString(); int fidIdx = vectorProvider->fields().lookupField( fidName ); if ( fidIdx != -1 ) { mOldToNewAttrIdx.remove( fidIdx ); } } mProvider = vectorProvider; mError = NoError; }