26 #include <QImageWriter>
30 QString QgsLayoutAtlasToImageAlgorithm::name()
const
32 return QStringLiteral(
"atlaslayouttoimage" );
35 QString QgsLayoutAtlasToImageAlgorithm::displayName()
const
37 return QObject::tr(
"Export atlas layout as image" );
40 QStringList QgsLayoutAtlasToImageAlgorithm::tags()
const
42 return QObject::tr(
"layout,atlas,composer,composition,save,png,jpeg,jpg" ).split(
',' );
45 QString QgsLayoutAtlasToImageAlgorithm::group()
const
47 return QObject::tr(
"Cartography" );
50 QString QgsLayoutAtlasToImageAlgorithm::groupId()
const
52 return QStringLiteral(
"cartography" );
55 QString QgsLayoutAtlasToImageAlgorithm::shortDescription()
const
57 return QObject::tr(
"Exports an atlas layout as a set of images." );
60 QString QgsLayoutAtlasToImageAlgorithm::shortHelpString()
const
62 return QObject::tr(
"This algorithm outputs an atlas layout to a set of image files (e.g. PNG or JPEG images).\n\n"
63 "If a coverage layer is set, the selected layout's atlas settings exposed in this algorithm "
64 "will be overwritten. In this case, an empty filter or sort by expression will turn those "
68 void QgsLayoutAtlasToImageAlgorithm::initAlgorithm(
const QVariantMap & )
73 addParameter(
new QgsProcessingParameterExpression( QStringLiteral(
"FILTER_EXPRESSION" ), QObject::tr(
"Filter expression" ), QString(), QStringLiteral(
"COVERAGE_LAYER" ),
true ) );
74 addParameter(
new QgsProcessingParameterExpression( QStringLiteral(
"SORTBY_EXPRESSION" ), QObject::tr(
"Sort expression" ), QString(), QStringLiteral(
"COVERAGE_LAYER" ),
true ) );
75 addParameter(
new QgsProcessingParameterBoolean( QStringLiteral(
"SORTBY_REVERSE" ), QObject::tr(
"Reverse sort order (used when a sort expression is provided)" ),
false,
true ) );
77 addParameter(
new QgsProcessingParameterExpression( QStringLiteral(
"FILENAME_EXPRESSION" ), QObject::tr(
"Output filename expression" ), QStringLiteral(
"'output_'||@atlas_featurenumber" ), QStringLiteral(
"COVERAGE_LAYER" ) ) );
81 std::unique_ptr< QgsProcessingParameterMultipleLayers > layersParam = qgis::make_unique< QgsProcessingParameterMultipleLayers>( QStringLiteral(
"LAYERS" ), QObject::tr(
"Map layers to assign to unlocked map item(s)" ),
QgsProcessing::TypeMapLayer, QVariant(),
true );
83 addParameter( layersParam.release() );
85 QStringList imageFormats;
86 const QList<QByteArray> supportedImageFormats { QImageWriter::supportedImageFormats() };
87 for (
const QByteArray &format : supportedImageFormats )
89 if ( format == QByteArray(
"svg" ) )
91 imageFormats << QString( format );
93 std::unique_ptr< QgsProcessingParameterEnum > extensionParam = qgis::make_unique< QgsProcessingParameterEnum >( QStringLiteral(
"EXTENSION" ), QObject::tr(
"Image format" ), imageFormats,
false, imageFormats.indexOf( QLatin1String(
"png" ) ) );
95 addParameter( extensionParam.release() );
97 std::unique_ptr< QgsProcessingParameterNumber > dpiParam = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral(
"DPI" ), QObject::tr(
"DPI (leave blank for default layout DPI)" ),
QgsProcessingParameterNumber::Double, QVariant(),
true, 0 );
99 addParameter( dpiParam.release() );
101 std::unique_ptr< QgsProcessingParameterBoolean > appendGeorefParam = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral(
"GEOREFERENCE" ), QObject::tr(
"Generate world file" ),
true );
103 addParameter( appendGeorefParam.release() );
105 std::unique_ptr< QgsProcessingParameterBoolean > exportRDFParam = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral(
"INCLUDE_METADATA" ), QObject::tr(
"Export RDF metadata (title, author, etc.)" ),
true );
107 addParameter( exportRDFParam.release() );
109 std::unique_ptr< QgsProcessingParameterBoolean > antialias = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral(
"ANTIALIAS" ), QObject::tr(
"Enable antialiasing" ),
true );
111 addParameter( antialias.release() );
114 QgsProcessingAlgorithm::Flags QgsLayoutAtlasToImageAlgorithm::flags()
const
119 QgsLayoutAtlasToImageAlgorithm *QgsLayoutAtlasToImageAlgorithm::createInstance()
const
121 return new QgsLayoutAtlasToImageAlgorithm();
127 QgsPrintLayout *l = parameterAsLayout( parameters, QStringLiteral(
"LAYOUT" ), context );
129 throw QgsProcessingException( QObject::tr(
"Cannot find layout with name \"%1\"" ).arg( parameters.value( QStringLiteral(
"LAYOUT" ) ).toString() ) );
131 std::unique_ptr< QgsPrintLayout > layout( l->
clone() );
134 QString expression, error;
135 QgsVectorLayer *layer = parameterAsVectorLayer( parameters, QStringLiteral(
"COVERAGE_LAYER" ), context );
141 expression = parameterAsString( parameters, QStringLiteral(
"FILTER_EXPRESSION" ), context );
143 if ( !expression.isEmpty() && !error.isEmpty() )
149 expression = parameterAsString( parameters, QStringLiteral(
"SORTBY_EXPRESSION" ), context );
150 if ( !expression.isEmpty() )
152 const bool sortByReverse = parameterAsBool( parameters, QStringLiteral(
"SORTBY_REVERSE" ), context );
167 expression = parameterAsString( parameters, QStringLiteral(
"FILENAME_EXPRESSION" ), context );
169 if ( !error.isEmpty() )
174 const QString directory = parameterAsFileOutput( parameters, QStringLiteral(
"FOLDER" ), context );
175 QString fileName = QDir( directory ).filePath( QStringLiteral(
"atlas" ) );
177 QStringList imageFormats;
178 const QList<QByteArray> supportedImageFormats { QImageWriter::supportedImageFormats() };
179 for (
const QByteArray &format : supportedImageFormats )
181 if ( format == QByteArray(
"svg" ) )
183 imageFormats << QString( format );
185 int idx = parameterAsEnum( parameters, QStringLiteral(
"EXTENSION" ), context );
186 QString extension =
'.' + imageFormats.at( idx );
191 if ( parameters.value( QStringLiteral(
"DPI" ) ).isValid() )
193 settings.
dpi = parameterAsDouble( parameters, QStringLiteral(
"DPI" ), context );
196 settings.
exportMetadata = parameterAsBool( parameters, QStringLiteral(
"INCLUDE_METADATA" ), context );
197 settings.
generateWorldFile = parameterAsBool( parameters, QStringLiteral(
"GEOREFERENCE" ), context );
199 if ( parameterAsBool( parameters, QStringLiteral(
"ANTIALIAS" ), context ) )
204 const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral(
"LAYERS" ), context );
205 if ( layers.size() > 0 )
207 const QList<QGraphicsItem *> items = layout->items();
208 for ( QGraphicsItem *graphicsItem : items )
220 switch ( exporter.exportToImage( atlas, fileName, extension, settings, error, feedback ) )
224 feedback->
pushInfo( QObject::tr(
"Successfully exported layout to %1" ).arg( QDir::toNativeSeparators( directory ) ) );
229 throw QgsProcessingException( QObject::tr(
"Cannot write to %1.\n\nThis file may be open in another application." ).arg( QDir::toNativeSeparators( directory ) ) );
233 "resulted in a memory overflow.\n\n"
234 "Please try a lower resolution or a smaller paper size." ) );
249 outputs.insert( QStringLiteral(
"FOLDER" ), directory );