30 #include <QImageWriter> 32 #include <QSvgGenerator> 38 class LayoutContextPreviewSettingRestorer
42 LayoutContextPreviewSettingRestorer(
QgsLayout *layout )
44 , mPreviousSetting( layout->renderContext().mIsPreviewRender )
46 mLayout->renderContext().mIsPreviewRender =
false;
49 ~LayoutContextPreviewSettingRestorer()
51 mLayout->renderContext().mIsPreviewRender = mPreviousSetting;
54 LayoutContextPreviewSettingRestorer(
const LayoutContextPreviewSettingRestorer &other ) =
delete;
55 LayoutContextPreviewSettingRestorer &operator=(
const LayoutContextPreviewSettingRestorer &other ) =
delete;
59 bool mPreviousSetting =
false;
62 class LayoutGuideHider
69 const QList< QgsLayoutGuide * > guides = mLayout->guides().guides();
72 mPrevVisibility.insert( guide, guide->item()->isVisible() );
73 guide->item()->setVisible(
false );
79 for (
auto it = mPrevVisibility.constBegin(); it != mPrevVisibility.constEnd(); ++it )
81 it.key()->item()->setVisible( it.value() );
85 LayoutGuideHider(
const LayoutGuideHider &other ) =
delete;
86 LayoutGuideHider &operator=(
const LayoutGuideHider &other ) =
delete;
90 QHash< QgsLayoutGuide *, bool > mPrevVisibility;
96 explicit LayoutItemHider(
const QList<QGraphicsItem *> &items )
98 mItemsToIterate.reserve( items.count() );
99 for ( QGraphicsItem *item : items )
101 const bool isVisible = item->isVisible();
102 mPrevVisibility[item] = isVisible;
104 mItemsToIterate.append( item );
105 if (
QgsLayoutItem *layoutItem = dynamic_cast< QgsLayoutItem * >( item ) )
106 layoutItem->setProperty(
"wasVisible", isVisible );
114 for (
auto it = mPrevVisibility.constBegin(); it != mPrevVisibility.constEnd(); ++it )
122 for (
auto it = mPrevVisibility.constBegin(); it != mPrevVisibility.constEnd(); ++it )
124 it.key()->setVisible( it.value() );
125 if (
QgsLayoutItem *layoutItem = dynamic_cast< QgsLayoutItem * >( it.key() ) )
126 layoutItem->setProperty(
"wasVisible", QVariant() );
130 QList< QGraphicsItem * > itemsToIterate()
const {
return mItemsToIterate; }
132 LayoutItemHider(
const LayoutItemHider &other ) =
delete;
133 LayoutItemHider &operator=(
const LayoutItemHider &other ) =
delete;
137 QList<QGraphicsItem * > mItemsToIterate;
138 QHash<QGraphicsItem *, bool> mPrevVisibility;
159 if ( mLayout->pageCollection()->pageCount() <= page || page < 0 )
170 LayoutContextPreviewSettingRestorer restorer( mLayout );
173 QRectF paperRect = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() );
182 if ( mLayout->pageCollection()->pageCount() <= page || page < 0 )
193 LayoutContextPreviewSettingRestorer restorer( mLayout );
196 QRectF paperRect = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() );
198 if ( imageSize.isValid() && ( !
qgsDoubleNear( static_cast< double >( imageSize.width() ) / imageSize.height(),
199 paperRect.width() / paperRect.height(), 0.008 ) ) )
211 class LayoutItemCacheSettingRestorer
215 LayoutItemCacheSettingRestorer(
QgsLayout *layout )
218 const QList< QGraphicsItem * > items = mLayout->items();
219 for ( QGraphicsItem *item : items )
221 mPrevCacheMode.insert( item, item->cacheMode() );
222 item->setCacheMode( QGraphicsItem::NoCache );
226 ~LayoutItemCacheSettingRestorer()
228 for (
auto it = mPrevCacheMode.constBegin(); it != mPrevCacheMode.constEnd(); ++it )
230 it.key()->setCacheMode( it.value() );
234 LayoutItemCacheSettingRestorer(
const LayoutItemCacheSettingRestorer &other ) =
delete;
235 LayoutItemCacheSettingRestorer &operator=(
const LayoutItemCacheSettingRestorer &other ) =
delete;
239 QHash< QGraphicsItem *, QGraphicsItem::CacheMode > mPrevCacheMode;
246 QPaintDevice *paintDevice = painter->device();
247 if ( !paintDevice || !mLayout )
252 LayoutItemCacheSettingRestorer cacheRestorer( mLayout );
253 ( void )cacheRestorer;
254 LayoutContextPreviewSettingRestorer restorer( mLayout );
256 LayoutGuideHider guideHider( mLayout );
261 mLayout->render( painter, QRectF( 0, 0, paintDevice->width(), paintDevice->height() ), region );
269 LayoutContextPreviewSettingRestorer restorer( mLayout );
272 double resolution = mLayout->renderContext().dpi();
274 if ( imageSize.isValid() )
278 resolution = ( imageSize.width() / region.width()
279 + imageSize.height() / region.height() ) / 2.0 * oneInchInLayoutUnits;
287 int width = imageSize.isValid() ? imageSize.width()
288 :
static_cast< int >( resolution * region.width() / oneInchInLayoutUnits );
289 int height = imageSize.isValid() ? imageSize.height()
290 :
static_cast< int >( resolution * region.height() / oneInchInLayoutUnits );
292 QImage image( QSize( width, height ), QImage::Format_ARGB32 );
293 if ( !image.isNull() )
295 image.setDotsPerMeterX( static_cast< int >( std::round( resolution / 25.4 * 1000 ) ) );
296 image.setDotsPerMeterY( static_cast< int>( std::round( resolution / 25.4 * 1000 ) ) );
297 image.fill( Qt::transparent );
298 QPainter imagePainter( &image );
300 if ( !imagePainter.isActive() )
308 class LayoutContextSettingsRestorer
313 LayoutContextSettingsRestorer(
QgsLayout *layout )
326 ~LayoutContextSettingsRestorer()
328 mLayout->renderContext().setDpi( mPreviousDpi );
329 mLayout->renderContext().setFlags( mPreviousFlags );
330 mLayout->renderContext().setTextRenderFormat( mPreviousTextFormat );
332 mLayout->renderContext().setCurrentExportLayer( mPreviousExportLayer );
334 mLayout->renderContext().setSimplifyMethod( mPreviousSimplifyMethod );
335 mLayout->renderContext().setExportThemes( mExportThemes );
336 mLayout->renderContext().setPredefinedScales( mPredefinedScales );
339 LayoutContextSettingsRestorer(
const LayoutContextSettingsRestorer &other ) =
delete;
340 LayoutContextSettingsRestorer &operator=(
const LayoutContextSettingsRestorer &other ) =
delete;
344 double mPreviousDpi = 0;
345 QgsLayoutRenderContext::Flags mPreviousFlags =
nullptr;
347 int mPreviousExportLayer = 0;
349 QStringList mExportThemes;
350 QVector< double > mPredefinedScales;
361 if ( settings.
dpi <= 0 )
362 settings.
dpi = mLayout->renderContext().dpi();
364 mErrorFileName.clear();
366 int worldFilePageNo = -1;
369 worldFilePageNo = referenceMap->page();
372 QFileInfo fi( filePath );
376 pageDetails.
baseName = fi.completeBaseName();
379 LayoutContextPreviewSettingRestorer restorer( mLayout );
381 LayoutContextSettingsRestorer dpiRestorer( mLayout );
383 mLayout->renderContext().setDpi( settings.
dpi );
384 mLayout->renderContext().setFlags( settings.
flags );
388 if ( settings.
pages.empty() )
390 for (
int page = 0; page < mLayout->pageCollection()->pageCount(); ++page )
395 for (
int page : qgis::as_const( settings.
pages ) )
397 if ( page >= 0 && page < mLayout->pageCollection()->pageCount() )
402 for (
int page : qgis::as_const( pages ) )
404 if ( !mLayout->pageCollection()->shouldExportPage( page ) )
411 QImage image = createImage( settings, page, bounds, skip );
416 pageDetails.
page = page;
419 if ( image.isNull() )
421 mErrorFileName = outputFilePath;
425 if ( !saveImage( image, outputFilePath, pageDetails.
extension, settings.
exportMetadata ? mLayout->project() : nullptr ) )
427 mErrorFileName = outputFilePath;
431 const bool shouldGeoreference = ( page == worldFilePageNo );
432 if ( shouldGeoreference )
434 georeferenceOutputPrivate( outputFilePath,
nullptr, bounds, settings.
dpi, shouldGeoreference );
439 double a, b,
c, d, e, f;
440 if ( bounds.isValid() )
445 QFileInfo fi( outputFilePath );
447 QString outputSuffix = fi.suffix();
448 QString worldFileName = fi.absolutePath() +
'/' + fi.baseName() +
'.' 449 + outputSuffix.at( 0 ) + outputSuffix.at( fi.suffix().size() - 1 ) +
'w';
451 writeWorldFile( worldFileName, a, b, c, d, e, f );
466 int total = iterator->
count();
467 double step = total > 0 ? 100.0 / total : 100.0;
469 while ( iterator->
next() )
474 feedback->setProperty(
"progress", QObject::tr(
"Exporting %1 of %2" ).arg( i + 1 ).arg( total ) );
476 feedback->setProperty(
"progress", QObject::tr(
"Exporting section %1" ).arg( i + 1 ).arg( total ) );
486 QString filePath = iterator->
filePath( baseFilePath, extension );
487 ExportResult result = exporter.exportToImage( filePath, settings );
491 error = QObject::tr(
"Cannot write to %1. This file may be open in another application or may be an invalid path." ).arg( QDir::toNativeSeparators( filePath ) );
509 if ( !mLayout || mLayout->pageCollection()->pageCount() == 0 )
513 if ( settings.
dpi <= 0 )
514 settings.
dpi = mLayout->renderContext().dpi();
516 mErrorFileName.clear();
518 LayoutContextPreviewSettingRestorer restorer( mLayout );
520 LayoutContextSettingsRestorer contextRestorer( mLayout );
521 ( void )contextRestorer;
522 mLayout->renderContext().setDpi( settings.
dpi );
527 mLayout->renderContext().setSimplifyMethod( createExportSimplifyMethod() );
530 std::unique_ptr< QgsLayoutGeoPdfExporter > geoPdfExporter;
532 geoPdfExporter = qgis::make_unique< QgsLayoutGeoPdfExporter >( mLayout );
534 mLayout->renderContext().setFlags( settings.
flags );
542 mLayout->renderContext().setExportThemes( settings.
exportThemes );
553 const QList<QGraphicsItem *> items = mLayout->items( Qt::AscendingOrder );
555 QList< QgsLayoutGeoPdfExporter::ComponentLayerDetail > pdfComponents;
562 component.
name = layerDetail.name;
563 component.
mapLayerId = layerDetail.mapLayerId;
564 component.
group = layerDetail.mapTheme;
565 component.
sourcePdfPath = geoPdfExporter->generateTemporaryFilepath( QStringLiteral(
"layer_%1.pdf" ).arg( layerId ) );
566 pdfComponents << component;
567 preparePrintAsPdf( mLayout, printer, component.sourcePdfPath );
568 preparePrint( mLayout, printer,
false );
570 if ( !p.begin( &printer ) )
578 return layerExportResult;
580 result = handleLayeredExport( items, exportFunc );
585 details.
dpi = settings.
dpi;
587 QgsLayoutSize pageSize = mLayout->pageCollection()->page( 0 )->sizeWithUnits();
594 details.
author = mLayout->project()->metadata().author();
597 details.
creationDateTime = mLayout->project()->metadata().creationDateTime();
598 details.
subject = mLayout->project()->metadata().abstract();
599 details.
title = mLayout->project()->metadata().title();
600 details.
keywords = mLayout->project()->metadata().keywords();
606 QList< QgsLayoutItemMap * > maps;
607 mLayout->layoutItems( maps );
611 georef.
crs = map->crs();
613 const QPointF topLeft = map->mapToScene( QPointF( 0, 0 ) );
614 const QPointF topRight = map->mapToScene( QPointF( map->rect().width(), 0 ) );
615 const QPointF bottomLeft = map->mapToScene( QPointF( 0, map->rect().height() ) );
616 const QPointF bottomRight = map->mapToScene( QPointF( map->rect().width(), map->rect().height() ) );
629 const QTransform t = map->layoutToMapCoordsTransform();
630 const QgsPointXY topLeftMap = t.map( topLeft );
631 const QgsPointXY topRightMap = t.map( topRight );
632 const QgsPointXY bottomLeftMap = t.map( bottomLeft );
633 const QgsPointXY bottomRightMap = t.map( bottomRight );
648 if ( !geoPdfExporter->finalize( pdfComponents, filePath, details ) )
654 preparePrintAsPdf( mLayout, printer, filePath );
655 preparePrint( mLayout, printer,
false );
657 if ( !p.begin( &printer ) )
666 bool shouldAppendGeoreference = settings.
appendGeoreference && mLayout && mLayout->referenceMap() && mLayout->referenceMap()->page() == 0;
669 georeferenceOutputPrivate( filePath,
nullptr, QRectF(), settings.
dpi, shouldAppendGeoreference, settings.
exportMetadata );
687 int total = iterator->
count();
688 double step = total > 0 ? 100.0 / total : 100.0;
691 while ( iterator->
next() )
696 feedback->setProperty(
"progress", QObject::tr(
"Exporting %1 of %2" ).arg( i + 1 ).arg( total ) );
698 feedback->setProperty(
"progress", QObject::tr(
"Exporting section %1" ).arg( i + 1 ) );
710 LayoutContextPreviewSettingRestorer restorer( iterator->
layout() );
712 LayoutContextSettingsRestorer contextRestorer( iterator->
layout() );
713 ( void )contextRestorer;
735 preparePrintAsPdf( iterator->
layout(), printer, fileName );
736 preparePrint( iterator->
layout(), printer, false );
738 if ( !p.begin( &printer ) )
751 error = QObject::tr(
"Cannot write to %1. This file may be open in another application or may be an invalid path." ).arg( QDir::toNativeSeparators( fileName ) );
775 int total = iterator->
count();
776 double step = total > 0 ? 100.0 / total : 100.0;
778 while ( iterator->
next() )
783 feedback->setProperty(
"progress", QObject::tr(
"Exporting %1 of %2" ).arg( i + 1 ).arg( total ) );
785 feedback->setProperty(
"progress", QObject::tr(
"Exporting section %1" ).arg( i + 1 ).arg( total ) );
794 QString filePath = iterator->
filePath( baseFilePath, QStringLiteral(
"pdf" ) );
801 error = QObject::tr(
"Cannot write to %1. This file may be open in another application or may be an invalid path." ).arg( QDir::toNativeSeparators( filePath ) );
823 if ( settings.
dpi <= 0 )
824 settings.
dpi = mLayout->renderContext().dpi();
826 mErrorFileName.clear();
828 LayoutContextPreviewSettingRestorer restorer( mLayout );
830 LayoutContextSettingsRestorer contextRestorer( mLayout );
831 ( void )contextRestorer;
832 mLayout->renderContext().setDpi( settings.
dpi );
834 mLayout->renderContext().setFlags( settings.
flags );
841 preparePrint( mLayout, printer,
true );
843 if ( !p.begin( &printer ) )
866 int total = iterator->
count();
867 double step = total > 0 ? 100.0 / total : 100.0;
870 while ( iterator->
next() )
875 feedback->setProperty(
"progress", QObject::tr(
"Printing %1 of %2" ).arg( i + 1 ).arg( total ) );
877 feedback->setProperty(
"progress", QObject::tr(
"Printing section %1" ).arg( i + 1 ).arg( total ) );
889 LayoutContextPreviewSettingRestorer restorer( iterator->
layout() );
891 LayoutContextSettingsRestorer contextRestorer( iterator->
layout() );
892 ( void )contextRestorer;
905 preparePrint( iterator->
layout(), printer, true );
907 if ( !p.begin( &printer ) )
941 if ( settings.
dpi <= 0 )
942 settings.
dpi = mLayout->renderContext().dpi();
944 mErrorFileName.clear();
946 LayoutContextPreviewSettingRestorer restorer( mLayout );
948 LayoutContextSettingsRestorer contextRestorer( mLayout );
949 ( void )contextRestorer;
950 mLayout->renderContext().setDpi( settings.
dpi );
952 mLayout->renderContext().setFlags( settings.
flags );
959 mLayout->renderContext().setSimplifyMethod( createExportSimplifyMethod() );
962 QFileInfo fi( filePath );
965 pageDetails.
baseName = fi.baseName();
966 pageDetails.
extension = fi.completeSuffix();
970 for (
int i = 0; i < mLayout->pageCollection()->pageCount(); ++i )
972 if ( !mLayout->pageCollection()->shouldExportPage( i ) )
977 pageDetails.
page = i;
984 if ( mLayout->pageCollection()->pageCount() == 1 )
987 bounds = mLayout->layoutBounds(
true );
992 bounds = mLayout->pageItemBounds( i,
true );
1001 bounds = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() );
1005 int width =
static_cast< int >( bounds.width() * settings.
dpi / inchesToLayoutUnits );
1007 int height =
static_cast< int >( bounds.height() * settings.
dpi / inchesToLayoutUnits );
1008 if ( width == 0 || height == 0 )
1017 const QRectF paperRect = QRectF( pageItem->pos().x(),
1018 pageItem->pos().y(),
1019 pageItem->rect().width(),
1020 pageItem->rect().height() );
1022 QDomNode svgDocRoot;
1023 const QList<QGraphicsItem *> items = mLayout->items( paperRect,
1024 Qt::IntersectsItemBoundingRect,
1025 Qt::AscendingOrder );
1029 return renderToLayeredSvg( settings, width, height, i, bounds, fileName, layerId, layerDetail.name, svg, svgDocRoot, settings.
exportMetadata );
1031 ExportResult res = handleLayeredExport( items, exportFunc );
1036 appendMetadataToSvg( svg );
1038 QFile out( fileName );
1039 bool openOk = out.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate );
1042 mErrorFileName = fileName;
1046 out.write( svg.toByteArray() );
1052 QSvgGenerator generator;
1055 generator.setTitle( mLayout->project()->metadata().title() );
1056 generator.setDescription( mLayout->project()->metadata().abstract() );
1058 generator.setOutputDevice( &svgBuffer );
1059 generator.setSize( QSize( width, height ) );
1060 generator.setViewBox( QRect( 0, 0, width, height ) );
1061 generator.setResolution( static_cast< int >( std::round( settings.
dpi ) ) );
1064 bool createOk = p.begin( &generator );
1067 mErrorFileName = fileName;
1080 svgBuffer.open( QIODevice::ReadOnly );
1084 if ( ! svg.setContent( &svgBuffer,
false, &errorMsg, &errorLine ) )
1086 mErrorFileName = fileName;
1091 appendMetadataToSvg( svg );
1093 QFile out( fileName );
1094 bool openOk = out.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate );
1097 mErrorFileName = fileName;
1101 out.write( svg.toByteArray() );
1116 int total = iterator->
count();
1117 double step = total > 0 ? 100.0 / total : 100.0;
1119 while ( iterator->
next() )
1124 feedback->setProperty(
"progress", QObject::tr(
"Exporting %1 of %2" ).arg( i + 1 ).arg( total ) );
1126 feedback->setProperty(
"progress", QObject::tr(
"Exporting section %1" ).arg( i + 1 ).arg( total ) );
1136 QString filePath = iterator->
filePath( baseFilePath, QStringLiteral(
"svg" ) );
1143 error = QObject::tr(
"Cannot write to %1. This file may be open in another application or may be an invalid path." ).arg( QDir::toNativeSeparators( filePath ) );
1160 void QgsLayoutExporter::preparePrintAsPdf(
QgsLayout *layout, QPrinter &printer,
const QString &filePath )
1162 printer.setOutputFileName( filePath );
1163 printer.setOutputFormat( QPrinter::PdfFormat );
1165 updatePrinterPageSize( layout, printer, firstPageToBeExported( layout ) );
1174 void QgsLayoutExporter::preparePrint(
QgsLayout *layout, QPrinter &printer,
bool setFirstPageSize )
1176 printer.setFullPage(
true );
1177 printer.setColorMode( QPrinter::Color );
1180 printer.setResolution( static_cast< int>( std::round( layout->
renderContext().
dpi() ) ) );
1182 if ( setFirstPageSize )
1184 updatePrinterPageSize( layout, printer, firstPageToBeExported( layout ) );
1190 if ( mLayout->pageCollection()->pageCount() == 0 )
1193 preparePrint( mLayout, printer,
true );
1195 if ( !p.begin( &printer ) )
1201 printPrivate( printer, p );
1206 QgsLayoutExporter::ExportResult QgsLayoutExporter::printPrivate( QPrinter &printer, QPainter &painter,
bool startNewPage,
double dpi,
bool rasterize )
1209 int fromPage = ( printer.fromPage() < 1 ) ? 0 : printer.fromPage() - 1;
1210 int toPage = ( printer.toPage() < 1 ) ? mLayout->pageCollection()->pageCount() - 1 : printer.toPage() - 1;
1212 bool pageExported =
false;
1215 for (
int i = fromPage; i <= toPage; ++i )
1217 if ( !mLayout->pageCollection()->shouldExportPage( i ) )
1222 updatePrinterPageSize( mLayout, printer, i );
1223 if ( ( pageExported && i > fromPage ) || startNewPage )
1229 if ( !image.isNull() )
1231 QRectF targetArea( 0, 0, image.width(), image.height() );
1232 painter.drawImage( targetArea, image, targetArea );
1238 pageExported =
true;
1243 for (
int i = fromPage; i <= toPage; ++i )
1245 if ( !mLayout->pageCollection()->shouldExportPage( i ) )
1250 updatePrinterPageSize( mLayout, printer, i );
1252 if ( ( pageExported && i > fromPage ) || startNewPage )
1257 pageExported =
true;
1263 void QgsLayoutExporter::updatePrinterPageSize(
QgsLayout *layout, QPrinter &printer,
int page )
1268 QPageLayout pageLayout( QPageSize( pageSizeMM.
toQSizeF(), QPageSize::Millimeter ),
1269 QPageLayout::Portrait,
1270 QMarginsF( 0, 0, 0, 0 ) );
1271 pageLayout.setMode( QPageLayout::FullPageMode );
1272 printer.setPageLayout( pageLayout );
1273 printer.setFullPage(
true );
1274 printer.setPageMargins( QMarginsF( 0, 0, 0, 0 ) );
1277 QgsLayoutExporter::ExportResult QgsLayoutExporter::renderToLayeredSvg(
const SvgExportSettings &settings,
double width,
double height,
int page,
const QRectF &bounds,
const QString &filename,
unsigned int svgLayerId,
const QString &layerName, QDomDocument &svg, QDomNode &svgDocRoot,
bool includeMetadata )
const 1281 QSvgGenerator generator;
1282 if ( includeMetadata )
1285 generator.setTitle( l->name() );
1286 else if ( mLayout->project() )
1287 generator.setTitle( mLayout->project()->title() );
1290 generator.setOutputDevice( &svgBuffer );
1291 generator.setSize( QSize( static_cast< int >( std::round( width ) ),
1292 static_cast< int >( std::round( height ) ) ) );
1293 generator.setViewBox( QRect( 0, 0,
1294 static_cast< int >( std::round( width ) ),
1295 static_cast< int >( std::round( height ) ) ) );
1296 generator.setResolution( static_cast< int >( std::round( settings.
dpi ) ) );
1298 QPainter svgPainter( &generator );
1310 svgBuffer.open( QIODevice::ReadOnly );
1314 if ( ! doc.setContent( &svgBuffer,
false, &errorMsg, &errorLine ) )
1316 mErrorFileName = filename;
1319 if ( 1 == svgLayerId )
1321 svg = QDomDocument( doc.doctype() );
1322 svg.appendChild( svg.importNode( doc.firstChild(), false ) );
1323 svgDocRoot = svg.importNode( doc.elementsByTagName( QStringLiteral(
"svg" ) ).at( 0 ), false );
1324 svgDocRoot.toElement().setAttribute( QStringLiteral(
"xmlns:inkscape" ), QStringLiteral(
"http://www.inkscape.org/namespaces/inkscape" ) );
1325 svg.appendChild( svgDocRoot );
1327 QDomNode mainGroup = svg.importNode( doc.elementsByTagName( QStringLiteral(
"g" ) ).at( 0 ), true );
1328 mainGroup.toElement().setAttribute( QStringLiteral(
"id" ), layerName );
1329 mainGroup.toElement().setAttribute( QStringLiteral(
"inkscape:label" ), layerName );
1330 mainGroup.toElement().setAttribute( QStringLiteral(
"inkscape:groupmode" ), QStringLiteral(
"layer" ) );
1331 QDomNode defs = svg.importNode( doc.elementsByTagName( QStringLiteral(
"defs" ) ).at( 0 ), true );
1332 svgDocRoot.appendChild( defs );
1333 svgDocRoot.appendChild( mainGroup );
1338 void QgsLayoutExporter::appendMetadataToSvg( QDomDocument &svg )
const 1341 QDomElement metadataElement = svg.createElement( QStringLiteral(
"metadata" ) );
1342 QDomElement rdfElement = svg.createElement( QStringLiteral(
"rdf:RDF" ) );
1343 rdfElement.setAttribute( QStringLiteral(
"xmlns:rdf" ), QStringLiteral(
"http://www.w3.org/1999/02/22-rdf-syntax-ns#" ) );
1344 rdfElement.setAttribute( QStringLiteral(
"xmlns:rdfs" ), QStringLiteral(
"http://www.w3.org/2000/01/rdf-schema#" ) );
1345 rdfElement.setAttribute( QStringLiteral(
"xmlns:dc" ), QStringLiteral(
"http://purl.org/dc/elements/1.1/" ) );
1346 QDomElement descriptionElement = svg.createElement( QStringLiteral(
"rdf:Description" ) );
1347 QDomElement workElement = svg.createElement( QStringLiteral(
"cc:Work" ) );
1348 workElement.setAttribute( QStringLiteral(
"rdf:about" ), QString() );
1350 auto addTextNode = [&workElement, &descriptionElement, &svg](
const QString & tag,
const QString & value )
1353 QDomElement element = svg.createElement( tag );
1354 QDomText t = svg.createTextNode( value );
1355 element.appendChild( t );
1356 workElement.appendChild( element );
1359 descriptionElement.setAttribute( tag, value );
1362 addTextNode( QStringLiteral(
"dc:format" ), QStringLiteral(
"image/svg+xml" ) );
1363 addTextNode( QStringLiteral(
"dc:title" ), metadata.
title() );
1364 addTextNode( QStringLiteral(
"dc:date" ), metadata.
creationDateTime().toString( Qt::ISODate ) );
1365 addTextNode( QStringLiteral(
"dc:identifier" ), metadata.
identifier() );
1366 addTextNode( QStringLiteral(
"dc:description" ), metadata.
abstract() );
1368 auto addAgentNode = [&workElement, &descriptionElement, &svg](
const QString & tag,
const QString & value )
1371 QDomElement inkscapeElement = svg.createElement( tag );
1372 QDomElement agentElement = svg.createElement( QStringLiteral(
"cc:Agent" ) );
1373 QDomElement titleElement = svg.createElement( QStringLiteral(
"dc:title" ) );
1374 QDomText t = svg.createTextNode( value );
1375 titleElement.appendChild( t );
1376 agentElement.appendChild( titleElement );
1377 inkscapeElement.appendChild( agentElement );
1378 workElement.appendChild( inkscapeElement );
1381 QDomElement bagElement = svg.createElement( QStringLiteral(
"rdf:Bag" ) );
1382 QDomElement liElement = svg.createElement( QStringLiteral(
"rdf:li" ) );
1383 t = svg.createTextNode( value );
1384 liElement.appendChild( t );
1385 bagElement.appendChild( liElement );
1387 QDomElement element = svg.createElement( tag );
1388 element.appendChild( bagElement );
1389 descriptionElement.appendChild( element );
1392 addAgentNode( QStringLiteral(
"dc:creator" ), metadata.
author() );
1393 addAgentNode( QStringLiteral(
"dc:publisher" ), QStringLiteral(
"QGIS %1" ).arg(
Qgis::QGIS_VERSION ) );
1397 QDomElement element = svg.createElement( QStringLiteral(
"dc:subject" ) );
1398 QDomElement bagElement = svg.createElement( QStringLiteral(
"rdf:Bag" ) );
1400 for (
auto it = keywords.constBegin(); it != keywords.constEnd(); ++it )
1402 const QStringList words = it.value();
1403 for (
const QString &keyword : words )
1405 QDomElement liElement = svg.createElement( QStringLiteral(
"rdf:li" ) );
1406 QDomText t = svg.createTextNode( keyword );
1407 liElement.appendChild( t );
1408 bagElement.appendChild( liElement );
1411 element.appendChild( bagElement );
1412 workElement.appendChild( element );
1413 descriptionElement.appendChild( element );
1416 rdfElement.appendChild( descriptionElement );
1417 rdfElement.appendChild( workElement );
1418 metadataElement.appendChild( rdfElement );
1419 svg.documentElement().appendChild( metadataElement );
1420 svg.documentElement().setAttribute( QStringLiteral(
"xmlns:cc" ), QStringLiteral(
"http://creativecommons.org/ns#" ) );
1423 std::unique_ptr<double[]> QgsLayoutExporter::computeGeoTransform(
const QgsLayoutItemMap *map,
const QRectF ®ion,
double dpi )
const 1426 map = mLayout->referenceMap();
1432 dpi = mLayout->renderContext().dpi();
1435 QRectF exportRegion = region;
1436 if ( !exportRegion.isValid() )
1438 int pageNumber = map->
page();
1441 double pageY = page->pos().y();
1442 QSizeF pageSize = page->rect().size();
1443 exportRegion = QRectF( 0, pageY, pageSize.width(), pageSize.height() );
1447 QRectF mapItemSceneRect = map->mapRectToScene( map->rect() );
1450 double outputHeightMM = exportRegion.height();
1451 double outputWidthMM = exportRegion.width();
1455 double mapXCenter = mapExtent.
center().
x();
1456 double mapYCenter = mapExtent.
center().
y();
1458 double sinAlpha = std::sin( alpha );
1459 double cosAlpha = std::cos( alpha );
1462 QPointF mapItemPos = map->pos();
1464 mapItemPos.rx() -= exportRegion.left();
1465 mapItemPos.ry() -= exportRegion.top();
1468 double xRatio = mapExtent.
width() / mapItemSceneRect.width();
1469 double yRatio = mapExtent.
height() / mapItemSceneRect.height();
1470 double xmin = mapExtent.
xMinimum() - mapItemPos.x() * xRatio;
1471 double ymax = mapExtent.
yMaximum() + mapItemPos.y() * yRatio;
1472 QgsRectangle paperExtent( xmin, ymax - outputHeightMM * yRatio, xmin + outputWidthMM * xRatio, ymax );
1475 double X0 = paperExtent.
xMinimum();
1476 double Y0 = paperExtent.
yMaximum();
1481 double X1 = X0 - mapXCenter;
1482 double Y1 = Y0 - mapYCenter;
1483 double X2 = X1 * cosAlpha + Y1 * sinAlpha;
1484 double Y2 = -X1 * sinAlpha + Y1 * cosAlpha;
1485 X0 = X2 + mapXCenter;
1486 Y0 = Y2 + mapYCenter;
1490 int pageWidthPixels =
static_cast< int >( dpi * outputWidthMM / 25.4 );
1491 int pageHeightPixels =
static_cast< int >( dpi * outputHeightMM / 25.4 );
1492 double pixelWidthScale = paperExtent.
width() / pageWidthPixels;
1493 double pixelHeightScale = paperExtent.
height() / pageHeightPixels;
1496 std::unique_ptr<double[]> t(
new double[6] );
1498 t[1] = cosAlpha * pixelWidthScale;
1499 t[2] = -sinAlpha * pixelWidthScale;
1501 t[4] = -sinAlpha * pixelHeightScale;
1502 t[5] = -cosAlpha * pixelHeightScale;
1507 void QgsLayoutExporter::writeWorldFile(
const QString &worldFileName,
double a,
double b,
double c,
double d,
double e,
double f )
const 1509 QFile worldFile( worldFileName );
1510 if ( !worldFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
1514 QTextStream fout( &worldFile );
1518 fout << QString::number( a,
'f', 12 ) <<
"\r\n";
1519 fout << QString::number( d,
'f', 12 ) <<
"\r\n";
1520 fout << QString::number( b,
'f', 12 ) <<
"\r\n";
1521 fout << QString::number( e,
'f', 12 ) <<
"\r\n";
1522 fout << QString::number( c,
'f', 12 ) <<
"\r\n";
1523 fout << QString::number( f,
'f', 12 ) <<
"\r\n";
1528 return georeferenceOutputPrivate( file, map, exportRegion, dpi,
false );
1531 bool QgsLayoutExporter::georeferenceOutputPrivate(
const QString &file,
QgsLayoutItemMap *map,
const QRectF &exportRegion,
double dpi,
bool includeGeoreference,
bool includeMetadata )
const 1536 if ( !map && includeGeoreference )
1537 map = mLayout->referenceMap();
1539 std::unique_ptr<double[]> t;
1541 if ( map && includeGeoreference )
1544 dpi = mLayout->renderContext().dpi();
1546 t = computeGeoTransform( map, exportRegion, dpi );
1551 CPLSetConfigOption(
"GDAL_PDF_DPI", QString::number( dpi ).toLocal8Bit().constData() );
1556 GDALSetGeoTransform( outputDS.get(), t.get() );
1558 if ( includeMetadata )
1560 QString creationDateString;
1561 const QDateTime creationDateTime = mLayout->project()->metadata().creationDateTime();
1562 if ( creationDateTime.isValid() )
1564 creationDateString = QStringLiteral(
"D:%1" ).arg( mLayout->project()->metadata().creationDateTime().toString( QStringLiteral(
"yyyyMMddHHmmss" ) ) );
1565 if ( creationDateTime.timeZone().isValid() )
1567 int offsetFromUtc = creationDateTime.timeZone().offsetFromUtc( creationDateTime );
1568 creationDateString += ( offsetFromUtc >= 0 ) ?
'+' :
'-';
1569 offsetFromUtc = std::abs( offsetFromUtc );
1570 int offsetHours = offsetFromUtc / 3600;
1571 int offsetMins = ( offsetFromUtc % 3600 ) / 60;
1572 creationDateString += QStringLiteral(
"%1'%2'" ).arg( offsetHours ).arg( offsetMins );
1575 GDALSetMetadataItem( outputDS.get(),
"CREATION_DATE", creationDateString.toLocal8Bit().constData(), nullptr );
1577 GDALSetMetadataItem( outputDS.get(),
"AUTHOR", mLayout->project()->metadata().author().toLocal8Bit().constData(), nullptr );
1579 GDALSetMetadataItem( outputDS.get(),
"CREATOR", creator.toLocal8Bit().constData(), nullptr );
1580 GDALSetMetadataItem( outputDS.get(),
"PRODUCER", creator.toLocal8Bit().constData(), nullptr );
1581 GDALSetMetadataItem( outputDS.get(),
"SUBJECT", mLayout->project()->metadata().abstract().toLocal8Bit().constData(), nullptr );
1582 GDALSetMetadataItem( outputDS.get(),
"TITLE", mLayout->project()->metadata().title().toLocal8Bit().constData(), nullptr );
1585 QStringList allKeywords;
1586 for (
auto it = keywords.constBegin(); it != keywords.constEnd(); ++it )
1588 allKeywords.append( QStringLiteral(
"%1: %2" ).arg( it.key(), it.value().join(
',' ) ) );
1590 const QString keywordString = allKeywords.join(
';' );
1591 GDALSetMetadataItem( outputDS.get(),
"KEYWORDS", keywordString.toLocal8Bit().constData(), nullptr );
1595 GDALSetProjection( outputDS.get(), map->
crs().
toWkt().toLocal8Bit().constData() );
1597 CPLSetConfigOption(
"GDAL_PDF_DPI",
nullptr );
1604 if ( items.count() == 1 )
1606 if (
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( items.at( 0 ) ) )
1608 QString name = layoutItem->displayName();
1610 if ( name.startsWith(
'<' ) && name.endsWith(
'>' ) )
1611 name = name.mid( 1, name.length() - 2 );
1615 else if ( items.count() > 1 )
1617 QStringList currentLayerItemTypes;
1618 for ( QGraphicsItem *item : items )
1620 if (
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
1624 if ( !currentLayerItemTypes.contains( itemType ) && !currentLayerItemTypes.contains( itemTypePlural ) )
1625 currentLayerItemTypes << itemType;
1626 else if ( currentLayerItemTypes.contains( itemType ) )
1628 currentLayerItemTypes.replace( currentLayerItemTypes.indexOf( itemType ), itemTypePlural );
1633 if ( !currentLayerItemTypes.contains( QObject::tr(
"Other" ) ) )
1634 currentLayerItemTypes.append( QObject::tr(
"Other" ) );
1637 return currentLayerItemTypes.join( QStringLiteral(
", " ) );
1639 return QObject::tr(
"Layer %1" ).arg( layerId );
1645 LayoutItemHider itemHider( items );
1650 unsigned int layerId = 1;
1652 itemHider.hideAll();
1653 const QList< QGraphicsItem * > itemsToIterate = itemHider.itemsToIterate();
1654 QList< QGraphicsItem * > currentLayerItems;
1655 for ( QGraphicsItem *item : itemsToIterate )
1659 bool canPlaceInExistingLayer =
false;
1666 switch ( prevItemBehavior )
1669 canPlaceInExistingLayer =
true;
1673 canPlaceInExistingLayer = prevType == -1 || prevType == layoutItem->
type();
1678 canPlaceInExistingLayer =
false;
1686 switch ( prevItemBehavior )
1690 canPlaceInExistingLayer = prevType == -1 || prevType == layoutItem->
type();
1695 canPlaceInExistingLayer =
false;
1703 canPlaceInExistingLayer =
false;
1708 canPlaceInExistingLayer =
false;
1712 prevType = layoutItem->
type();
1719 if ( canPlaceInExistingLayer )
1721 currentLayerItems << item;
1726 if ( !currentLayerItems.isEmpty() )
1730 ExportResult result = exportFunc( layerId, layerDetails );
1734 currentLayerItems.clear();
1737 itemHider.hideAll();
1742 int layoutItemLayerIdx = 0;
1744 mLayout->renderContext().setCurrentExportLayer( layoutItemLayerIdx );
1750 mLayout->renderContext().setCurrentExportLayer( layoutItemLayerIdx );
1754 ExportResult result = exportFunc( layerId, layerDetails );
1759 layoutItemLayerIdx++;
1763 mLayout->renderContext().setCurrentExportLayer( -1 );
1766 currentLayerItems.clear();
1770 currentLayerItems << item;
1774 if ( !currentLayerItems.isEmpty() )
1777 ExportResult result = exportFunc( layerId, layerDetails );
1792 return simplifyMethod;
1806 int pageNumber = map->
page();
1808 double pageY = page->pos().y();
1809 QSizeF pageSize = page->rect().size();
1810 QRectF pageRect( 0, pageY, pageSize.width(), pageSize.height() );
1826 double destinationHeight = exportRegion.height();
1827 double destinationWidth = exportRegion.width();
1829 QRectF mapItemSceneRect = map->mapRectToScene( map->rect() );
1834 double xRatio = mapExtent.
width() / mapItemSceneRect.width();
1835 double yRatio = mapExtent.
height() / mapItemSceneRect.height();
1837 double xCenter = mapExtent.
center().
x();
1838 double yCenter = mapExtent.
center().
y();
1841 QPointF mapItemPos = map->pos();
1843 mapItemPos.rx() -= exportRegion.left();
1844 mapItemPos.ry() -= exportRegion.top();
1846 double xmin = mapExtent.
xMinimum() - mapItemPos.x() * xRatio;
1847 double ymax = mapExtent.
yMaximum() + mapItemPos.y() * yRatio;
1848 QgsRectangle paperExtent( xmin, ymax - destinationHeight * yRatio, xmin + destinationWidth * xRatio, ymax );
1850 double X0 = paperExtent.
xMinimum();
1851 double Y0 = paperExtent.
yMinimum();
1854 dpi = mLayout->renderContext().dpi();
1856 int widthPx =
static_cast< int >( dpi * destinationWidth / 25.4 );
1857 int heightPx =
static_cast< int >( dpi * destinationHeight / 25.4 );
1859 double Ww = paperExtent.
width() / widthPx;
1860 double Hh = paperExtent.
height() / heightPx;
1869 s[5] = Y0 + paperExtent.
height();
1873 r[0] = std::cos( alpha );
1874 r[1] = -std::sin( alpha );
1875 r[2] = xCenter * ( 1 - std::cos( alpha ) ) + yCenter * std::sin( alpha );
1876 r[3] = std::sin( alpha );
1877 r[4] = std::cos( alpha );
1878 r[5] = - xCenter * std::sin( alpha ) + yCenter * ( 1 - std::cos( alpha ) );
1881 a = r[0] * s[0] + r[1] * s[3];
1882 b = r[0] * s[1] + r[1] * s[4];
1883 c = r[0] * s[2] + r[1] * s[5] + r[2];
1884 d = r[3] * s[0] + r[4] * s[3];
1885 e = r[3] * s[1] + r[4] * s[4];
1886 f = r[3] * s[2] + r[4] * s[5] + r[5];
1896 if ( mLayout->pageCollection()->pageCount() == 1 )
1899 bounds = mLayout->layoutBounds(
true );
1904 bounds = mLayout->pageItemBounds( page,
true );
1906 if ( bounds.width() <= 0 || bounds.height() <= 0 )
1914 bounds = bounds.adjusted( -settings.
cropMargins.
left() * pixelToLayoutUnits,
1926 int QgsLayoutExporter::firstPageToBeExported(
QgsLayout *layout )
1929 for (
int i = 0; i < pageCount; ++i )
1943 if ( details.
page == 0 )
1953 bool QgsLayoutExporter::saveImage(
const QImage &image,
const QString &imageFilename,
const QString &imageFormat,
QgsProject *projectForMetadata )
1955 QImageWriter w( imageFilename, imageFormat.toLocal8Bit().constData() );
1956 if ( imageFormat.compare( QLatin1String(
"tiff" ), Qt::CaseInsensitive ) == 0 || imageFormat.compare( QLatin1String(
"tif" ), Qt::CaseInsensitive ) == 0 )
1958 w.setCompression( 1 );
1960 if ( projectForMetadata )
1962 w.setText( QStringLiteral(
"Author" ), projectForMetadata->
metadata().
author() );
1964 w.setText( QStringLiteral(
"Creator" ), creator );
1965 w.setText( QStringLiteral(
"Producer" ), creator );
1966 w.setText( QStringLiteral(
"Subject" ), projectForMetadata->
metadata().
abstract() );
1967 w.setText( QStringLiteral(
"Created" ), projectForMetadata->
metadata().
creationDateTime().toString( Qt::ISODate ) );
1968 w.setText( QStringLiteral(
"Title" ), projectForMetadata->
metadata().
title() );
1971 QStringList allKeywords;
1972 for (
auto it = keywords.constBegin(); it != keywords.constEnd(); ++it )
1974 allKeywords.append( QStringLiteral(
"%1: %2" ).arg( it.key(), it.value().join(
',' ) ) );
1976 const QString keywordString = allKeywords.join(
';' );
1977 w.setText( QStringLiteral(
"Keywords" ), keywordString );
1979 return w.write( image );
1982 #endif // ! QT_NO_PRINTER bool cropToContents
Set to true if image should be cropped so only parts of the layout containing items are exported...
double right() const
Returns the right margin.
void setPredefinedScales(const QVector< qreal > &scales)
Sets the list of predefined scales to use with the layout.
void setDpi(double dpi)
Sets the dpi for outputting the layout.
QList< QgsAbstractGeoPdfExporter::GeoReferencedSection > georeferencedSections
List of georeferenced sections.
bool includeFeatures
true if feature vector information (such as attributes) should be exported.
A rectangle specified with double values.
void renderRegion(QPainter *painter, const QRectF ®ion) const
Renders a region from the layout to a painter.
static const QString QGIS_VERSION
Version string.
QString author
Metadata author tag.
QVector< qreal > predefinedScales() const
Returns the current list of predefined scales for use with the layout.
Contains settings relating to printing layouts.
Base class for graphical items within a QgsLayout.
bool simplifyGeometries
Indicates whether vector geometries should be simplified to avoid redundant extraneous detail...
int type() const override
Returns a unique graphics item type identifier.
QString mapLayerId
Associated map layer ID, or an empty string if this component layer is not associated with a map laye...
QgsMargins cropMargins
Crop to content margins, in layout units.
Unable to allocate memory required to export.
virtual bool endRender()=0
Ends the render, performing any required cleanup tasks.
Item must be placed in its own individual layer.
virtual void stopLayeredExport()
Stops a multi-layer export operation.
void setFlag(QgsLayoutRenderContext::Flag flag, bool on=true)
Enables or disables a particular rendering flag for the layout.
bool shouldExportPage(int page) const
Returns whether the specified page number should be included in exports of the layouts.
Contains the configuration for a single snap guide used by a layout.
Could not write to destination file, likely due to a lock held by another application.
Item contains multiple sublayers which must be individually exported.
ExportResult exportToImage(const QString &filePath, const QgsLayoutExporter::ImageExportSettings &settings)
Exports the layout to the filePath, using the specified export settings.
QgsLayoutMeasurement convert(QgsLayoutMeasurement measurement, QgsUnitTypes::LayoutUnit targetUnits) const
Converts a measurement from one unit to another.
The geometries can be simplified using the current map2pixel context state.
bool exportMetadata
Indicates whether SVG export should include RDF metadata generated from the layout's project's metada...
A class to represent a 2D point.
void setForceLocalOptimization(bool localOptimization)
Sets where the simplification executes, after fetch the geometries from provider, or when supported...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
void setProgress(double progress)
Sets the current progress for the feedback object.
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
QgsLayoutItemAbstractMetadata * itemMetadata(int type) const
Returns the metadata for the specified item type.
QgsAbstractMetadataBase::KeywordMap keywords
Metadata keyword map.
virtual bool next()=0
Iterates to next feature, returning false if no more features exist to iterate over.
#define Q_NOWARN_DEPRECATED_PUSH
Snap to a global grid based on the tolerance. Good for consistent results for incoming vertices...
QgsMargins cropMargins
Crop to content margins, in pixels.
bool forceVectorOutput
Set to true to force vector object exports, even when the resultant appearance will differ from the l...
bool rasterizeWholeImage
Set to true to force whole layout to be rasterized while exporting.
bool exportLabelsToSeparateLayers
Set to true to export labels to separate layers (grouped by map layer) in layered SVG exports...
QSizeF pageSizeMm
Page size, in millimeters.
QgsRenderContext::TextRenderFormat textRenderFormat
Text rendering format, which controls how text should be rendered in the export (e.g.
Item can only be placed on layers with other items of the same type, but multiple items of this type ...
QMap< QString, QString > customLayerTreeGroups
Optional map of map layer ID to custom logical layer tree group in created PDF file.
ExportResult print(QPrinter &printer, const QgsLayoutExporter::PrintExportSettings &settings)
Prints the layout to a printer, using the specified export settings.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO3200 extension format georeferencing should be used.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
bool georeferenceOutput(const QString &file, QgsLayoutItemMap *referenceMap=nullptr, const QRectF &exportRegion=QRectF(), double dpi=-1) const
Georeferences a file (image of PDF) exported from the layout.
QList< int > pages
List of specific pages to export, or an empty list to export all pages.
QString directory
Target folder.
QgsLayoutExporter(QgsLayout *layout)
Constructor for QgsLayoutExporter, for the specified layout.
QDateTime creationDateTime
Metadata creation datetime.
This class provides a method of storing points, consisting of an x and y coordinate, for use in QGIS layouts.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
void setTextRenderFormat(QgsRenderContext::TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
QImage renderRegionToImage(const QRectF ®ion, QSize imageSize=QSize(), double dpi=-1) const
Renders a region of the layout to an image.
QSizeF toQSizeF() const
Converts the layout size to a QSizeF.
Contains details of a control point used during georeferencing GeoPDF outputs.
Contains details of a page being exported by the class.
QString name
User-friendly name for the export layer.
QSize imageSize
Manual size in pixels for output image.
bool useOgcBestPracticeFormatGeoreferencing
true if OGC "best practice" format georeferencing should be used.
QString creator
Metadata creator tag.
static QgsLayoutItemRegistry * layoutItemRegistry()
Returns the application's layout item registry, used for layout item types.
QgsRectangle extent() const
Returns the current map extent.
Layout graphical items for displaying a map.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
bool useOgcBestPracticeFormatGeoreferencing
true if OGC "best practice" format georeferencing should be used.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
virtual QString generateFileName(const PageExportDetails &details) const
Generates the file name for a page during export.
bool exportAsLayers
Set to true to export as a layered SVG file.
An abstract base class for QgsLayout based classes which can be exported by QgsLayoutExporter.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout...
QgsProjectMetadata metadata
void computeWorldFileParameters(double &a, double &b, double &c, double &d, double &e, double &f, double dpi=-1) const
Compute world file parameters.
double bottom() const
Returns the bottom margin.
QgsLayoutRenderContext::Flags flags() const
Returns the current combination of flags used for rendering the layout.
Always render text using path objects (AKA outlines/curves).
double dpi() const
Returns the dpi for outputting the layout.
double width() const
Returns the width of the rectangle.
QList< QgsAbstractGeoPdfExporter::ControlPoint > controlPoints
List of control points corresponding to this georeferenced section.
QgsCoordinateReferenceSystem crs
Coordinate reference system for georeferenced section.
double y() const
Returns y coordinate of point.
bool rasterizeWholeImage
Set to true to force whole layout to be rasterized while exporting.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QgsLayoutRenderContext::Flags flags
Layout context flags, which control how the export will be created.
bool forceVectorOutput
Set to true to force vector object exports, even when the resultant appearance will differ from the l...
QString extension
File suffix/extension (without the leading '.')
QString subject
Metadata subject tag.
virtual QgsLayout * layout()=0
Returns the layout associated with the iterator.
double top() const
Returns the top margin.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
double x() const
Returns x coordinate of point.
QString baseName
Base part of filename (i.e. file name without extension or '.')
Could not create layered SVG file.
bool appendGeoreference
Indicates whether PDF export should append georeference data.
int page() const
Returns the page the item is currently on, with the first page returning 0.
ExportResult exportToSvg(const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings)
Exports the layout as an SVG to the filePath, using the specified export settings.
QStringList exportThemes
Optional list of map themes to export as GeoPDF layer groups.
void setSimplifyAlgorithm(SimplifyAlgorithm simplifyAlgorithm)
Sets the local simplification algorithm of the vector layer managed.
QgsLayoutRenderContext::Flags flags
Layout context flags, which control how the export will be created.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
TextRenderFormat
Options for rendering text.
QString group
Optional group name, for arranging layers in top-level groups.
Use antialiasing when drawing items.
virtual int count() const =0
Returns the number of features to iterate over.
QgsRenderContext::TextRenderFormat textRenderFormat() const
Returns the text render format, which dictates how text is rendered (e.g.
int pageCount() const
Returns the number of pages in the collection.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Contains details of a particular input component to be used during PDF composition.
Handles rendering and exports of layouts to various formats.
#define Q_NOWARN_DEPRECATED_POP
bool simplifyGeometries
Indicates whether vector geometries should be simplified to avoid redundant extraneous detail...
Contains settings relating to exporting layouts to PDF.
bool generateWorldFile
Set to true to generate an external world file alongside exported images.
Q_DECL_DEPRECATED int currentExportLayer() const
Returns the current item layer to draw while exporting.
double mapRotation(QgsLayoutObject::PropertyValueType valueType=QgsLayoutObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the layout item, in degrees clockwise.
virtual void startLayeredExport()
Starts a multi-layer export operation.
This class contains information how to simplify geometries fetched from a vector layer.
bool writeGeoPdf
true if GeoPDF files should be created, instead of normal PDF files.
Force output in vector format where possible, even if items require rasterization to keep their corre...
const QgsVectorSimplifyMethod & simplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
QgsRenderContext::TextRenderFormat textRenderFormat
Text rendering format, which controls how text should be rendered in the export (e.g.
const QgsLayoutMeasurementConverter & measurementConverter() const
Returns the layout measurement converter to be used in the layout.
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
Contains settings relating to exporting layouts to raster images.
QString name
User-friendly name for the generated PDF layer.
void setFlags(QgsLayoutRenderContext::Flags flags)
Sets the combination of flags that will be used for rendering the layout.
static ExportResult exportToPdfs(QgsAbstractLayoutIterator *iterator, const QString &baseFilePath, const QgsLayoutExporter::PdfExportSettings &settings, QString &error, QgsFeedback *feedback=nullptr)
Exports a layout iterator to multiple PDF files, with the specified export settings.
bool isCanceled() const
Tells whether the operation has been canceled already.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
Enable advanced effects such as blend modes.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO3200 extension format georeferencing should be used.
ExportResult exportToPdf(const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings)
Exports the layout as a PDF to the filePath, using the specified export settings. ...
Line string geometry type, with support for z-dimension and m-values.
QgsPolygon pageBoundsPolygon
Bounds of the georeferenced section on the page, in millimeters, as a free-form polygon.
QString title
Metadata title tag.
QString nameForLayerWithItems(const QList< QGraphicsItem * > items, unsigned int layerId)
static void fixEngineFlags(QPaintEngine *engine)
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
QString sourcePdfPath
File path to the (already created) PDF to use as the source for this component layer.
int page
Page number, where 0 = first page.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Item can be placed on a layer with any other item (default behavior)
bool exportMetadata
Indicates whether PDF export should include metadata generated from the layout's project's metadata...
bool includeGeoPdfFeatures
true if feature vector information (such as attributes) should be exported during GeoPDF exports...
QString producer
Metadata producer tag.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
std::unique_ptr< std::remove_pointer< GDALDatasetH >::type, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset.
QString mapLayerId
Associated map layer ID, or an empty string if this export layer is not associated with a map layer...
bool exportMetadata
Indicates whether image export should include metadata generated from the layout's project's metadata...
Could not start printing to destination device.
QImage renderPageToImage(int page, QSize imageSize=QSize(), double dpi=-1) const
Renders a full page to an image.
QgsPointXY center() const
Returns the center point of the rectangle.
virtual bool nextExportPart()
Moves to the next export part for a multi-layered export item, during a multi-layered export...
virtual QgsLayoutItem::ExportLayerDetail exportLayerDetails() const
Returns the details for the specified current export layer.
bool cropToContents
Set to true if image should be cropped so only parts of the layout containing items are exported...
QStringList exportThemes() const
Returns a list of map themes to use during the export.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
QgsLayoutRenderContext::Flags flags
Layout context flags, which control how the export will be created.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Interface for master layout type objects, such as print layouts and reports.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
virtual ExportLayerBehavior exportLayerBehavior() const
Returns the behavior of this item during exporting to layered exports (e.g.
Contains details of a particular export layer relating to a layout item.
Contains settings relating to exporting layouts to SVG.
virtual bool beginRender()=0
Called when rendering begins, before iteration commences.
double left() const
Returns the left margin.
void setSimplifyMethod(const QgsVectorSimplifyMethod &method)
Sets the simplification setting to use when rendering vector layers.
QgsLayout * layout() const
Returns the layout linked to this exporter.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
virtual QString filePath(const QString &baseFilePath, const QString &extension)=0
Returns the file path for the current feature, based on a specified base file path and extension...
double height() const
Returns the height of the rectangle.
Item representing the paper in a layout.
When rendering map items to multi-layered exports, render labels belonging to different layers into s...
QgsLayoutRenderContext::Flags flags
Layout context flags, which control how the export will be created.
void setThreshold(float threshold)
Sets the simplification threshold of the vector layer managed.
ExportResult
Result codes for exporting layouts.
void renderPage(QPainter *painter, int page) const
Renders a full page to a destination painter.
Error iterating over layout.