QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
qgslayermetadataformatter.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayermetadataformatter.cpp
3 ---------------------
4 begin : September 2017
5 copyright : (C) 2017 by Etienne Trimaille
6 email : etienne.trimaille at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15#include <QStringBuilder>
16#include <QDateTime>
17
19#include "qgslayermetadata.h"
20#include "qgsstringutils.h"
21
23 : mMetadata( metadata )
24{
25}
26
28{
29 QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
30 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Fees" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.fees() ) + QStringLiteral( "</td></tr>\n" );
31 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Licenses" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.licenses().join( QLatin1String( "<br />" ) ) ) + QStringLiteral( "</td></tr>\n" );
32 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Rights" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.rights().join( QLatin1String( "<br />" ) ) ) + QStringLiteral( "</td></tr>\n" );
33 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Constraints" ) + QStringLiteral( "</td><td>" );
34 const QList<QgsLayerMetadata::Constraint> &constraints = mMetadata.constraints();
35 bool notFirstRow = false;
36 for ( const QgsLayerMetadata::Constraint &constraint : constraints )
37 {
38 if ( notFirstRow )
39 {
40 myMetadata += QLatin1String( "<br />" );
41 }
42 myMetadata += QStringLiteral( "<strong>" ) + constraint.type + QStringLiteral( ": </strong>" ) + QgsStringUtils::insertLinks( constraint.constraint );
43 notFirstRow = true;
44 }
45 myMetadata += QLatin1String( "</td></tr>\n" );
46 myMetadata += QLatin1String( "</table>\n" );
47 return myMetadata;
48}
49
51{
52 const QList<QgsAbstractMetadataBase::Contact> &contacts = mMetadata.contacts();
53 QString myMetadata;
54 if ( contacts.isEmpty() )
55 {
56 myMetadata += QStringLiteral( "<p>" ) + tr( "No contact yet." ) + QStringLiteral( "</p>" );
57 }
58 else
59 {
60 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
61 myMetadata += QLatin1String( "<tr><th>" ) + tr( "ID" ) + QLatin1String( "</th><th>" ) + tr( "Name" ) + QLatin1String( "</th><th>" ) + tr( "Position" ) + QLatin1String( "</th><th>" ) + tr( "Organization" ) + QLatin1String( "</th><th>" ) + tr( "Role" ) + QLatin1String( "</th><th>" ) + tr( "Email" ) + QLatin1String( "</th><th>" ) + tr( "Voice" ) + QLatin1String( "</th><th>" ) + tr( "Fax" ) + QLatin1String( "</th><th>" ) + tr( "Addresses" ) + QLatin1String( "</th></tr>\n" );
62 int i = 1;
63 for ( const QgsAbstractMetadataBase::Contact &contact : contacts )
64 {
65 QString rowClass;
66 if ( i % 2 )
67 rowClass = QStringLiteral( "class=\"odd-row\"" );
68 myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + contact.name + QLatin1String( "</td><td>" ) + contact.position + QLatin1String( "</td><td>" ) + contact.organization + QLatin1String( "</td><td>" ) + contact.role + QStringLiteral( "</td><td><a href=\"mailto:%1\">%1</a></td><td>" ).arg( contact.email ) + contact.voice + QLatin1String( "</td><td>" ) + contact.fax + QLatin1String( "</td><td>" );
69 bool notFirstRow = false;
70 for ( const QgsAbstractMetadataBase::Address &oneAddress : contact.addresses )
71 {
72 if ( notFirstRow )
73 {
74 myMetadata += QLatin1String( "<br />\n" );
75 }
76 if ( ! oneAddress.type.isEmpty() )
77 {
78 myMetadata += oneAddress.type + QStringLiteral( "<br />" );
79 }
80 if ( ! oneAddress.address.isEmpty() )
81 {
82 myMetadata += oneAddress.address + QStringLiteral( "<br />" );
83 }
84 if ( ! oneAddress.postalCode.isEmpty() )
85 {
86 myMetadata += oneAddress.postalCode + QStringLiteral( "<br />" );
87 }
88 if ( ! oneAddress.city.isEmpty() )
89 {
90 myMetadata += oneAddress.city + QStringLiteral( "<br />" );
91 }
92 if ( ! oneAddress.administrativeArea.isEmpty() )
93 {
94 myMetadata += oneAddress.administrativeArea + QStringLiteral( "<br />" );
95 }
96 if ( ! oneAddress.country.isEmpty() )
97 {
98 myMetadata += oneAddress.country;
99 }
100 notFirstRow = true;
101 }
102 myMetadata += QLatin1String( "</td></tr>\n" );
103 i++;
104 }
105 myMetadata += QLatin1String( "</table>\n" );
106 }
107 return myMetadata;
108}
109
110QString QgsLayerMetadataFormatter::extentSectionHtml( const bool showSpatialExtent ) const
111{
112 const QgsLayerMetadata::Extent extent = mMetadata.extent();
113 bool notFirstRow = false;
114 QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
115 if ( showSpatialExtent )
116 {
117 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "CRS" ) + QStringLiteral( "</td><td>" );
118 if ( mMetadata.crs().isValid() )
119 {
120 myMetadata += mMetadata.crs().userFriendlyIdentifier() + QStringLiteral( " - " );
121 if ( mMetadata.crs().isGeographic() )
122 myMetadata += tr( "Geographic" );
123 else
124 myMetadata += tr( "Projected" );
125 }
126 myMetadata += QLatin1String( "</td></tr>\n" );
127
128 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Spatial Extent" ) + QStringLiteral( "</td><td>" );
129 const QList< QgsLayerMetadata::SpatialExtent > spatialExtents = extent.spatialExtents();
130 for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : spatialExtents )
131 {
132 if ( notFirstRow )
133 {
134 myMetadata += QLatin1String( "<br />\n" );
135 }
136 myMetadata += QStringLiteral( "<strong>" ) + tr( "CRS" ) + QStringLiteral( ": </strong>" ) + spatialExtent.extentCrs.userFriendlyIdentifier() + QStringLiteral( " - " );
137 if ( spatialExtent.extentCrs.isGeographic() )
138 myMetadata += tr( "Geographic" );
139 else
140 myMetadata += tr( "Projected" );
141 myMetadata += QLatin1String( "<br />" );
142 myMetadata += QStringLiteral( "<strong>" ) + tr( "X Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMinimum() ) + QStringLiteral( "<br />" );
143 myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMinimum() ) + QStringLiteral( "<br />" );
144 myMetadata += QStringLiteral( "<strong>" ) + tr( "X Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMaximum() ) + QStringLiteral( "<br />" );
145 myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMaximum() ) + QStringLiteral( "<br />" );
146 if ( spatialExtent.bounds.zMinimum() || spatialExtent.bounds.zMaximum() )
147 {
148 myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMinimum() ) + QStringLiteral( "<br />" );
149 myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMaximum() );
150 }
151 notFirstRow = true;
152 }
153 myMetadata += QLatin1String( "</td></tr>\n" );
154 }
155 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Temporal Extent" ) + QStringLiteral( "</td><td>" );
156 const QList< QgsDateTimeRange > temporalExtents = extent.temporalExtents();
157 notFirstRow = false;
158 for ( const QgsDateTimeRange &temporalExtent : temporalExtents )
159 {
160 if ( notFirstRow )
161 {
162 myMetadata += QLatin1String( "<br />\n" );
163 }
164 if ( temporalExtent.isInstant() )
165 {
166 myMetadata += QStringLiteral( "<strong>" ) + tr( "Instant:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
167 }
168 else
169 {
170 myMetadata += QStringLiteral( "<strong>" ) + tr( "Start:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) + QStringLiteral( "<br />\n" );
171 myMetadata += QStringLiteral( "<strong>" ) + tr( "End:" ) + QStringLiteral( " </strong>" ) + temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
172 }
173 notFirstRow = true;
174 }
175 myMetadata += QLatin1String( "</td></tr>\n" );
176 myMetadata += QLatin1String( "</table>\n" );
177 return myMetadata;
178}
179
181{
182 QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
183
184 // Identifier
185 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.identifier() + QStringLiteral( "</td></tr>\n" );
186
187 // Parent Identifier
188 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Parent Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.parentIdentifier() + QStringLiteral( "</td></tr>\n" );
189
190 // Title
191 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Title" ) + QStringLiteral( "</td><td>" ) + mMetadata.title() + QStringLiteral( "</td></tr>\n" );
192
193 // Type
194 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Type" ) + QStringLiteral( "</td><td>" ) + mMetadata.type() + QStringLiteral( "</td></tr>\n" );
195
196 // Language
197 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Language" ) + QStringLiteral( "</td><td>" ) + mMetadata.language() + QStringLiteral( "</td></tr>\n" );
198
199 // Abstract
200 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Abstract" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.abstract() ).replace( '\n', QLatin1String( "<br>" ) ) + QStringLiteral( "</td></tr>\n" );
201
202 // Categories
203 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Categories" ) + QStringLiteral( "</td><td>" ) + mMetadata.categories().join( QLatin1String( ", " ) ) + QStringLiteral( "</td></tr>\n" );
204
205 // Keywords
206 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Keywords" ) + QStringLiteral( "</td><td>\n" );
207 QMapIterator<QString, QStringList> i( mMetadata.keywords() );
208 if ( i.hasNext() )
209 {
210 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
211 myMetadata += QLatin1String( "<tr><th>" ) + tr( "Vocabulary" ) + QLatin1String( "</th><th>" ) + tr( "Items" ) + QLatin1String( "</th></tr>\n" );
212 int j = 1;
213 while ( i.hasNext() )
214 {
215 i.next();
216 QString rowClass;
217 if ( j % 2 )
218 rowClass = QStringLiteral( "class=\"odd-row\"" );
219 myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + i.key() + QLatin1String( "</td><td>" ) + i.value().join( QLatin1String( ", " ) ) + QLatin1String( "</td></tr>\n" );
220 j++;
221 }
222 myMetadata += QLatin1String( "</table>\n" ); // End keywords table
223 }
224 myMetadata += QLatin1String( "</td></tr>\n" ); // End of keywords row
225 myMetadata += QLatin1String( "</table>\n" ); // End identification table
226 return myMetadata;
227}
228
230{
231 QString myMetadata;
232 const QStringList historyItems = mMetadata.history();
233 if ( historyItems.isEmpty() )
234 {
235 myMetadata += QStringLiteral( "<p>" ) + tr( "No history yet." ) + QStringLiteral( "</p>\n" );
236 }
237 else
238 {
239 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
240 myMetadata += QLatin1String( "<tr><th>" ) + tr( "ID" ) + QLatin1String( "</th><th>" ) + tr( "Action" ) + QLatin1String( "</th></tr>\n" );
241 int i = 1;
242 for ( const QString &history : historyItems )
243 {
244 QString rowClass;
245 if ( i % 2 )
246 rowClass = QStringLiteral( "class=\"odd-row\"" );
247 myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td width=\"5%\">" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + QgsStringUtils::insertLinks( history ) + QLatin1String( "</td></tr>\n" );
248 i++;
249 }
250 myMetadata += QLatin1String( "</table>\n" );
251 }
252 return myMetadata;
253}
254
256{
257 QString myMetadata;
258 const QList<QgsAbstractMetadataBase::Link> &links = mMetadata.links();
259 if ( links.isEmpty() )
260 {
261 myMetadata += QStringLiteral( "<p>" ) + tr( "No links yet." ) + QStringLiteral( "</p>\n" );
262 }
263 else
264 {
265 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
266 myMetadata += QLatin1String( "<tr><th>" ) + tr( "ID" ) + QLatin1String( "</th><th>" ) + tr( "Name" ) + QLatin1String( "</th><th>" ) + tr( "Type" ) + QLatin1String( "</th><th>" ) + tr( "URL" ) + QLatin1String( "</th><th>" ) + tr( "Description" ) + QLatin1String( "</th><th>" ) + tr( "Format" ) + QLatin1String( "</th><th>" ) + tr( "MIME Type" ) + QLatin1String( "</th><th>" ) + tr( "Size" ) + QLatin1String( "</th></tr>\n" );
267 int i = 1;
268 for ( const QgsAbstractMetadataBase::Link &link : links )
269 {
270 QString rowClass;
271 if ( i % 2 )
272 rowClass = QStringLiteral( "class=\"odd-row\"" );
273 myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + link.name + QLatin1String( "</td><td>" ) + link.type + QStringLiteral( "</td><td><a href=\"%1\">%1</a></td><td>" ).arg( link.url ) + link.description + QLatin1String( "</td><td>" ) + link.format + QLatin1String( "</td><td>" ) + link.mimeType + QLatin1String( "</td><td>" ) + link.size + QLatin1String( "</td></tr>\n" );
274 i++;
275 }
276 myMetadata += QLatin1String( "</table>\n" );
277 }
278 return myMetadata;
279}
QgsAbstractMetadataBase::ContactList contacts() const
Returns a list of contact persons or entities associated with the resource.
QStringList categories() const
Returns categories of the resource.
QString abstract() const
Returns a free-form description of the resource.
QString title() const
Returns the human readable name of the resource, typically displayed in search results.
QStringList history() const
Returns a freeform description of the history or lineage of the resource.
QgsAbstractMetadataBase::KeywordMap keywords() const
Returns the keywords map, which is a set of descriptive keywords associated with the resource.
QgsAbstractMetadataBase::LinkList links() const
Returns a list of online resources associated with the resource.
QString parentIdentifier() const
A reference, URI, URL or some other mechanism to identify the parent resource that this resource is a...
QString language() const
Returns the human language associated with the resource.
QString type() const
Returns the nature of the resource.
QString identifier() const
A reference, URI, URL or some other mechanism to identify the resource.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
QString linksSectionHtml() const
Formats the "Links" section according to a metadata object.
QString extentSectionHtml(const bool showSpatialExtent=true) const
Formats the "Extents" section according to a metadata object (extent and temporal).
QgsLayerMetadataFormatter(const QgsLayerMetadata &metadata)
Constructor for QgsLayerMetadataFormatter.
QString contactsSectionHtml() const
Formats the "Contacts" section according to a metadata object.
QString identificationSectionHtml() const
Formats the "Identification" section according to a metadata object.
QString historySectionHtml() const
Formats the "History" section according to a metadata object.
QString accessSectionHtml() const
Formats the "Access" section according to a metadata object.
A structured metadata store for a map layer.
const QgsLayerMetadata::Extent & extent() const
Returns the spatial and temporal extents associated with the resource.
QgsLayerMetadata::ConstraintList constraints() const
Returns a list of constraints associated with using the resource.
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system described by the layer's metadata.
QStringList licenses() const
Returns a list of licenses associated with the resource (examples: http://opendefinition....
QStringList rights() const
Returns a list of attribution or copyright strings associated with the resource.
QString fees() const
Returns any fees associated with using the resource.
static QString insertLinks(const QString &string, bool *foundLinks=nullptr)
Returns a string with any URL (e.g., http(s)/ftp) and mailto: text converted to valid HTML <a ....
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:3927
QString administrativeArea
Administrative area (state, province/territory, etc.).
QString address
Free-form physical address component, e.g.
QString city
City or locality name.
QString type
Type of address, e.g.
QString country
Free-form country string.
QString postalCode
Postal (or ZIP) code.
Metadata constraint structure.
Metadata extent structure.
QList< QgsLayerMetadata::SpatialExtent > spatialExtents() const
Spatial extents of the resource.
QList< QgsDateTimeRange > temporalExtents() const
Temporal extents of the resource.
Metadata spatial extent structure.