27 QString QgsPackageAlgorithm::name()
const 29 return QStringLiteral(
"package" );
32 QString QgsPackageAlgorithm::displayName()
const 34 return QObject::tr(
"Package layers" );
37 QStringList QgsPackageAlgorithm::tags()
const 39 return QObject::tr(
"geopackage,collect,merge,combine,styles" ).split(
',' );
42 QString QgsPackageAlgorithm::group()
const 44 return QObject::tr(
"Database" );
47 QString QgsPackageAlgorithm::groupId()
const 49 return QStringLiteral(
"database" );
52 void QgsPackageAlgorithm::initAlgorithm(
const QVariantMap & )
57 addParameter(
new QgsProcessingParameterBoolean( QStringLiteral(
"SAVE_STYLES" ), QObject::tr(
"Save layer styles into GeoPackage" ),
true ) );
61 QString QgsPackageAlgorithm::shortHelpString()
const 63 return QObject::tr(
"This algorithm collects a number of existing layers and packages them together into a single GeoPackage database." );
66 QgsPackageAlgorithm *QgsPackageAlgorithm::createInstance()
const 68 return new QgsPackageAlgorithm();
73 const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral(
"LAYERS" ), context );
76 mLayers.emplace_back( layer->clone() );
79 if ( mLayers.empty() )
80 feedback->
reportError( QObject::tr(
"No layers selected, geopackage will be empty" ),
false );
87 const bool overwrite = parameterAsBoolean( parameters, QStringLiteral(
"OVERWRITE" ), context );
88 const bool saveStyles = parameterAsBoolean( parameters, QStringLiteral(
"SAVE_STYLES" ), context );
89 QString packagePath = parameterAsString( parameters, QStringLiteral(
"OUTPUT" ), context );
90 if ( packagePath.isEmpty() )
94 if ( overwrite && QFile::exists( packagePath ) )
96 feedback->
pushInfo( QObject::tr(
"Removing existing file '%1'" ).arg( packagePath ) );
97 if ( !QFile( packagePath ).
remove() )
103 OGRSFDriverH hGpkgDriver = OGRGetDriverByName(
"GPKG" );
111 if ( !QFile::exists( packagePath ) )
115 throw QgsProcessingException( QObject::tr(
"Creation of database %1 failed (OGR error: %2)" ).arg( packagePath, QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
121 throw QgsProcessingException( QObject::tr(
"Opening database %1 failed (OGR error: %2)" ).arg( packagePath, QString::fromUtf8( CPLGetLastErrorMsg() ) ) );
125 bool errored =
false;
129 QStringList outputLayers;
131 for (
const auto &layer : mLayers )
142 feedback->
pushDebugInfo( QObject::tr(
"Error retrieving map layer." ) );
147 feedback->
pushInfo( QObject::tr(
"Packaging layer %1/%2: %3" ).arg( i ).arg( mLayers.size() ).arg( layer ? layer->name() : QString() ) );
149 switch ( layer->type() )
153 if ( !packageVectorLayer( qobject_cast< QgsVectorLayer * >( layer.get() ), packagePath,
154 context, &multiStepFeedback, saveStyles ) )
157 outputLayers.append( QStringLiteral(
"%1|layername=%2" ).arg( packagePath, layer->name() ) );
164 feedback->
pushDebugInfo( QObject::tr(
"Packaging raster layers is not supported." ) );
171 feedback->
pushDebugInfo( QObject::tr(
"Packaging plugin layers is not supported." ) );
177 feedback->
pushDebugInfo( QObject::tr(
"Packaging mesh layers is not supported." ) );
187 outputs.insert( QStringLiteral(
"OUTPUT" ), packagePath );
188 outputs.insert( QStringLiteral(
"OUTPUT_LAYERS" ), outputLayers );
196 options.
driverName = QStringLiteral(
"GPKG" );
205 const int fidIndex = fields.
lookupField( QStringLiteral(
"fid" ) );
221 feedback->
reportError( QObject::tr(
"Packaging layer failed: %1" ).arg( error ) );
228 std::unique_ptr< QgsVectorLayer > res = qgis::make_unique< QgsVectorLayer >( QStringLiteral(
"%1|layername=%2" ).arg( newFilename, newLayer ) );
232 QDomDocument doc( QStringLiteral(
"qgis" ) );
235 if ( !errorMsg.isEmpty() )
237 feedback->
reportError( QObject::tr(
"Could not retrieve existing layer style: %1 " ).arg( errorMsg ) );
241 if ( !res->importNamedStyle( doc, errorMsg ) )
243 feedback->
reportError( QObject::tr(
"Could not set existing layer style: %1 " ).arg( errorMsg ) );
249 QVariant prevOverwriteStyle = settings.
value( QStringLiteral(
"qgis/overwriteStyle" ) );
250 settings.
setValue( QStringLiteral(
"qgis/overwriteStyle" ),
true );
251 res->saveStyleToDatabase( newLayer, QString(),
true, QString(), errorMsg );
252 settings.
setValue( QStringLiteral(
"qgis/overwriteStyle" ), prevOverwriteStyle );
253 if ( !errorMsg.isEmpty() )
255 feedback->
reportError( QObject::tr(
"Could not save layer style: %1 " ).arg( errorMsg ) );
262 feedback->
reportError( QObject::tr(
"Could not save layer style -- error loading: %1 %2" ).arg( newFilename, newLayer ) );
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A boolean parameter for processing algorithms.
The class is used as a container of context for various read/write operations on other objects...
A parameter for processing algorithms which accepts multiple map layers.
QgsVectorFileWriter::ActionOnExistingFile actionOnExistingFile
Action on existing file.
Base class for all map layer types.
Base class for providing feedback from a processing algorithm.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Processing feedback object for multi-step operations.
QgsAttributeList attributes
Attributes to export (empty means all unless skipAttributeCreation is set)
void setCurrentStep(int step)
Sets the step which is being executed.
Container of fields for a vector layer.
Options to pass to writeAsVectorFormat()
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
Custom exception class for processing related exceptions.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Create or overwrite layer.
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
QString driverName
OGR driver to use.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
A multi-layer output for processing algorithms which create map layers, when the number and nature of...
virtual void exportNamedStyle(QDomDocument &doc, QString &errorMsg, const QgsReadWriteContext &context=QgsReadWriteContext(), QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories) const
Export the properties of this layer as named style in a QDomDocument.
static QgsVectorFileWriter::WriterError writeAsVectorFormatV2(QgsVectorLayer *layer, const QString &fileName, const QgsCoordinateTransformContext &transformContext, const QgsVectorFileWriter::SaveVectorOptions &options, QString *newFilename=nullptr, QString *newLayer=nullptr, QString *errorMessage=nullptr)
Writes a layer out to a vector file.
QString fileEncoding
Encoding to use.
bool isCanceled() const
Tells whether the operation has been canceled already.
bool skipAttributeCreation
Only write geometries.
QString defaultEncoding() const
Returns the default encoding to use for newly created files.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
QString layerName
Layer name. If let empty, it will be derived from the filename.
std::unique_ptr< std::remove_pointer< OGRDataSourceH >::type, OGRDataSourceDeleter > ogr_datasource_unique_ptr
Scoped OGR data source.
QgsFeedback * feedback
Optional feedback object allowing cancellation of layer save.
Represents a vector layer which manages a vector based data sets.
Contains information about the context in which a processing algorithm is executed.