mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[FEATURE] Add possibility to export metadata when saving map canvas as PDF
This commit is contained in:
parent
a817a8e247
commit
f801d1716d
@ -10,6 +10,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsMapRendererTask : QgsTask
|
||||
{
|
||||
%Docstring
|
||||
@ -63,6 +64,11 @@ Adds ``decorations`` to be rendered on the map.
|
||||
void setSaveWorldFile( bool save );
|
||||
%Docstring
|
||||
Sets whether the image file will be georeferenced (embedded or via a world file).
|
||||
%End
|
||||
|
||||
void setExportMetadata( bool exportMetadata );
|
||||
%Docstring
|
||||
Sets whether metadata such as title and subject will be exported whenever possible.
|
||||
%End
|
||||
|
||||
virtual void cancel();
|
||||
|
@ -148,6 +148,7 @@ QgsMapSaveDialog::QgsMapSaveDialog( QWidget *parent, QgsMapCanvas *mapCanvas, co
|
||||
|
||||
case Image:
|
||||
{
|
||||
mExportMetadataCheckBox->hide();
|
||||
mGeoPDFGroupBox->hide();
|
||||
mAdvancedPdfSettings->hide();
|
||||
mTextExportLabel->hide();
|
||||
@ -307,6 +308,11 @@ bool QgsMapSaveDialog::saveWorldFile() const
|
||||
return mSaveWorldFile->isChecked();
|
||||
}
|
||||
|
||||
bool QgsMapSaveDialog::exportMetadata() const
|
||||
{
|
||||
return mExportMetadataCheckBox->isChecked();;
|
||||
}
|
||||
|
||||
bool QgsMapSaveDialog::saveAsRaster() const
|
||||
{
|
||||
return mSaveAsRaster->isChecked();
|
||||
@ -502,19 +508,20 @@ void QgsMapSaveDialog::onAccepted()
|
||||
ms.setTextRenderFormat( static_cast< QgsRenderContext::TextRenderFormat >( mTextRenderFormatComboBox->currentData().toInt() ) );
|
||||
|
||||
QgsAbstractGeoPdfExporter::ExportDetails geoPdfExportDetails;
|
||||
if ( mExportMetadataCheckBox->isChecked() )
|
||||
{
|
||||
// These details will be used on non-GeoPDF exports is the export metadata checkbox is checked
|
||||
geoPdfExportDetails.author = QgsProject::instance()->metadata().author();
|
||||
geoPdfExportDetails.producer = QStringLiteral( "QGIS %1" ).arg( Qgis::QGIS_VERSION );
|
||||
geoPdfExportDetails.creator = QStringLiteral( "QGIS %1" ).arg( Qgis::QGIS_VERSION );
|
||||
geoPdfExportDetails.creationDateTime = QDateTime::currentDateTime();
|
||||
geoPdfExportDetails.subject = QgsProject::instance()->metadata().abstract();
|
||||
geoPdfExportDetails.title = QgsProject::instance()->metadata().title();
|
||||
geoPdfExportDetails.keywords = QgsProject::instance()->metadata().keywords();
|
||||
}
|
||||
|
||||
if ( mGeoPDFGroupBox->isChecked() )
|
||||
{
|
||||
if ( mExportMetadataCheckBox->isChecked() )
|
||||
{
|
||||
geoPdfExportDetails.author = QgsProject::instance()->metadata().author();
|
||||
geoPdfExportDetails.producer = QStringLiteral( "QGIS %1" ).arg( Qgis::QGIS_VERSION );
|
||||
geoPdfExportDetails.creator = QStringLiteral( "QGIS %1" ).arg( Qgis::QGIS_VERSION );
|
||||
geoPdfExportDetails.creationDateTime = QDateTime::currentDateTime();
|
||||
geoPdfExportDetails.subject = QgsProject::instance()->metadata().abstract();
|
||||
geoPdfExportDetails.title = QgsProject::instance()->metadata().title();
|
||||
geoPdfExportDetails.keywords = QgsProject::instance()->metadata().keywords();
|
||||
}
|
||||
|
||||
if ( mGeoPdfFormatComboBox->currentIndex() == 0 )
|
||||
{
|
||||
geoPdfExportDetails.useIso32000ExtensionFormatGeoreferencing = true;
|
||||
@ -542,6 +549,11 @@ void QgsMapSaveDialog::onAccepted()
|
||||
|
||||
mapRendererTask->setSaveWorldFile( saveWorldFile() );
|
||||
|
||||
if ( exportMetadata() )
|
||||
{
|
||||
mapRendererTask->setExportMetadata( exportMetadata() );
|
||||
}
|
||||
|
||||
connect( mapRendererTask, &QgsMapRendererTask::renderingComplete, [ = ]
|
||||
{
|
||||
QgisApp::instance()->messageBar()->pushSuccess( tr( "Save as PDF" ), tr( "Successfully saved map to <a href=\"%1\">%2</a>" )
|
||||
|
@ -74,6 +74,9 @@ class APP_EXPORT QgsMapSaveDialog: public QDialog, private Ui::QgsMapSaveDialog
|
||||
//! returns whether the resulting image will be georeferenced (embedded or via world file)
|
||||
bool saveWorldFile() const;
|
||||
|
||||
//! returns whether metadata such as title and subject will be exported whenever possible
|
||||
bool exportMetadata() const;
|
||||
|
||||
//! returns whether the map will be rasterized
|
||||
bool saveAsRaster() const;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "qgsrenderedfeaturehandlerinterface.h"
|
||||
#include "qgsfeaturerequest.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#ifndef QT_NO_PRINTER
|
||||
@ -299,21 +300,60 @@ bool QgsMapRendererTask::run()
|
||||
pp.end();
|
||||
}
|
||||
|
||||
if ( mSaveWorldFile )
|
||||
if ( mSaveWorldFile || mExportMetadata )
|
||||
{
|
||||
CPLSetThreadLocalConfigOption( "GDAL_PDF_DPI", QString::number( mMapSettings.outputDpi() ).toLocal8Bit().constData() );
|
||||
gdal::dataset_unique_ptr outputDS( GDALOpen( mFileName.toLocal8Bit().constData(), GA_Update ) );
|
||||
if ( outputDS )
|
||||
{
|
||||
double a, b, c, d, e, f;
|
||||
QgsMapSettingsUtils::worldFileParameters( mMapSettings, a, b, c, d, e, f );
|
||||
c -= 0.5 * a;
|
||||
c -= 0.5 * b;
|
||||
f -= 0.5 * d;
|
||||
f -= 0.5 * e;
|
||||
double geoTransform[6] = { c, a, b, f, d, e };
|
||||
GDALSetGeoTransform( outputDS.get(), geoTransform );
|
||||
GDALSetProjection( outputDS.get(), mMapSettings.destinationCrs().toWkt().toLocal8Bit().constData() );
|
||||
if ( mSaveWorldFile )
|
||||
{
|
||||
double a, b, c, d, e, f;
|
||||
QgsMapSettingsUtils::worldFileParameters( mMapSettings, a, b, c, d, e, f );
|
||||
c -= 0.5 * a;
|
||||
c -= 0.5 * b;
|
||||
f -= 0.5 * d;
|
||||
f -= 0.5 * e;
|
||||
double geoTransform[6] = { c, a, b, f, d, e };
|
||||
GDALSetGeoTransform( outputDS.get(), geoTransform );
|
||||
GDALSetProjection( outputDS.get(), mMapSettings.destinationCrs().toWkt().toLocal8Bit().constData() );
|
||||
}
|
||||
|
||||
if ( mExportMetadata )
|
||||
{
|
||||
QString creationDateString;
|
||||
const QDateTime creationDateTime = mGeoPdfExportDetails.creationDateTime;
|
||||
if ( creationDateTime.isValid() )
|
||||
{
|
||||
creationDateString = QStringLiteral( "D:%1" ).arg( mGeoPdfExportDetails.creationDateTime.toString( QStringLiteral( "yyyyMMddHHmmss" ) ) );
|
||||
if ( creationDateTime.timeZone().isValid() )
|
||||
{
|
||||
int offsetFromUtc = creationDateTime.timeZone().offsetFromUtc( 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 );
|
||||
}
|
||||
}
|
||||
GDALSetMetadataItem( outputDS.get(), "CREATION_DATE", creationDateString.toLocal8Bit().constData(), nullptr );
|
||||
|
||||
GDALSetMetadataItem( outputDS.get(), "AUTHOR", mGeoPdfExportDetails.author.toLocal8Bit().constData(), nullptr );
|
||||
const QString creator = QStringLiteral( "QGIS %1" ).arg( Qgis::QGIS_VERSION );
|
||||
GDALSetMetadataItem( outputDS.get(), "CREATOR", creator.toLocal8Bit().constData(), nullptr );
|
||||
GDALSetMetadataItem( outputDS.get(), "PRODUCER", creator.toLocal8Bit().constData(), nullptr );
|
||||
GDALSetMetadataItem( outputDS.get(), "SUBJECT", mGeoPdfExportDetails.subject.toLocal8Bit().constData(), nullptr );
|
||||
GDALSetMetadataItem( outputDS.get(), "TITLE", mGeoPdfExportDetails.title.toLocal8Bit().constData(), nullptr );
|
||||
|
||||
const QgsAbstractMetadataBase::KeywordMap keywords = mGeoPdfExportDetails.keywords;
|
||||
QStringList allKeywords;
|
||||
for ( auto it = keywords.constBegin(); it != keywords.constEnd(); ++it )
|
||||
{
|
||||
allKeywords.append( QStringLiteral( "%1: %2" ).arg( it.key(), it.value().join( ',' ) ) );
|
||||
}
|
||||
const QString keywordString = allKeywords.join( ';' );
|
||||
GDALSetMetadataItem( outputDS.get(), "KEYWORDS", keywordString.toLocal8Bit().constData(), nullptr );
|
||||
}
|
||||
}
|
||||
CPLSetThreadLocalConfigOption( "GDAL_PDF_DPI", nullptr );
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#ifndef QT_NO_PRINTER
|
||||
#include <QPrinter>
|
||||
#endif
|
||||
|
||||
class QgsMapRendererCustomPainterJob;
|
||||
class QgsAbstractGeoPdfExporter;
|
||||
|
||||
@ -98,6 +99,11 @@ class CORE_EXPORT QgsMapRendererTask : public QgsTask
|
||||
*/
|
||||
void setSaveWorldFile( bool save ) { mSaveWorldFile = save; }
|
||||
|
||||
/**
|
||||
* Sets whether metadata such as title and subject will be exported whenever possible.
|
||||
*/
|
||||
void setExportMetadata( bool exportMetadata ) { mExportMetadata = exportMetadata; }
|
||||
|
||||
void cancel() override;
|
||||
|
||||
signals:
|
||||
@ -144,6 +150,7 @@ class CORE_EXPORT QgsMapRendererTask : public QgsTask
|
||||
QString mFileFormat;
|
||||
bool mForceRaster = false;
|
||||
bool mSaveWorldFile = false;
|
||||
bool mExportMetadata = false;
|
||||
bool mGeoPDF = false;
|
||||
QgsAbstractGeoPdfExporter::ExportDetails mGeoPdfExportDetails;
|
||||
|
||||
|
@ -33,6 +33,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mExportMetadataCheckBox">
|
||||
<property name="text">
|
||||
<string>Export RDF metadata (title, author, etc.)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsScaleWidget" name="mScaleWidget" native="true"/>
|
||||
</item>
|
||||
@ -46,7 +56,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="mGeoPDFGroupBox">
|
||||
<property name="title">
|
||||
<string>Create Geospatial PDF (GeoPDF)</string>
|
||||
@ -100,16 +110,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mExportMetadataCheckBox">
|
||||
<property name="text">
|
||||
<string>Export RDF metadata (title, author, etc.)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="mGeoPdfFormatComboBox"/>
|
||||
</item>
|
||||
@ -120,7 +120,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mExportGeoPdfFeaturesCheckBox">
|
||||
<property name="text">
|
||||
<string>Include vector feature information</string>
|
||||
@ -137,7 +137,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<item row="10" column="0" colspan="2">
|
||||
<widget class="QgsCollapsibleGroupBox" name="mAdvancedPdfSettings">
|
||||
<property name="title">
|
||||
<string>Advanced Settings</string>
|
||||
@ -329,7 +329,7 @@ Rasterizing the map is recommended when such effects are used.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="QLabel" name="mInfo">
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
Loading…
x
Reference in New Issue
Block a user