Skip to content

Commit

Permalink
[FEATURE][processing] Add "Save layer styles into GeoPackage" option …
Browse files Browse the repository at this point in the history
…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.