Skip to content

Commit

Permalink
Initial steps towards creation of GDAL composition XML
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 17, 2019
1 parent 3b5388b commit 522dacf
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 3 deletions.
99 changes: 98 additions & 1 deletion src/core/layout/qgslayoutgeopdfexporter.cpp
Expand Up @@ -23,6 +23,9 @@
#include "qgsvectorfilewriter.h"
#include <QMutex>
#include <QMutexLocker>
#include <QDomDocument>
#include <QDomElement>


class QgsGeoPdfRenderedFeatureHandler: public QgsRenderedFeatureHandlerInterface
{
Expand Down Expand Up @@ -126,7 +129,14 @@ bool QgsLayoutGeoPdfExporter::finalize()
}
}

return saveTemporaryLayers();
if ( !saveTemporaryLayers() )
return false;

const QString composition = createCompositionXml();
if ( composition.isEmpty() )
return false;

return true;
}

bool QgsLayoutGeoPdfExporter::saveTemporaryLayers()
Expand Down Expand Up @@ -159,3 +169,90 @@ bool QgsLayoutGeoPdfExporter::saveTemporaryLayers()
return true;
}

QString QgsLayoutGeoPdfExporter::createCompositionXml()
{
QDomDocument doc;

QDomElement compositionElem = doc.createElement( QStringLiteral( "PDFComposition" ) );

// metadata tags
QDomElement metadata = doc.createElement( QStringLiteral( "Metadata" ) );
QDomElement author = doc.createElement( QStringLiteral( "Author" ) );
author.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( author );
QDomElement producer = doc.createElement( QStringLiteral( "Producer" ) );
producer.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( producer );
QDomElement creator = doc.createElement( QStringLiteral( "Creator" ) );
creator.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( creator );
QDomElement creationDate = doc.createElement( QStringLiteral( "CreationDate" ) );
//creationDate.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( creationDate );
QDomElement subject = doc.createElement( QStringLiteral( "Subject" ) );
//subject.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( subject );
QDomElement title = doc.createElement( QStringLiteral( "Title" ) );
//title.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( title );
QDomElement keywords = doc.createElement( QStringLiteral( "Keywords" ) );
//keywords.appendChild( doc.createTextNode( QStringLiteral( "QGIS" ) ) );
metadata.appendChild( keywords );
compositionElem.appendChild( metadata );

// layertree
QDomElement layerTree = doc.createElement( QStringLiteral( "LayerTree" ) );
//layerTree.setAttribute( QStringLiteral("displayOnlyOnVisiblePages"), QStringLiteral("true"));
for ( auto it = mTemporaryFilePaths.constBegin(); it != mTemporaryFilePaths.constEnd(); ++it )
{
QDomElement layer = doc.createElement( QStringLiteral( "Layer" ) );
layer.setAttribute( QStringLiteral( "id" ), it.key() );
layer.setAttribute( QStringLiteral( "name" ), it.key() ); // TODO
layer.setAttribute( QStringLiteral( "initiallyVisible" ), QStringLiteral( "true" ) );
layerTree.appendChild( layer );
}
compositionElem.appendChild( layerTree );

// pages
QDomElement page = doc.createElement( QStringLiteral( "Page" ) );
QDomElement dpi = doc.createElement( QStringLiteral( "DPI" ) );
dpi.appendChild( doc.createTextNode( QStringLiteral( "300" ) ) );
page.appendChild( dpi );
QDomElement width = doc.createElement( QStringLiteral( "Width" ) );
width.appendChild( doc.createTextNode( QStringLiteral( "297" ) ) );
page.appendChild( width );
QDomElement height = doc.createElement( QStringLiteral( "Height" ) );
height.appendChild( doc.createTextNode( QStringLiteral( "210" ) ) );
page.appendChild( height );
// georeferencing - TODO

// content
QDomElement content = doc.createElement( QStringLiteral( "Content" ) );

for ( auto it = mTemporaryFilePaths.constBegin(); it != mTemporaryFilePaths.constEnd(); ++it )
{
QDomElement ifLayerOn = doc.createElement( QStringLiteral( "IfLayerOn" ) );
ifLayerOn.setAttribute( QStringLiteral( "layerId" ), it.key() );
QDomElement vectorDataset = doc.createElement( QStringLiteral( "Vector" ) );
vectorDataset.setAttribute( QStringLiteral( "dataset" ), it.value() );
vectorDataset.setAttribute( QStringLiteral( "visible" ), QStringLiteral( "true" ) ); // actually false!
QDomElement logicalStructure = doc.createElement( QStringLiteral( "LogicalStructure" ) );
logicalStructure.setAttribute( QStringLiteral( "displayLayerName" ), it.key() );
//logicalStructure.setAttribute( QStringLiteral( "fieldToDisplay" ), it.key() );
vectorDataset.appendChild( logicalStructure );
ifLayerOn.appendChild( vectorDataset );
content.appendChild( ifLayerOn );
}

page.appendChild( content );
compositionElem.appendChild( page );

doc.appendChild( compositionElem );

QString composition;
QTextStream stream( &composition );
doc.save( stream, -1 );

return composition;
}

2 changes: 2 additions & 0 deletions src/core/layout/qgslayoutgeopdfexporter.h
Expand Up @@ -113,6 +113,8 @@ class CORE_EXPORT QgsLayoutGeoPdfExporter

bool saveTemporaryLayers();

QString createCompositionXml();

friend class TestQgsLayoutGeoPdfExport;
};

Expand Down
13 changes: 11 additions & 2 deletions tests/src/core/testqgslayoutgeopdfexport.cpp
Expand Up @@ -193,16 +193,25 @@ void TestQgsLayoutGeoPdfExport::testCollectingFeatures()

// check layers were written
QCOMPARE( geoPdfExporter.mTemporaryFilePaths.count(), 2 );
std::unique_ptr< QgsVectorLayer > pointTemp = qgis::make_unique< QgsVectorLayer >( geoPdfExporter.mTemporaryFilePaths.value( pointsLayer->id(), QString() ) );
std::unique_ptr< QgsVectorLayer > pointTemp = qgis::make_unique< QgsVectorLayer >( geoPdfExporter.mTemporaryFilePaths.value( pointsLayer->id() ) );
QVERIFY( pointTemp->isValid() );
QCOMPARE( pointTemp->featureCount(), 32 );
QCOMPARE( pointTemp->wkbType(), QgsWkbTypes::MultiPolygon );
pointTemp.reset();
std::unique_ptr< QgsVectorLayer > lineTemp = qgis::make_unique< QgsVectorLayer >( geoPdfExporter.mTemporaryFilePaths.value( linesLayer->id(), QString() ) );
std::unique_ptr< QgsVectorLayer > lineTemp = qgis::make_unique< QgsVectorLayer >( geoPdfExporter.mTemporaryFilePaths.value( linesLayer->id() ) );
QVERIFY( lineTemp->isValid() );
QCOMPARE( lineTemp->featureCount(), 6 );
QCOMPARE( lineTemp->wkbType(), QgsWkbTypes::MultiLineString );
lineTemp.reset();

// test creation of the composition xml
QString composition = geoPdfExporter.createCompositionXml();
QgsDebugMsg( composition );
QVERIFY( composition.contains( QStringLiteral( "id=\"%1\"" ).arg( linesLayer->id() ) ) );
QVERIFY( composition.contains( QStringLiteral( "id=\"%1\"" ).arg( pointsLayer->id() ) ) );
QVERIFY( composition.contains( QStringLiteral( "dataset=\"%1\"" ).arg( geoPdfExporter.mTemporaryFilePaths.value( pointsLayer->id() ) ) ) );
QVERIFY( composition.contains( QStringLiteral( "dataset=\"%1\"" ).arg( geoPdfExporter.mTemporaryFilePaths.value( linesLayer->id() ) ) ) );

}

QGSTEST_MAIN( TestQgsLayoutGeoPdfExport )
Expand Down

0 comments on commit 522dacf

Please sign in to comment.