Skip to content

Commit

Permalink
Fix metadata export in GeoPDF
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 17, 2019
1 parent d7ad628 commit 0e10856
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 21 deletions.
78 changes: 57 additions & 21 deletions src/core/qgsabstractgeopdfexporter.cpp
Expand Up @@ -191,27 +191,63 @@ QString QgsAbstractGeoPdfExporter::createCompositionXml( const QList<ComponentLa

// 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 );
if ( !details.author.isEmpty() )
{
QDomElement author = doc.createElement( QStringLiteral( "Author" ) );
author.appendChild( doc.createTextNode( details.author ) );
metadata.appendChild( author );
}
if ( !details.producer.isEmpty() )
{
QDomElement producer = doc.createElement( QStringLiteral( "Producer" ) );
producer.appendChild( doc.createTextNode( details.producer ) );
metadata.appendChild( producer );
}
if ( !details.creator.isEmpty() )
{
QDomElement creator = doc.createElement( QStringLiteral( "Creator" ) );
creator.appendChild( doc.createTextNode( details.creator ) );
metadata.appendChild( creator );
}
if ( details.creationDateTime.isValid() )
{
QDomElement creationDate = doc.createElement( QStringLiteral( "CreationDate" ) );
QString creationDateString = QStringLiteral( "D:%1" ).arg( details.creationDateTime.toString( QStringLiteral( "yyyyMMddHHmmss" ) ) );
if ( details.creationDateTime.timeZone().isValid() )
{
int offsetFromUtc = details.creationDateTime.timeZone().offsetFromUtc( details.creationDateTime );
creationDateString += ( offsetFromUtc >= 0 ) ? '+' : '-';
offsetFromUtc = std::abs( offsetFromUtc );
int offsetHours = offsetFromUtc / 3600;
int offsetMins = ( offsetFromUtc % 3600 ) / 60;
creationDateString += QStringLiteral( "%1'%2'" ).arg( offsetHours ).arg( offsetMins );
}
creationDate.appendChild( doc.createTextNode( creationDateString ) );
metadata.appendChild( creationDate );
}
if ( !details.subject.isEmpty() )
{
QDomElement subject = doc.createElement( QStringLiteral( "Subject" ) );
subject.appendChild( doc.createTextNode( details.subject ) );
metadata.appendChild( subject );
}
if ( !details.title.isEmpty() )
{
QDomElement title = doc.createElement( QStringLiteral( "Title" ) );
title.appendChild( doc.createTextNode( details.title ) );
metadata.appendChild( title );
}
if ( !details.keywords.empty() )
{
QStringList allKeywords;
for ( auto it = details.keywords.constBegin(); it != details.keywords.constEnd(); ++it )
{
allKeywords.append( QStringLiteral( "%1: %2" ).arg( it.key(), it.value().join( ',' ) ) );
}
QDomElement keywords = doc.createElement( QStringLiteral( "Keywords" ) );
keywords.appendChild( doc.createTextNode( allKeywords.join( ';' ) ) );
metadata.appendChild( keywords );
}
compositionElem.appendChild( metadata );

// layertree
Expand Down
23 changes: 23 additions & 0 deletions src/core/qgsabstractgeopdfexporter.h
Expand Up @@ -20,7 +20,9 @@
#include <QList>
#include <QTemporaryDir>
#include <QMutex>
#include <QDateTime>
#include "qgsfeature.h"
#include "qgsabstractmetadatabase.h"

#define SIP_NO_FILE

Expand Down Expand Up @@ -136,6 +138,27 @@ class CORE_EXPORT QgsAbstractGeoPdfExporter
//! Output DPI
double dpi = 300;

//! Metadata author tag
QString author;

//! Metadata producer tag
QString producer;

//! Metadata creator tag
QString creator;

//! Metadata creation datetime
QDateTime creationDateTime;

//! Metadata subject tag
QString subject;

//! Metadata title tag
QString title;

//! Metadata keyword map
QgsAbstractMetadataBase::KeywordMap keywords;

};

/**
Expand Down
47 changes: 47 additions & 0 deletions tests/src/core/testqgsgeopdfexport.cpp
Expand Up @@ -56,6 +56,7 @@ class TestQgsGeoPdfExport : public QObject
void cleanup();// will be called after every testfunction.
void testCollectingFeatures();
void testComposition();
void testMetadata();

private:

Expand Down Expand Up @@ -264,5 +265,51 @@ void TestQgsGeoPdfExport::testComposition()

}

void TestQgsGeoPdfExport::testMetadata()
{
if ( !QgsAbstractGeoPdfExporter::geoPDFCreationAvailable() )
{
QSKIP( "This test requires GeoPDF creation abilities", SkipSingle );
}

TestGeoPdfExporter geoPdfExporter;
// test creation of the composition xml with metadata

QList< QgsAbstractGeoPdfExporter::ComponentLayerDetail > renderedLayers;
QgsAbstractGeoPdfExporter::ExportDetails details;
QString composition = geoPdfExporter.createCompositionXml( renderedLayers, details );
QgsDebugMsg( composition );
QDomDocument doc;
doc.setContent( composition );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Author" ) ).count(), 0 );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Producer" ) ).count(), 0 );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Creator" ) ).count(), 0 );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "CreationDate" ) ).count(), 0 );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Subject" ) ).count(), 0 );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Title" ) ).count(), 0 );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Keywords" ) ).count(), 0 );

// with metadata
details.author = QStringLiteral( "my author" );
details.producer = QStringLiteral( "my producer" );
details.creator = QStringLiteral( "my creator" );
details.creationDateTime = QDateTime( QDate( 2010, 3, 5 ), QTime( 12, 34 ), Qt::UTC );
details.subject = QStringLiteral( "my subject" );
details.title = QStringLiteral( "my title" );
details.keywords.insert( QStringLiteral( "k1" ), QStringList() << QStringLiteral( "v1" ) << QStringLiteral( "v2" ) );

composition = geoPdfExporter.createCompositionXml( renderedLayers, details );
QgsDebugMsg( composition );
doc.setContent( composition );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Author" ) ).at( 0 ).toElement().text(), QStringLiteral( "my author" ) );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Producer" ) ).at( 0 ).toElement().text(), QStringLiteral( "my producer" ) );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Creator" ) ).at( 0 ).toElement().text(), QStringLiteral( "my creator" ) );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "CreationDate" ) ).at( 0 ).toElement().text(), QStringLiteral( "D:20100305123400+0'0'" ) );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Subject" ) ).at( 0 ).toElement().text(), QStringLiteral( "my subject" ) );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Title" ) ).at( 0 ).toElement().text(), QStringLiteral( "my title" ) );
QCOMPARE( doc.elementsByTagName( QStringLiteral( "Keywords" ) ).at( 0 ).toElement().text(), QStringLiteral( "k1: v1,v2" ) );

}

QGSTEST_MAIN( TestQgsGeoPdfExport )
#include "testqgsgeopdfexport.moc"

0 comments on commit 0e10856

Please sign in to comment.