QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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 ***************************************************************************/
16
17#include "qgslayermetadata.h"
18#include "qgsstringutils.h"
19
20#include <QDateTime>
21#include <QStringBuilder>
22
24 : mMetadata( metadata )
25{
26}
27
29{
30 QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
31 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Fees" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.fees() ) + QStringLiteral( "</td></tr>\n" );
32 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Licenses" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.licenses().join( QLatin1String( "<br />" ) ) ) + QStringLiteral( "</td></tr>\n" );
33 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Rights" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.rights().join( QLatin1String( "<br />" ) ) ) + QStringLiteral( "</td></tr>\n" );
34 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Constraints" ) + QStringLiteral( "</td><td>" );
35 const QList<QgsLayerMetadata::Constraint> &constraints = mMetadata.constraints();
36 bool notFirstRow = false;
37 for ( const QgsLayerMetadata::Constraint &constraint : constraints )
38 {
39 if ( notFirstRow )
40 {
41 myMetadata += QLatin1String( "<br />" );
42 }
43 myMetadata += QStringLiteral( "<strong>" ) + constraint.type + QStringLiteral( ": </strong>" ) + QgsStringUtils::insertLinks( constraint.constraint );
44 notFirstRow = true;
45 }
46 myMetadata += QLatin1String( "</td></tr>\n" );
47 myMetadata += QLatin1String( "</table>\n" );
48 return myMetadata;
49}
50
52{
53 const QList<QgsAbstractMetadataBase::Contact> &contacts = mMetadata.contacts();
54 QString myMetadata;
55 if ( contacts.isEmpty() )
56 {
57 myMetadata += QStringLiteral( "<p>" ) + tr( "No contact yet." ) + QStringLiteral( "</p>" );
58 }
59 else
60 {
61 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
62 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" );
63 int i = 1;
64 for ( const QgsAbstractMetadataBase::Contact &contact : contacts )
65 {
66 QString rowClass;
67 if ( i % 2 )
68 rowClass = QStringLiteral( "class=\"odd-row\"" );
69 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>" );
70 bool notFirstRow = false;
71 for ( const QgsAbstractMetadataBase::Address &oneAddress : contact.addresses )
72 {
73 if ( notFirstRow )
74 {
75 myMetadata += QLatin1String( "<br />\n" );
76 }
77 if ( ! oneAddress.type.isEmpty() )
78 {
79 myMetadata += oneAddress.type + QStringLiteral( "<br />" );
80 }
81 if ( ! oneAddress.address.isEmpty() )
82 {
83 myMetadata += oneAddress.address + QStringLiteral( "<br />" );
84 }
85 if ( ! oneAddress.postalCode.isEmpty() )
86 {
87 myMetadata += oneAddress.postalCode + QStringLiteral( "<br />" );
88 }
89 if ( ! oneAddress.city.isEmpty() )
90 {
91 myMetadata += oneAddress.city + QStringLiteral( "<br />" );
92 }
93 if ( ! oneAddress.administrativeArea.isEmpty() )
94 {
95 myMetadata += oneAddress.administrativeArea + QStringLiteral( "<br />" );
96 }
97 if ( ! oneAddress.country.isEmpty() )
98 {
99 myMetadata += oneAddress.country;
100 }
101 notFirstRow = true;
102 }
103 myMetadata += QLatin1String( "</td></tr>\n" );
104 i++;
105 }
106 myMetadata += QLatin1String( "</table>\n" );
107 }
108 return myMetadata;
109}
110
111QString QgsLayerMetadataFormatter::extentSectionHtml( const bool showSpatialExtent ) const
112{
113 const QgsLayerMetadata::Extent extent = mMetadata.extent();
114 bool notFirstRow = false;
115 QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
116 if ( showSpatialExtent )
117 {
118 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "CRS" ) + QStringLiteral( "</td><td>" );
119 if ( mMetadata.crs().isValid() )
120 {
121 myMetadata += mMetadata.crs().userFriendlyIdentifier() + QStringLiteral( " - " );
122 if ( mMetadata.crs().isGeographic() )
123 myMetadata += tr( "Geographic" );
124 else
125 myMetadata += tr( "Projected" );
126 }
127 myMetadata += QLatin1String( "</td></tr>\n" );
128
129 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Spatial Extent" ) + QStringLiteral( "</td><td>" );
130 const QList< QgsLayerMetadata::SpatialExtent > spatialExtents = extent.spatialExtents();
131 for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : spatialExtents )
132 {
133 if ( spatialExtent.bounds.isNull() || spatialExtent.bounds.toRectangle().isNull() )
134 continue;
135
136 if ( notFirstRow )
137 {
138 myMetadata += QLatin1String( "<br />\n" );
139 }
140 myMetadata += QStringLiteral( "<strong>" ) + tr( "CRS" ) + QStringLiteral( ": </strong>" ) + spatialExtent.extentCrs.userFriendlyIdentifier() + QStringLiteral( " - " );
141 if ( spatialExtent.extentCrs.isGeographic() )
142 myMetadata += tr( "Geographic" );
143 else
144 myMetadata += tr( "Projected" );
145 myMetadata += QLatin1String( "<br />" );
146 myMetadata += QStringLiteral( "<strong>" ) + tr( "X Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMinimum() ) + QStringLiteral( "<br />" );
147 myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMinimum() ) + QStringLiteral( "<br />" );
148 myMetadata += QStringLiteral( "<strong>" ) + tr( "X Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMaximum() ) + QStringLiteral( "<br />" );
149 myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMaximum() ) + QStringLiteral( "<br />" );
150 if ( spatialExtent.bounds.zMinimum() || spatialExtent.bounds.zMaximum() )
151 {
152 myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMinimum() ) + QStringLiteral( "<br />" );
153 myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMaximum() );
154 }
155 notFirstRow = true;
156 }
157 myMetadata += QLatin1String( "</td></tr>\n" );
158 }
159 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Temporal Extent" ) + QStringLiteral( "</td><td>" );
160 const QList< QgsDateTimeRange > temporalExtents = extent.temporalExtents();
161 notFirstRow = false;
162 for ( const QgsDateTimeRange &temporalExtent : temporalExtents )
163 {
164 if ( notFirstRow )
165 {
166 myMetadata += QLatin1String( "<br />\n" );
167 }
168 if ( temporalExtent.isInstant() )
169 {
170 myMetadata += QStringLiteral( "<strong>" ) + tr( "Instant:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
171 }
172 else
173 {
174 myMetadata += QStringLiteral( "<strong>" ) + tr( "Start:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) + QStringLiteral( "<br />\n" );
175 myMetadata += QStringLiteral( "<strong>" ) + tr( "End:" ) + QStringLiteral( " </strong>" ) + temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
176 }
177 notFirstRow = true;
178 }
179 myMetadata += QLatin1String( "</td></tr>\n" );
180 myMetadata += QLatin1String( "</table>\n" );
181 return myMetadata;
182}
183
185{
186 QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
187
188 // Identifier
189 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.identifier() + QStringLiteral( "</td></tr>\n" );
190
191 // Parent Identifier
192 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Parent Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.parentIdentifier() + QStringLiteral( "</td></tr>\n" );
193
194 // Title
195 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Title" ) + QStringLiteral( "</td><td>" ) + mMetadata.title() + QStringLiteral( "</td></tr>\n" );
196
197 // Type
198 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Type" ) + QStringLiteral( "</td><td>" ) + mMetadata.type() + QStringLiteral( "</td></tr>\n" );
199
200 // Language
201 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Language" ) + QStringLiteral( "</td><td>" ) + mMetadata.language() + QStringLiteral( "</td></tr>\n" );
202
203 // Abstract
204 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Abstract" ) + QStringLiteral( "</td><td>" ) + QgsStringUtils::insertLinks( mMetadata.abstract() ).replace( '\n', QLatin1String( "<br>" ) ) + QStringLiteral( "</td></tr>\n" );
205
206 // Categories
207 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Categories" ) + QStringLiteral( "</td><td>" ) + mMetadata.categories().join( QLatin1String( ", " ) ) + QStringLiteral( "</td></tr>\n" );
208
209 // Keywords
210 myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Keywords" ) + QStringLiteral( "</td><td>\n" );
211 QMapIterator<QString, QStringList> i( mMetadata.keywords() );
212 if ( i.hasNext() )
213 {
214 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
215 myMetadata += QLatin1String( "<tr><th>" ) + tr( "Vocabulary" ) + QLatin1String( "</th><th>" ) + tr( "Items" ) + QLatin1String( "</th></tr>\n" );
216 int j = 1;
217 while ( i.hasNext() )
218 {
219 i.next();
220 QString rowClass;
221 if ( j % 2 )
222 rowClass = QStringLiteral( "class=\"odd-row\"" );
223 myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + i.key() + QLatin1String( "</td><td>" ) + i.value().join( QLatin1String( ", " ) ) + QLatin1String( "</td></tr>\n" );
224 j++;
225 }
226 myMetadata += QLatin1String( "</table>\n" ); // End keywords table
227 }
228 myMetadata += QLatin1String( "</td></tr>\n" ); // End of keywords row
229 myMetadata += QLatin1String( "</table>\n" ); // End identification table
230 return myMetadata;
231}
232
234{
235 QString myMetadata;
236 const QStringList historyItems = mMetadata.history();
237 if ( historyItems.isEmpty() )
238 {
239 myMetadata += QStringLiteral( "<p>" ) + tr( "No history yet." ) + QStringLiteral( "</p>\n" );
240 }
241 else
242 {
243 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
244 myMetadata += QLatin1String( "<tr><th>" ) + tr( "ID" ) + QLatin1String( "</th><th>" ) + tr( "Action" ) + QLatin1String( "</th></tr>\n" );
245 int i = 1;
246 for ( const QString &history : historyItems )
247 {
248 QString rowClass;
249 if ( i % 2 )
250 rowClass = QStringLiteral( "class=\"odd-row\"" );
251 myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td width=\"5%\">" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + QgsStringUtils::insertLinks( history ) + QLatin1String( "</td></tr>\n" );
252 i++;
253 }
254 myMetadata += QLatin1String( "</table>\n" );
255 }
256 return myMetadata;
257}
258
260{
261 QString myMetadata;
262 const QList<QgsAbstractMetadataBase::Link> &links = mMetadata.links();
263 if ( links.isEmpty() )
264 {
265 myMetadata += QStringLiteral( "<p>" ) + tr( "No links yet." ) + QStringLiteral( "</p>\n" );
266 }
267 else
268 {
269 myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
270 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" );
271 int i = 1;
272 for ( const QgsAbstractMetadataBase::Link &link : links )
273 {
274 QString rowClass;
275 if ( i % 2 )
276 rowClass = QStringLiteral( "class=\"odd-row\"" );
277 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" );
278 i++;
279 }
280 myMetadata += QLatin1String( "</table>\n" );
281 }
282 return myMetadata;
283}
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.
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:6524
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
Definition qgsrange.h:761
QString administrativeArea
Administrative area (state, province/territory, etc.).
QString address
Free-form physical address component, e.g.
QString city
City or locality name.
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.