From c3309b9257bf87d0bb2d21392fb3030580242365 Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Tue, 12 Sep 2017 16:28:45 +0200 Subject: [PATCH] use the metadata API in the HTML viewer --- python/core/core_auto.sip | 1 + .../metadata/qgslayermetadataformatter.sip | 79 ++++++ src/core/CMakeLists.txt | 2 + .../metadata/qgslayermetadataformatter.cpp | 260 ++++++++++++++++++ src/core/metadata/qgslayermetadataformatter.h | 80 ++++++ src/core/qgsvectorlayer.cpp | 123 ++++----- src/core/raster/qgsrasterlayer.cpp | 118 ++++---- 7 files changed, 533 insertions(+), 130 deletions(-) create mode 100644 python/core/metadata/qgslayermetadataformatter.sip create mode 100644 src/core/metadata/qgslayermetadataformatter.cpp create mode 100644 src/core/metadata/qgslayermetadataformatter.h diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index 89862b429ba1..58e26ab6c568 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -168,6 +168,7 @@ %Include layout/qgslayoututils.sip %Include metadata/qgslayermetadata.sip %Include metadata/qgslayermetadatavalidator.sip +%Include metadata/qgslayermetadataformatter.sip %Include processing/qgsprocessing.sip %Include processing/qgsprocessingalgorithm.sip %Include processing/qgsprocessingcontext.sip diff --git a/python/core/metadata/qgslayermetadataformatter.sip b/python/core/metadata/qgslayermetadataformatter.sip new file mode 100644 index 000000000000..8d7f2f50b2f5 --- /dev/null +++ b/python/core/metadata/qgslayermetadataformatter.sip @@ -0,0 +1,79 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/metadata/qgslayermetadataformatter.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsLayerMetadataFormatter +{ +%Docstring + Class for metadata formatter. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgslayermetadataformatter.h" +%End + public: + + QgsLayerMetadataFormatter( const QgsLayerMetadata &metadata ); +%Docstring + Constructor for QgsLayerMetadataFormatter +%End + + QString accessSectionHtml() const; +%Docstring + Formats the "Access" section according to a ``metadata`` object. + This will return a HTML table. + :rtype: str +%End + + QString contactsSectionHtml() const; +%Docstring + Formats the "Contacts" section according to a ``metadata`` object. + This will return a HTML table. + :rtype: str +%End + + QString extentSectionHtml() const; +%Docstring + Formats the "Extents" section according to a ``metadata`` object. + This will return a HTML table. + :rtype: str +%End + + QString identificationSectionHtml() const; +%Docstring + Formats the "Identification" section according to a ``metadata`` object. + This will return a HTML table. + :rtype: str +%End + + QString historySectionHtml() const; +%Docstring + Formats the "History" section according to a ``metadata`` object. + This will return a HTML table. + :rtype: str +%End + + QString linksSectionHtml() const; +%Docstring + Formats the "Links" section according to a ``metadata`` object. + This will return a HTML table. + :rtype: str +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/metadata/qgslayermetadataformatter.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4715fddf53ea..08532516c615 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -73,6 +73,7 @@ SET(QGIS_CORE_SRCS metadata/qgslayermetadata.cpp metadata/qgslayermetadatavalidator.cpp + metadata/qgslayermetadataformatter.cpp auth/qgsauthcertutils.cpp auth/qgsauthconfig.cpp @@ -959,6 +960,7 @@ SET(QGIS_CORE_HDRS metadata/qgslayermetadata.h metadata/qgslayermetadatavalidator.h + metadata/qgslayermetadataformatter.h processing/qgsprocessing.h processing/qgsprocessingalgorithm.h diff --git a/src/core/metadata/qgslayermetadataformatter.cpp b/src/core/metadata/qgslayermetadataformatter.cpp new file mode 100644 index 000000000000..f031ddc66310 --- /dev/null +++ b/src/core/metadata/qgslayermetadataformatter.cpp @@ -0,0 +1,260 @@ +#include + +#include "qgslayermetadataformatter.h" +#include "qgslayermetadata.h" + + +QgsLayerMetadataFormatter::QgsLayerMetadataFormatter( const QgsLayerMetadata &metadata ) + : mMetadata( metadata ) +{ +} + +QString QgsLayerMetadataFormatter::accessSectionHtml() const +{ + QString myMetadata = QStringLiteral( "\n" ); + myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); + mMetadata.rights().join( QStringLiteral( "
" ) ) + QLatin1String( "\n" ); + myMetadata += QLatin1String( "
" ) + QObject::tr( "Fees" ) + QLatin1String( "" ) + mMetadata.fees() + QLatin1String( "
" ) + QObject::tr( "Licenses" ) + QLatin1String( "" ) + mMetadata.licenses().join( QStringLiteral( "
" ) ) + QLatin1String( "
" ) + QObject::tr( "Rights" ) + QLatin1String( "" ) + mMetadata.rights().join( QStringLiteral( "
" ) ) + QLatin1String( "
" ) + QObject::tr( "Constraints" ) + QLatin1String( "" ); + const QList &constraints = mMetadata.constraints(); + bool notFirstRow = false; + for ( const QgsLayerMetadata::Constraint &constraint : constraints ) + { + if ( notFirstRow ) + { + myMetadata += QLatin1String( "
" ); + } + myMetadata += QLatin1String( "" ) + constraint.type + QLatin1String( ": " ) + constraint.constraint; + notFirstRow = true; + } + myMetadata += QLatin1String( "
\n" ); + return myMetadata; +} + +QString QgsLayerMetadataFormatter::contactsSectionHtml() const +{ + const QList &contacts = mMetadata.contacts(); + QString myMetadata; + if ( contacts.isEmpty() ) + { + myMetadata += QLatin1String( "

" ) + QObject::tr( "No contact yet." ) + QLatin1String( "

" ); + } + else + { + myMetadata = QStringLiteral( "\n" ); + myMetadata += "\n"; + int i = 1; + for ( const QgsLayerMetadata::Contact &contact : contacts ) + { + QString rowClass; + if ( i % 2 ) + rowClass = QString( "class=\"odd-row\"" ); + myMetadata += "\n"; + i++; + } + myMetadata += QLatin1String( "
" + QObject::tr( "ID" ) + "" + QObject::tr( "Name" ) + "" + QObject::tr( "Position" ) + "" + QObject::tr( "Organization" ) + "" + QObject::tr( "Role" ) + "" + QObject::tr( "Email" ) + "" + QObject::tr( "Voice" ) + "" + QObject::tr( "Fax" ) + "" + QObject::tr( "Addresses" ) + "
" + QString::number( i ) + "" + contact.name + "" + contact.position + "" + contact.organization + "" + contact.role + "" + contact.email + "" + contact.voice + "" + contact.fax + ""; + bool notFirstRow = false; + for ( const QgsLayerMetadata::Address &oneAddress : contact.addresses ) + { + if ( notFirstRow ) + { + myMetadata += QLatin1String( "
\n" ); + } + if ( ! oneAddress.type.isEmpty() ) + { + myMetadata += oneAddress.type + QLatin1String( "
" ); + } + if ( ! oneAddress.address.isEmpty() ) + { + myMetadata += oneAddress.address + QLatin1String( "
" ); + } + if ( ! oneAddress.postalCode.isEmpty() ) + { + myMetadata += oneAddress.postalCode + QLatin1String( "
" ); + } + if ( ! oneAddress.city.isEmpty() ) + { + myMetadata += oneAddress.city + QLatin1String( "
" ); + } + if ( ! oneAddress.administrativeArea.isEmpty() ) + { + myMetadata += oneAddress.administrativeArea + QLatin1String( "
" ); + } + if ( ! oneAddress.country.isEmpty() ) + { + myMetadata += oneAddress.country; + } + notFirstRow = true; + } + myMetadata += "
\n" ); + } + return myMetadata; +} + +QString QgsLayerMetadataFormatter::extentSectionHtml() const +{ + QString myMetadata = QStringLiteral( "\n" ); + myMetadata += QStringLiteral( "\n" ); + + const QgsLayerMetadata::Extent extent = mMetadata.extent(); + myMetadata += QStringLiteral( "\n" ); + myMetadata += QStringLiteral( "\n" ); + myMetadata += QLatin1String( "
" ) + QObject::tr( "CRS" ) + QLatin1String( "" ) + mMetadata.crs().authid() + QLatin1String( " - " ); + myMetadata += mMetadata.crs().description() + QLatin1String( " - " ); + if ( mMetadata.crs().isGeographic() ) + myMetadata += QObject::tr( "Geographic" ); + else + myMetadata += QObject::tr( "Projected" ); + myMetadata += QLatin1String( "
" ) + QObject::tr( "Spatial Extent" ) + QLatin1String( "" ); + const QList< QgsLayerMetadata::SpatialExtent > spatialExtents = extent.spatialExtents(); + bool notFirstRow = false; + for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : spatialExtents ) + { + if ( notFirstRow ) + { + myMetadata += QLatin1String( "
\n" ); + } + myMetadata += QStringLiteral( "" ) + QObject::tr( "CRS" ) + QStringLiteral( ": " ) + spatialExtent.extentCrs.authid() + QLatin1String( " - " ); + myMetadata += spatialExtent.extentCrs.description() + QLatin1String( " - " ); + if ( spatialExtent.extentCrs.isGeographic() ) + myMetadata += QObject::tr( "Geographic" ); + else + myMetadata += QObject::tr( "Projected" ); + myMetadata += QStringLiteral( "
" ); + myMetadata += QStringLiteral( "" ) + QObject::tr( "X Minimum" ) + QStringLiteral( ": " ) + qgsDoubleToString( spatialExtent.bounds.xMinimum() ) + QStringLiteral( "
" ); + myMetadata += QStringLiteral( "" ) + QObject::tr( "Y Minimum" ) + QStringLiteral( ": " ) + qgsDoubleToString( spatialExtent.bounds.yMinimum() ) + QStringLiteral( "
" ); + myMetadata += QStringLiteral( "" ) + QObject::tr( "X Maximum" ) + QStringLiteral( ": " ) + qgsDoubleToString( spatialExtent.bounds.xMaximum() ) + QStringLiteral( "
" ); + myMetadata += QStringLiteral( "" ) + QObject::tr( "Y Maximum" ) + QStringLiteral( ": " ) + qgsDoubleToString( spatialExtent.bounds.yMaximum() ) + QStringLiteral( "
" ); + if ( spatialExtent.bounds.zMinimum() || spatialExtent.bounds.zMinimum() ) + { + myMetadata += QStringLiteral( "" ) + QObject::tr( "Z Minimum" ) + QStringLiteral( ": " ) + qgsDoubleToString( spatialExtent.bounds.zMinimum() ) + QStringLiteral( "
" ); + myMetadata += QStringLiteral( "" ) + QObject::tr( "Z Maximum" ) + QStringLiteral( ": " ) + qgsDoubleToString( spatialExtent.bounds.zMaximum() ); + } + notFirstRow = true; + } + myMetadata += QLatin1String( "
" ) + QObject::tr( "Temporal Extent" ) + QLatin1String( "" ); + const QList< QgsDateTimeRange > temporalExtents = extent.temporalExtents(); + notFirstRow = false; + for ( const QgsDateTimeRange &temporalExtent : temporalExtents ) + { + if ( notFirstRow ) + { + myMetadata += QLatin1String( "
\n" ); + } + if ( temporalExtent.isInstant() ) + { + myMetadata += QStringLiteral( "" ) + QObject::tr( "Instant" ) + QStringLiteral( ": " ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ); + } + else + { + myMetadata += QStringLiteral( "" ) + QObject::tr( "Start" ) + QStringLiteral( ": " ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) + QStringLiteral( "
\n" ); + myMetadata += QStringLiteral( "" ) + QObject::tr( "End" ) + QStringLiteral( ": " ) + temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ); + } + notFirstRow = true; + } + myMetadata += QLatin1String( "
\n" ); + return myMetadata; +} + +QString QgsLayerMetadataFormatter::identificationSectionHtml() const +{ + QString myMetadata = QStringLiteral( "\n" ); + + // Identifier + myMetadata += QStringLiteral( "\n" ); + + // Parent Identifier + myMetadata += QLatin1String( "\n" ); + + // Title + myMetadata += QLatin1String( "\n" ); + + // Type + myMetadata += QLatin1String( "\n" ); + + // Language + myMetadata += QLatin1String( "\n" ); + + // Abstract + myMetadata += QLatin1String( "\n" ); + + // Categories + myMetadata += QLatin1String( "\n" ); + + // Keywords + myMetadata += QLatin1String( "\n" ); // End of keywords row + myMetadata += QLatin1String( "
" ) + QObject::tr( "Identifier" ) + QLatin1String( "" ) + mMetadata.identifier() + QLatin1String( "
" ) + QObject::tr( "Parent Identifier" ) + QLatin1String( "" ) + mMetadata.parentIdentifier() + QLatin1String( "
" ) + QObject::tr( "Title" ) + QLatin1String( "" ) + mMetadata.title() + QLatin1String( "
" ) + QObject::tr( "Type" ) + QLatin1String( "" ) + mMetadata.type() + QLatin1String( "
" ) + QObject::tr( "Language" ) + QLatin1String( "" ) + mMetadata.language() + QLatin1String( "
" ) + QObject::tr( "Abstract" ) + QLatin1String( "" ) + mMetadata.abstract() + QLatin1String( "
" ) + QObject::tr( "Categories" ) + QLatin1String( "" ) + mMetadata.categories().join( QStringLiteral( ", " ) ) + QLatin1String( "
" ) + QObject::tr( "Keywords" ) + QLatin1String( "\n" ); + QMapIterator i( mMetadata.keywords() ); + if ( i.hasNext() ) + { + myMetadata += QStringLiteral( "\n" ); + myMetadata += "\n"; + int j = 1; + while ( i.hasNext() ) + { + i.next(); + QString rowClass; + if ( j % 2 ) + rowClass = QString( "class=\"odd-row\"" ); + myMetadata += "\n"; + j++; + } + myMetadata += QLatin1String( "
" + QObject::tr( "Vocabulary" ) + "" + QObject::tr( "Items" ) + "
" + i.key() + "" + i.value().join( QStringLiteral( ", " ) ) + "
\n" ); // End keywords table + } + myMetadata += QLatin1String( "
\n" ); // End identification table + return myMetadata; +} + +QString QgsLayerMetadataFormatter::historySectionHtml() const +{ + QString myMetadata; + const QStringList historyItems = mMetadata.history(); + if ( historyItems.isEmpty() ) + { + myMetadata += QLatin1String( "

" ) + QObject::tr( "No history yet." ) + QLatin1String( "

\n" ); + } + else + { + myMetadata = QStringLiteral( "\n" ); + myMetadata += "\n"; + int i = 1; + for ( const QString &history : historyItems ) + { + QString rowClass; + if ( i % 2 ) + rowClass = QString( "class=\"odd-row\"" ); + myMetadata += "\n"; + i++; + } + myMetadata += QLatin1String( "
" + QObject::tr( "ID" ) + "" + QObject::tr( "Action" ) + "
" + QString::number( i ) + "" + history + "
\n" ); + } + return myMetadata; +} + +QString QgsLayerMetadataFormatter::linksSectionHtml() const +{ + QString myMetadata; + const QList &links = mMetadata.links(); + if ( links.isEmpty() ) + { + myMetadata += QLatin1String( "

" ) + QObject::tr( "No links yet." ) + QLatin1String( "

\n" ); + } + else + { + myMetadata = QStringLiteral( "\n" ); + myMetadata += "\n"; + int i = 1; + for ( const QgsLayerMetadata::Link &link : links ) + { + QString rowClass; + if ( i % 2 ) + rowClass = QString( "class=\"odd-row\"" ); + myMetadata += "\n"; + i++; + } + myMetadata += QLatin1String( "
" + QObject::tr( "ID" ) + "" + QObject::tr( "Name" ) + "" + QObject::tr( "Type" ) + "" + QObject::tr( "URL" ) + "" + QObject::tr( "Description" ) + "" + QObject::tr( "Format" ) + "" + QObject::tr( "MIME Type" ) + "" + QObject::tr( "Size" ) + "
" + QString::number( i ) + "" + link.name + "" + link.type + "" + link.url + "" + link.description + "" + link.format + "" + link.mimeType + "" + link.size + "
\n" ); + } + return myMetadata; +} diff --git a/src/core/metadata/qgslayermetadataformatter.h b/src/core/metadata/qgslayermetadataformatter.h new file mode 100644 index 000000000000..558899bc2024 --- /dev/null +++ b/src/core/metadata/qgslayermetadataformatter.h @@ -0,0 +1,80 @@ +/*************************************************************************** + qgslayermetadataformatter.h + --------------------------- + begin : September 2017 + copyright : (C) 2017 by Etienne Trimaille + email : etienne dot trimaille at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSLAYERMETADATAFORMATTER_H +#define QGSLAYERMETADATAFORMATTER_H + +#include "qgis.h" +#include "qgis_core.h" +#include "qgslayermetadata.h" + +/** + * \ingroup core + * \class QgsLayerMetadataFormatter + * \brief Class for metadata formatter. + * \since QGIS 3.0 + */ +class CORE_EXPORT QgsLayerMetadataFormatter +{ + public: + + /** + * Constructor for QgsLayerMetadataFormatter + */ + QgsLayerMetadataFormatter( const QgsLayerMetadata &metadata ); + + /** + * Formats the "Access" section according to a \a metadata object. + * This will return a HTML table. + */ + QString accessSectionHtml() const; + + /** + * Formats the "Contacts" section according to a \a metadata object. + * This will return a HTML table. + */ + QString contactsSectionHtml() const; + + /** + * Formats the "Extents" section according to a \a metadata object. + * This will return a HTML table. + */ + QString extentSectionHtml() const; + + /** + * Formats the "Identification" section according to a \a metadata object. + * This will return a HTML table. + */ + QString identificationSectionHtml() const; + + /** + * Formats the "History" section according to a \a metadata object. + * This will return a HTML table. + */ + QString historySectionHtml() const; + + /** + * Formats the "Links" section according to a \a metadata object. + * This will return a HTML table. + */ + QString linksSectionHtml() const; + + private: + QgsLayerMetadata mMetadata; +}; + +#endif // QGSLAYERMETADATAFORMATTER_H diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index 2caea23bcf71..c73c1722e8d6 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -51,6 +51,7 @@ #include "qgsfeaturerequest.h" #include "qgsfields.h" #include "qgsgeometry.h" +#include "qgslayermetadataformatter.h" #include "qgslogger.h" #include "qgsmaplayerlegend.h" #include "qgsmaptopixel.h" @@ -3907,52 +3908,35 @@ void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings &s ) QString QgsVectorLayer::htmlMetadata() const { + QgsLayerMetadataFormatter htmlFormatter( metadata() ); QString myMetadata = QStringLiteral( "\n\n" ); - // Identification section - myMetadata += QLatin1String( "

" ) % tr( "Identification" ) % QLatin1String( "

\n
\n\n" ); + // identification section + myMetadata += QLatin1String( "

" ) + tr( "Identification" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.identificationSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - // ID - myMetadata += QLatin1String( "\n" ); + // Begin Provider section + myMetadata += QLatin1String( "

" ) + tr( "Information from provider" ) + QLatin1String( "

\n
\n" ); + myMetadata += QLatin1String( "
" ) % tr( "ID" ) % QLatin1String( "" ) % id() % QLatin1String( "
\n" ); // original name - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // name - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); - // short - myMetadata += QLatin1String( "\n" ); - - // title - myMetadata += QLatin1String( "\n" ); - - // abstract - myMetadata += QLatin1String( "\n" ); - - // keywords - myMetadata += QLatin1String( "\n" ); - - // lang, waiting for the proper metadata implementation QEP #91 Work package 2 - // myMetadata += QLatin1String( "\n" ); - - // comment - myMetadata += QLatin1String( "\n" ); - - // date, waiting for the proper metadata implementation QEP #91 Work package 2 - // myMetadata += QLatin1String( "\n" ); + // data source + myMetadata += QLatin1String( "\n" ); // storage type - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); - // data source - myMetadata += QLatin1String( "\n" ); + // comment + myMetadata += QLatin1String( "\n" ); // encoding - myMetadata += QLatin1String( "\n" ); - - // Section spatial - myMetadata += QLatin1String( "
" ) % tr( "Original" ) % QLatin1String( "" ) % originalName() % QLatin1String( "
" ) + tr( "Original" ) + QLatin1String( "" ) + originalName() + QLatin1String( "
" ) % tr( "Name" ) % QLatin1String( "" ) % name() % QLatin1String( "
" ) + tr( "Name" ) + QLatin1String( "" ) + name() + QLatin1String( "
" ) % tr( "Short" ) % QLatin1String( "" ) % shortName() % QLatin1String( "
" ) % tr( "Title" ) % QLatin1String( "" ) % title() % QLatin1String( "
" ) % tr( "Abstract" ) % QLatin1String( "" ) % abstract() % QLatin1String( "
" ) % tr( "Keywords" ) % QLatin1String( "" ) % keywordList() % QLatin1String( "
" ) % tr( "Language" ) % QLatin1String( "en-CA
" ) % tr( "Comment" ) % QLatin1String( "" ) % dataComment() % QLatin1String( "
" ) % tr( "Date" ) % QLatin1String( "28/03/17
" ) + tr( "Source" ) + QLatin1String( "" ) + publicSource() + QLatin1String( "
" ) % tr( "Storage" ) % QLatin1String( "" ) % storageType() % QLatin1String( "
" ) + tr( "Storage" ) + QLatin1String( "" ) + storageType() + QLatin1String( "
" ) % tr( "Source" ) % QLatin1String( "" ) % publicSource() % QLatin1String( "
" ) + tr( "Comment" ) + QLatin1String( "" ) + dataComment() + QLatin1String( "
" ) % tr( "Encoding" ) % QLatin1String( "" ) % dataProvider()->encoding() % QLatin1String( "
\n

" ) % tr( "Spatial" ) % QLatin1String( "

\n
\n\n" ); + myMetadata += QLatin1String( "\n" ); // geom type QgsWkbTypes::GeometryType type = geometryType(); @@ -3964,12 +3948,12 @@ QString QgsVectorLayer::htmlMetadata() const { QString typeString( QStringLiteral( "%1 (%2)" ).arg( QgsWkbTypes::geometryDisplayString( geometryType() ), QgsWkbTypes::displayString( wkbType() ) ) ); - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); } // EPSG - myMetadata += QLatin1String( "\n" ); // Extent - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // unit - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); - // max scale - // myMetadata += QLatin1String( "\n" ); + // feature count + myMetadata += QLatin1String( "\n" ); - // min scale - // myMetadata += QLatin1String( "\n" ); + // End Provider section + myMetadata += QLatin1String( "
" ) + tr( "Encoding" ) + QLatin1String( "" ) + dataProvider()->encoding() + QLatin1String( "
" ) % tr( "Geometry" ) % QLatin1String( "" ) % typeString % QLatin1String( "
" ) + tr( "Geometry" ) + QLatin1String( "" ) + typeString + QLatin1String( "
" ) % tr( "CRS" ) % QLatin1String( "" ) % crs().authid() % QLatin1String( " - " ); - myMetadata += crs().description() % QLatin1String( " - " ); + myMetadata += QLatin1String( "
" ) + tr( "CRS" ) + QLatin1String( "" ) + crs().authid() + QLatin1String( " - " ); + myMetadata += crs().description() + QLatin1String( " - " ); if ( crs().isGeographic() ) myMetadata += tr( "Geographic" ); else @@ -3977,31 +3961,38 @@ QString QgsVectorLayer::htmlMetadata() const myMetadata += QLatin1String( "
" ) % tr( "Extent" ) % QLatin1String( "" ) % extent().toString() % QLatin1String( "
" ) + tr( "Extent" ) + QLatin1String( "" ) + extent().toString() + QLatin1String( "
" ) % tr( "Unit" ) % QLatin1String( "" ) % QgsUnitTypes::toString( crs().mapUnits() ) % QLatin1String( "
" ) + tr( "Unit" ) + QLatin1String( "" ) + QgsUnitTypes::toString( crs().mapUnits() ) + QLatin1String( "
" ) % tr( "Max scale" ) % QLatin1String( "" ) % QString::number( maximumScale() ) % QLatin1String( "
" ) + tr( "Feature count" ) + QLatin1String( "" ) + QString::number( featureCount() ) + QLatin1String( "
" ) % tr( "Min scale" ) % QLatin1String( "" ) % QString::number( minimumScale() ) % QLatin1String( "
\n

" ); - // feature count - myMetadata += QLatin1String( "" ) % tr( "Feature count" ) % QLatin1String( "" ) % QString::number( featureCount() ) % QLatin1String( "\n" ); + // extent section + myMetadata += QLatin1String( "

" ) + tr( "Extent" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.extentSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); + + // Start the Access section + myMetadata += QLatin1String( "

" ) + tr( "Access" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.accessSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); // Fields section - myMetadata += QLatin1String( "\n

" ) % tr( "Fields" ) % QLatin1String( "

\n
\n\n" ); + myMetadata += QLatin1String( "

" ) + tr( "Fields" ) + QLatin1String( "

\n
\n
\n" ); // primary key QgsAttributeList pkAttrList = pkAttributeList(); if ( !pkAttrList.isEmpty() ) { - myMetadata += QLatin1String( "\n" ); } @@ -4009,10 +4000,10 @@ QString QgsVectorLayer::htmlMetadata() const const QgsFields &myFields = pendingFields(); // count fields - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); myMetadata += "
" ) % tr( "Primary key attributes" ) % QLatin1String( "" ); + myMetadata += QLatin1String( "
" ) + tr( "Primary key attributes" ) + QLatin1String( "" ); Q_FOREACH ( int idx, pkAttrList ) { - myMetadata += fields().at( idx ).name() % ' '; + myMetadata += fields().at( idx ).name() + ' '; } myMetadata += QLatin1String( "
" ) % tr( "Count" ) % QLatin1String( "" ) % QString::number( myFields.size() ) % QLatin1String( "
" ) + tr( "Count" ) + QLatin1String( "" ) + QString::number( myFields.size() ) + QLatin1String( "
\n
\n"; - myMetadata += "\n"; + myMetadata += "\n"; for ( int i = 0; i < myFields.size(); ++i ) { @@ -4020,30 +4011,28 @@ QString QgsVectorLayer::htmlMetadata() const QString rowClass = QString( "" ); if ( i % 2 ) rowClass = QString( "class=\"odd-row\"" ); - myMetadata += "\n"; + myMetadata += "\n"; } - //close field list and start references - myMetadata += QLatin1String( "
" % tr( "Field" ) % "" % tr( "Type" ) % "" % tr( "Length" ) % "" % tr( "Precision" ) % "" % tr( "Comment" ) % "
" + tr( "Field" ) + "" + tr( "Type" ) + "" + tr( "Length" ) + "" + tr( "Precision" ) + "" + tr( "Comment" ) + "
" % myField.name() % "" % myField.typeName() % "" % QString::number( myField.length() ) % "" % QString::number( myField.precision() ) % "" % myField.comment() % "
" + myField.name() + "" + myField.typeName() + "" + QString::number( myField.length() ) + "" + QString::number( myField.precision() ) + "" + myField.comment() + "
\n

" ) % tr( "References" ) % QLatin1String( "

\n
\n\n" ); - - // data URL - myMetadata += QLatin1String( "\n" ); - myMetadata += QLatin1String( "\n" ); + //close field list + myMetadata += QLatin1String( "
" ) % tr( "Data URL" ) % QLatin1String( "" ) % dataUrl() % QLatin1String( "
" ) % tr( "Data Format" ) % QLatin1String( "" ) % dataUrlFormat() % QLatin1String( "
\n

" ); - // attribution - myMetadata += QLatin1String( "" ) % tr( "Attribution" ) % QLatin1String( "" ) % attribution() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Attribution URL" ) % QLatin1String( "" ) % attributionUrl() % QLatin1String( "\n" ); + // Start the contacts section + myMetadata += QLatin1String( "

" ) + tr( "Contacts" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.contactsSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - // metadata URL - myMetadata += QLatin1String( "" ) % tr( "Metadata URL" ) % QLatin1String( "" ) % metadataUrl() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Metadata Type" ) % QLatin1String( "" ) % metadataUrlType() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Metadata Format" ) % QLatin1String( "" ) % metadataUrlFormat() % QLatin1String( "\n" ); + // Start the links section + myMetadata += QLatin1String( "

" ) + tr( "Links" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.linksSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - // legend URL - myMetadata += QLatin1String( "" ) % tr( "Legend URL" ) % QLatin1String( "" ) % legendUrl() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Legend Format" ) % QLatin1String( "" ) % legendUrlFormat() % QLatin1String( "\n" ); + // Start the history section + myMetadata += QLatin1String( "

" ) + tr( "History" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.historySectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - myMetadata += QStringLiteral( "\n\n\n" ); + myMetadata += QStringLiteral( "\n\n\n" ); return myMetadata; } diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp index 814b27a8ac23..5b7292df6b01 100644 --- a/src/core/raster/qgsrasterlayer.cpp +++ b/src/core/raster/qgsrasterlayer.cpp @@ -21,6 +21,7 @@ email : tim at linfiniti.com #include "qgscoordinatetransform.h" #include "qgsdatasourceuri.h" #include "qgshuesaturationfilter.h" +#include "qgslayermetadataformatter.h" #include "qgslogger.h" #include "qgsmaplayerlegend.h" #include "qgsmaptopixel.h" @@ -303,53 +304,33 @@ QgsLegendColorList QgsRasterLayer::legendSymbologyItems() const QString QgsRasterLayer::htmlMetadata() const { + QgsLayerMetadataFormatter htmlFormatter( metadata() ); QString myMetadata = QStringLiteral( "\n\n" ); // Identification section - myMetadata += QLatin1String( "

" ) % tr( "Identification" ) % QLatin1String( "

\n
\n\n" ); + myMetadata += QLatin1String( "

" ) + tr( "Identification" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.identificationSectionHtml(); + myMetadata += QLatin1String( "

\n" ); - // ID - myMetadata += QLatin1String( "\n" ); + // Begin Provider section + myMetadata += QLatin1String( "

" ) + tr( "Information from provider" ) + QLatin1String( "

\n
\n" ); + myMetadata += QLatin1String( "
" ) % tr( "ID" ) % QLatin1String( "" ) % id() % QLatin1String( "
\n" ); // original name - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // name - myMetadata += QLatin1String( "\n" ); - - // short - myMetadata += QLatin1String( "\n" ); - - // title - myMetadata += QLatin1String( "\n" ); - - // abstract - myMetadata += QLatin1String( "\n" ); - - // keywords - myMetadata += QLatin1String( "\n" ); - - // lang, waiting for the proper metadata implementation QEP #91 Work package 2 - // myMetadata += QLatin1String( "\n" ); - - // comment, not existing for rasters for now - // myMetadata += QLatin1String( "\n" ); - - // date, waiting for the proper metadata implementation QEP #91 Work package 2 - // myMetadata += QLatin1String( "\n" ); - - // storage type - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // data source - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); - // Section spatial - myMetadata += QLatin1String( "
" ) % tr( "Original" ) % QLatin1String( "" ) % originalName() % QLatin1String( "
" ) + tr( "Original" ) + QLatin1String( "" ) + originalName() + QLatin1String( "
" ) % tr( "Name" ) % QLatin1String( "" ) % name() % QLatin1String( "
" ) % tr( "Short" ) % QLatin1String( "" ) % shortName() % QLatin1String( "
" ) % tr( "Title" ) % QLatin1String( "" ) % title() % QLatin1String( "
" ) % tr( "Abstract" ) % QLatin1String( "" ) % abstract() % QLatin1String( "
" ) % tr( "Keywords" ) % QLatin1String( "" ) % keywordList() % QLatin1String( "
" ) % tr( "Language" ) % QLatin1String( "en-CA
" ) % tr( "Comment" ) % QLatin1String( "" ) % dataComment() % QLatin1String( "
" ) % tr( "Date" ) % QLatin1String( "28/03/17
" ) % tr( "Provider" ) % QLatin1String( "" ) % providerType() % QLatin1String( "
" ) + tr( "Name" ) + QLatin1String( "" ) + name() + QLatin1String( "
" ) % tr( "Source" ) % QLatin1String( "" ) % publicSource() % QLatin1String( "
" ) + tr( "Source" ) + QLatin1String( "" ) + publicSource() + QLatin1String( "
\n

" ) % tr( "Spatial" ) % QLatin1String( "

\n
\n\n" ); + // storage type + myMetadata += QLatin1String( "\n" ); // EPSG - myMetadata += QLatin1String( "\n" ); // Extent - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // unit - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // Raster Width - myMetadata += QLatin1String( "\n" ); // Raster height - myMetadata += QLatin1String( "\n" ); // Data type - myMetadata += QLatin1String( "\n" ); + // End Provider section + myMetadata += QLatin1String( "
" ) + tr( "Provider" ) + QLatin1String( "" ) + providerType() + QLatin1String( "
" ) % tr( "CRS" ) % QLatin1String( "" ) % crs().authid() % QLatin1String( " - " ); - myMetadata += crs().description() % QLatin1String( " - " ); + myMetadata += QLatin1String( "
" ) + tr( "CRS" ) + QLatin1String( "" ) + crs().authid() + QLatin1String( " - " ); + myMetadata += crs().description() + QLatin1String( " - " ); if ( crs().isGeographic() ) myMetadata += tr( "Geographic" ); else @@ -357,13 +338,13 @@ QString QgsRasterLayer::htmlMetadata() const myMetadata += QLatin1String( "
" ) % tr( "Extent" ) % QLatin1String( "" ) % extent().toString() % QLatin1String( "
" ) + tr( "Extent" ) + QLatin1String( "" ) + extent().toString() + QLatin1String( "
" ) % tr( "Unit" ) % QLatin1String( "" ) % QgsUnitTypes::toString( crs().mapUnits() ) % QLatin1String( "
" ) + tr( "Unit" ) + QLatin1String( "" ) + QgsUnitTypes::toString( crs().mapUnits() ) + QLatin1String( "
" ) % tr( "Width" ) % QLatin1String( "" ); + myMetadata += QLatin1String( "
" ) + tr( "Width" ) + QLatin1String( "" ); if ( dataProvider()->capabilities() & QgsRasterDataProvider::Size ) myMetadata += QString::number( width() ); else @@ -371,7 +352,7 @@ QString QgsRasterLayer::htmlMetadata() const myMetadata += QLatin1String( "
" ) % tr( "Height" ) % QLatin1String( "" ); + myMetadata += QLatin1String( "
" ) + tr( "Height" ) + QLatin1String( "" ); if ( dataProvider()->capabilities() & QgsRasterDataProvider::Size ) myMetadata += QString::number( height() ); else @@ -379,7 +360,7 @@ QString QgsRasterLayer::htmlMetadata() const myMetadata += QLatin1String( "
" ) % tr( "Data type" ) % QLatin1String( "" ); + myMetadata += QLatin1String( "
" ) + tr( "Data type" ) + QLatin1String( "" ); // Just use the first band switch ( mDataProvider->sourceDataType( 1 ) ) { @@ -421,15 +402,28 @@ QString QgsRasterLayer::htmlMetadata() const } myMetadata += QLatin1String( "
\n

" ); + + // extent section + myMetadata += QLatin1String( "

" ) + tr( "Extent" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.extentSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); + + // Start the Access section + myMetadata += QLatin1String( "

" ) + tr( "Access" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.accessSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); + // Bands section - myMetadata += QLatin1String( "\n

" ) % tr( "Bands" ) % QLatin1String( "

\n
\n\n" ); + myMetadata += QLatin1String( "
\n

" ) + tr( "Bands" ) + QLatin1String( "

\n
\n\n" ); // Band count - myMetadata += QLatin1String( "\n" ); + myMetadata += QLatin1String( "\n" ); // Band table myMetadata += "
" ) % tr( "Band count" ) % QLatin1String( "" ) % QString::number( bandCount() ) % QLatin1String( "
" ) + tr( "Band count" ) + QLatin1String( "" ) + QString::number( bandCount() ) + QLatin1String( "
\n
\n"; - myMetadata += "\n"; + myMetadata += "\n"; QgsRasterDataProvider *provider = const_cast< QgsRasterDataProvider * >( mDataProvider ); for ( int i = 1; i <= bandCount(); i++ ) @@ -437,7 +431,7 @@ QString QgsRasterLayer::htmlMetadata() const QString rowClass = QString( "" ); if ( i % 2 ) rowClass = QString( "class=\"odd-row\"" ); - myMetadata += ""; - myMetadata += ""; + myMetadata += ""; + myMetadata += ""; } else { - myMetadata += ""; + myMetadata += ""; } myMetadata += "\n"; } - //close previous bands table and start references - myMetadata += QLatin1String( "
" % tr( "Number" ) % "" % tr( "Band" ) % "" % tr( "No-Data" ) % "" % tr( "Min" ) % "" % tr( "Max" ) % "
" + tr( "Number" ) + "" + tr( "Band" ) + "" + tr( "No-Data" ) + "" + tr( "Min" ) + "" + tr( "Max" ) + "
" % QString::number( i ) % "" % bandName( i ) % ""; + myMetadata += "
" + QString::number( i ) + "" + bandName( i ) + ""; if ( dataProvider()->sourceHasNoDataValue( i ) ) myMetadata += QString::number( dataProvider()->sourceNoDataValue( i ) ); @@ -448,38 +442,36 @@ QString QgsRasterLayer::htmlMetadata() const if ( provider->hasStatistics( i ) ) { QgsRasterBandStats myRasterBandStats = provider->bandStatistics( i ); - myMetadata += "" % QString::number( myRasterBandStats.minimumValue, 'f', 10 ) % "" % QString::number( myRasterBandStats.maximumValue, 'f', 10 ) % "" + QString::number( myRasterBandStats.minimumValue, 'f', 10 ) + "" + QString::number( myRasterBandStats.maximumValue, 'f', 10 ) + "" % tr( "n/a" ) % "" % tr( "n/a" ) % "" + tr( "n/a" ) + "" + tr( "n/a" ) + "
\n

" ) % tr( "References" ) % QLatin1String( "

\n
\n\n" ); - - // data URL - myMetadata += QLatin1String( "\n" ); - myMetadata += QLatin1String( "\n" ); + //close previous bands table + myMetadata += QLatin1String( "
" ) % tr( "Data URL" ) % QLatin1String( "" ) % dataUrl() % QLatin1String( "
" ) % tr( "Data Format" ) % QLatin1String( "" ) % dataUrlFormat() % QLatin1String( "
\n

" ); - // attribution - myMetadata += QLatin1String( "" ) % tr( "Attribution" ) % QLatin1String( "" ) % attribution() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Attribution URL" ) % QLatin1String( "" ) % attributionUrl() % QLatin1String( "\n" ); + // Start the contacts section + myMetadata += QLatin1String( "

" ) + tr( "Contacts" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.contactsSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - // metadata URL - myMetadata += QLatin1String( "" ) % tr( "Metadata URL" ) % QLatin1String( "" ) % metadataUrl() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Metadata Type" ) % QLatin1String( "" ) % metadataUrlType() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Metadata Format" ) % QLatin1String( "" ) % metadataUrlFormat() % QLatin1String( "\n" ); + // Start the links section + myMetadata += QLatin1String( "

" ) + tr( "References" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.linksSectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - // legend URL - myMetadata += QLatin1String( "" ) % tr( "Legend URL" ) % QLatin1String( "" ) % legendUrl() % QLatin1String( "\n" ); - myMetadata += QLatin1String( "" ) % tr( "Legend Format" ) % QLatin1String( "" ) % legendUrlFormat() % QLatin1String( "\n" ); + // Start the history section + myMetadata += QLatin1String( "

" ) + tr( "History" ) + QLatin1String( "

\n
\n" ); + myMetadata += htmlFormatter.historySectionHtml( ); + myMetadata += QLatin1String( "

\n" ); - myMetadata += QStringLiteral( "\n\n\n" ); + myMetadata += QStringLiteral( "\n\n\n" ); return myMetadata; }