QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 
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>" ) + mMetadata.fees() + QStringLiteral( "</td></tr>\n" );
31  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Licenses" ) + QStringLiteral( "</td><td>" ) + mMetadata.licenses().join( QStringLiteral( "<br />" ) ) + QStringLiteral( "</td></tr>\n" );
32  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Rights" ) + QStringLiteral( "</td><td>" ) + mMetadata.rights().join( QStringLiteral( "<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>" ) + constraint.constraint;
43  notFirstRow = true;
44  }
45  myMetadata += QLatin1String( "</td></tr>\n" );
46  mMetadata.rights().join( QStringLiteral( "<br />" ) ) + QStringLiteral( "</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 += QStringLiteral( "<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 + QLatin1String( "</td><td>" ) + contact.email + QLatin1String( "</td><td>" ) + 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 
111 QString 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().authid() + QStringLiteral( " - " );
122  myMetadata += mMetadata.crs().description() + QStringLiteral( " - " );
123  if ( mMetadata.crs().isGeographic() )
124  myMetadata += tr( "Geographic" );
125  else
126  myMetadata += tr( "Projected" );
127  }
128  myMetadata += QLatin1String( "</td></tr>\n" );
129 
130  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Spatial Extent" ) + QStringLiteral( "</td><td>" );
131  const QList< QgsLayerMetadata::SpatialExtent > spatialExtents = extent.spatialExtents();
132  for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : spatialExtents )
133  {
134  if ( notFirstRow )
135  {
136  myMetadata += QLatin1String( "<br />\n" );
137  }
138  myMetadata += QStringLiteral( "<strong>" ) + tr( "CRS" ) + QStringLiteral( ": </strong>" ) + spatialExtent.extentCrs.authid() + QStringLiteral( " - " );
139  myMetadata += spatialExtent.extentCrs.description() + QStringLiteral( " - " );
140  if ( spatialExtent.extentCrs.isGeographic() )
141  myMetadata += tr( "Geographic" );
142  else
143  myMetadata += tr( "Projected" );
144  myMetadata += QStringLiteral( "<br />" );
145  myMetadata += QStringLiteral( "<strong>" ) + tr( "X Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMinimum() ) + QStringLiteral( "<br />" );
146  myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMinimum() ) + QStringLiteral( "<br />" );
147  myMetadata += QStringLiteral( "<strong>" ) + tr( "X Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMaximum() ) + QStringLiteral( "<br />" );
148  myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMaximum() ) + QStringLiteral( "<br />" );
149  if ( spatialExtent.bounds.zMinimum() || spatialExtent.bounds.zMaximum() )
150  {
151  myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMinimum() ) + QStringLiteral( "<br />" );
152  myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMaximum() );
153  }
154  notFirstRow = true;
155  }
156  myMetadata += QLatin1String( "</td></tr>\n" );
157  }
158  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Temporal Extent" ) + QStringLiteral( "</td><td>" );
159  const QList< QgsDateTimeRange > temporalExtents = extent.temporalExtents();
160  notFirstRow = false;
161  for ( const QgsDateTimeRange &temporalExtent : temporalExtents )
162  {
163  if ( notFirstRow )
164  {
165  myMetadata += QLatin1String( "<br />\n" );
166  }
167  if ( temporalExtent.isInstant() )
168  {
169  myMetadata += QStringLiteral( "<strong>" ) + tr( "Instant:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
170  }
171  else
172  {
173  myMetadata += QStringLiteral( "<strong>" ) + tr( "Start:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) + QStringLiteral( "<br />\n" );
174  myMetadata += QStringLiteral( "<strong>" ) + tr( "End:" ) + QStringLiteral( " </strong>" ) + temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
175  }
176  notFirstRow = true;
177  }
178  myMetadata += QLatin1String( "</td></tr>\n" );
179  myMetadata += QLatin1String( "</table>\n" );
180  return myMetadata;
181 }
182 
184 {
185  QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
186 
187  // Identifier
188  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.identifier() + QStringLiteral( "</td></tr>\n" );
189 
190  // Parent Identifier
191  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Parent Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.parentIdentifier() + QStringLiteral( "</td></tr>\n" );
192 
193  // Title
194  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Title" ) + QStringLiteral( "</td><td>" ) + mMetadata.title() + QStringLiteral( "</td></tr>\n" );
195 
196  // Type
197  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Type" ) + QStringLiteral( "</td><td>" ) + mMetadata.type() + QStringLiteral( "</td></tr>\n" );
198 
199  // Language
200  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Language" ) + QStringLiteral( "</td><td>" ) + mMetadata.language() + QStringLiteral( "</td></tr>\n" );
201 
202  // Abstract
203  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Abstract" ) + QStringLiteral( "</td><td>" ) + mMetadata.abstract() + QStringLiteral( "</td></tr>\n" );
204 
205  // Categories
206  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Categories" ) + QStringLiteral( "</td><td>" ) + mMetadata.categories().join( QStringLiteral( ", " ) ) + QStringLiteral( "</td></tr>\n" );
207 
208  // Keywords
209  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Keywords" ) + QStringLiteral( "</td><td>\n" );
210  QMapIterator<QString, QStringList> i( mMetadata.keywords() );
211  if ( i.hasNext() )
212  {
213  myMetadata += QStringLiteral( "<table width=\"100%\" class=\"tabular-view\">\n" );
214  myMetadata += QLatin1String( "<tr><th>" ) + tr( "Vocabulary" ) + QLatin1String( "</th><th>" ) + tr( "Items" ) + QLatin1String( "</th></tr>\n" );
215  int j = 1;
216  while ( i.hasNext() )
217  {
218  i.next();
219  QString rowClass;
220  if ( j % 2 )
221  rowClass = QStringLiteral( "class=\"odd-row\"" );
222  myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + i.key() + QLatin1String( "</td><td>" ) + i.value().join( QStringLiteral( ", " ) ) + QLatin1String( "</td></tr>\n" );
223  j++;
224  }
225  myMetadata += QLatin1String( "</table>\n" ); // End keywords table
226  }
227  myMetadata += QLatin1String( "</td></tr>\n" ); // End of keywords row
228  myMetadata += QLatin1String( "</table>\n" ); // End identification table
229  return myMetadata;
230 }
231 
233 {
234  QString myMetadata;
235  const QStringList historyItems = mMetadata.history();
236  if ( historyItems.isEmpty() )
237  {
238  myMetadata += QStringLiteral( "<p>" ) + tr( "No history yet." ) + QStringLiteral( "</p>\n" );
239  }
240  else
241  {
242  myMetadata += QStringLiteral( "<table width=\"100%\" class=\"tabular-view\">\n" );
243  myMetadata += QLatin1String( "<tr><th>" ) + tr( "ID" ) + QLatin1String( "</th><th>" ) + tr( "Action" ) + QLatin1String( "</th></tr>\n" );
244  int i = 1;
245  for ( const QString &history : historyItems )
246  {
247  QString rowClass;
248  if ( i % 2 )
249  rowClass = QStringLiteral( "class=\"odd-row\"" );
250  myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td width=\"5%\">" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + history + QLatin1String( "</td></tr>\n" );
251  i++;
252  }
253  myMetadata += QLatin1String( "</table>\n" );
254  }
255  return myMetadata;
256 }
257 
259 {
260  QString myMetadata;
261  const QList<QgsAbstractMetadataBase::Link> &links = mMetadata.links();
262  if ( links.isEmpty() )
263  {
264  myMetadata += QStringLiteral( "<p>" ) + tr( "No links yet." ) + QStringLiteral( "</p>\n" );
265  }
266  else
267  {
268  myMetadata += QStringLiteral( "<table width=\"100%\" class=\"tabular-view\">\n" );
269  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" );
270  int i = 1;
271  for ( const QgsAbstractMetadataBase::Link &link : links )
272  {
273  QString rowClass;
274  if ( i % 2 )
275  rowClass = QStringLiteral( "class=\"odd-row\"" );
276  myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + link.name + QLatin1String( "</td><td>" ) + link.type + QLatin1String( "</td><td>" ) + link.url + QLatin1String( "</td><td>" ) + link.description + QLatin1String( "</td><td>" ) + link.format + QLatin1String( "</td><td>" ) + link.mimeType + QLatin1String( "</td><td>" ) + link.size + QLatin1String( "</td></tr>\n" );
277  i++;
278  }
279  myMetadata += QLatin1String( "</table>\n" );
280  }
281  return myMetadata;
282 }
QString extentSectionHtml(const bool showSpatialExtent=true) const
Formats the "Extents" section according to a metadata object (extent and temporal).
QgsAbstractMetadataBase::KeywordMap keywords() const
Returns the keywords map, which is a set of descriptive keywords associated with the resource...
QString contactsSectionHtml() const
Formats the "Contacts" section according to a metadata object.
QString historySectionHtml() const
Formats the "History" section according to a metadata object.
QString city
City or locality name.
QString country
Free-form country string.
QStringList rights() const
Returns a list of attribution or copyright strings associated with the resource.
QStringList history() const
Returns a freeform description of the history or lineage of the resource.
QString accessSectionHtml() const
Formats the "Access" section according to a metadata object.
QString linksSectionHtml() const
Formats the "Links" section according to a metadata object.
QStringList categories() const
Returns categories of the resource.
QList< QgsDateTimeRange > temporalExtents() const
Temporal extents of the resource.
QString type() const
Returns the nature of the resource.
QString title() const
Returns the human readable name of the resource, typically displayed in search results.
const QgsLayerMetadata::Extent & extent() const
Returns the spatial and temporal extents associated with the resource.
Metadata address structure.
Metadata constraint structure.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:225
QString administrativeArea
Administrative area (state, province/territory, etc.).
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
Metadata extent structure.
QgsAbstractMetadataBase::ContactList contacts() const
Returns a list of contact persons or entities associated with the resource.
QString postalCode
Postal (or ZIP) code.
QString abstract() const
Returns a free-form description of the resource.
QgsAbstractMetadataBase::LinkList links() const
Returns a list of online resources associated with the resource.
QString identificationSectionHtml() const
Formats the "Identification" section according to a metadata object.
QString type
Type of address, e.g.
A structured metadata store for a map layer.
QString address
Free-form physical address component, e.g.
QgsLayerMetadata::ConstraintList constraints() const
Returns a list of constraints associated with using the resource.
QgsLayerMetadataFormatter(const QgsLayerMetadata &metadata)
Constructor for QgsLayerMetadataFormatter.
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system described by the layer&#39;s metadata.
QStringList licenses() const
Returns a list of licenses associated with the resource (examples: http://opendefinition.org/licenses/).
QList< QgsLayerMetadata::SpatialExtent > spatialExtents() const
Spatial extents of the resource.
QString fees() const
Returns any fees associated with using the resource.
Metadata spatial extent structure.
QString language() const
Returns the human language associated with the resource.
QString authid() const
Returns the authority identifier for the CRS.
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 parentIdentifier() const
A reference, URI, URL or some other mechanism to identify the parent resource that this resource is a...