Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE][processing] Add "Save layer styles into GeoPackage" option …
…for Package Layers algorithm

Allows embedding of the current layer styles into the packaged layers
as the default layer styles.
  • Loading branch information
nyalldawson committed May 14, 2019
1 parent 95f8bfb commit 2d64437
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
52 changes: 48 additions & 4 deletions src/analysis/processing/qgsalgorithmpackage.cpp
Expand Up @@ -20,6 +20,7 @@
#include "qgsogrutils.h"
#include "qgsvectorfilewriter.h"
#include "qgsvectorlayer.h"
#include "qgssettings.h"

///@cond PRIVATE

Expand Down Expand Up @@ -53,6 +54,7 @@ void QgsPackageAlgorithm::initAlgorithm( const QVariantMap & )
addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "LAYERS" ), QObject::tr( "Input layers" ), QgsProcessing::TypeVector ) );
addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Destination GeoPackage" ), QObject::tr( "GeoPackage files (*.gpkg)" ) ) );
addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "OVERWRITE" ), QObject::tr( "Overwrite existing GeoPackage" ), false ) );
addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "SAVE_STYLES" ), QObject::tr( "Save layer styles into GeoPackage" ), true ) );
addOutput( new QgsProcessingOutputMultipleLayers( QStringLiteral( "OUTPUT_LAYERS" ), QObject::tr( "Layers within new package" ) ) );
}

Expand All @@ -68,7 +70,8 @@ QgsPackageAlgorithm *QgsPackageAlgorithm::createInstance() const

QVariantMap QgsPackageAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
bool overwrite = parameterAsBoolean( parameters, QStringLiteral( "OVERWRITE" ), context );
const bool overwrite = parameterAsBoolean( parameters, QStringLiteral( "OVERWRITE" ), context );
const bool saveStyles = parameterAsBoolean( parameters, QStringLiteral( "SAVE_STYLES" ), context );
QString packagePath = parameterAsString( parameters, QStringLiteral( "OUTPUT" ), context );
if ( packagePath.isEmpty() )
throw QgsProcessingException( QObject::tr( "No output file specified." ) );
Expand Down Expand Up @@ -123,7 +126,7 @@ QVariantMap QgsPackageAlgorithm::processAlgorithm( const QVariantMap &parameters
case QgsMapLayerType::VectorLayer:
{
if ( !packageVectorLayer( qobject_cast< QgsVectorLayer * >( layer ), packagePath,
context, &multiStepFeedback ) )
context, &multiStepFeedback, saveStyles ) )
errored = true;
else
outputLayers.append( QStringLiteral( "%1|layername=%2" ).arg( packagePath, layer->name() ) );
Expand Down Expand Up @@ -162,7 +165,7 @@ QVariantMap QgsPackageAlgorithm::processAlgorithm( const QVariantMap &parameters
}

bool QgsPackageAlgorithm::packageVectorLayer( QgsVectorLayer *layer, const QString &path, QgsProcessingContext &context,
QgsProcessingFeedback *feedback )
QgsProcessingFeedback *feedback, bool saveStyles )
{
QgsVectorFileWriter::SaveVectorOptions options;
options.driverName = QStringLiteral( "GPKG" );
Expand All @@ -172,13 +175,54 @@ bool QgsPackageAlgorithm::packageVectorLayer( QgsVectorLayer *layer, const QStri
options.feedback = feedback;

QString error;
if ( QgsVectorFileWriter::writeAsVectorFormat( layer, path, options, nullptr, &error ) != QgsVectorFileWriter::NoError )
QString newFilename;
QString newLayer;
if ( QgsVectorFileWriter::writeAsVectorFormat( layer, path, options, &newFilename, &error, &newLayer ) != QgsVectorFileWriter::NoError )
{
feedback->reportError( QObject::tr( "Packaging layer failed: %1" ).arg( error ) );
return false;
}
else
{
if ( saveStyles )
{
std::unique_ptr< QgsVectorLayer > res = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "%1|layername=%2" ).arg( newFilename, newLayer ) );
if ( res )
{
QString errorMsg;
QDomDocument doc( QStringLiteral( "qgis" ) );
QgsReadWriteContext context;
layer->exportNamedStyle( doc, errorMsg, context );
if ( !errorMsg.isEmpty() )
{
feedback->reportError( QObject::tr( "Could not retrieve existing layer style: %1 " ).arg( errorMsg ) );
}
else
{
if ( !res->importNamedStyle( doc, errorMsg ) )
{
feedback->reportError( QObject::tr( "Could not set existing layer style: %1 " ).arg( errorMsg ) );
}
else
{
QgsSettings settings;
// this is not nice -- but needed to avoid an "overwrite" prompt messagebox from the provider! This api needs a rework to avoid this.
QVariant prevOverwriteStyle = settings.value( QStringLiteral( "qgis/overwriteStyle" ) );
settings.setValue( QStringLiteral( "qgis/overwriteStyle" ), true );
res->saveStyleToDatabase( newLayer, QString(), true, QString(), errorMsg );
settings.setValue( QStringLiteral( "qgis/overwriteStyle" ), prevOverwriteStyle );
if ( !errorMsg.isEmpty() )
{
feedback->reportError( QObject::tr( "Could not save layer style: %1 " ).arg( errorMsg ) );
}
}
}
}
else
{
feedback->reportError( QObject::tr( "Could not save layer style -- error loading: %1 %2" ).arg( newFilename, newLayer ) );
}
}
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmpackage.h
Expand Up @@ -52,7 +52,7 @@ class QgsPackageAlgorithm : public QgsProcessingAlgorithm

private:

bool packageVectorLayer( QgsVectorLayer *layer, const QString &path, QgsProcessingContext &context, QgsProcessingFeedback *feedback );
bool packageVectorLayer( QgsVectorLayer *layer, const QString &path, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool saveStyles );

};

Expand Down

0 comments on commit 2d64437

Please sign in to comment.