QGIS API Documentation  3.17.0-Master (a035f434f4)
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( QLatin1String( "<br />" ) ) + QStringLiteral( "</td></tr>\n" );
32  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Rights" ) + QStringLiteral( "</td><td>" ) + 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>" ) + constraint.constraint;
43  notFirstRow = true;
44  }
45  mMetadata.rights().join( QLatin1String( "<br />" ) );
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 + 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().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 ( notFirstRow )
134  {
135  myMetadata += QLatin1String( "<br />\n" );
136  }
137  myMetadata += QStringLiteral( "<strong>" ) + tr( "CRS" ) + QStringLiteral( ": </strong>" ) + spatialExtent.extentCrs.userFriendlyIdentifier() + QStringLiteral( " - " );
138  if ( spatialExtent.extentCrs.isGeographic() )
139  myMetadata += tr( "Geographic" );
140  else
141  myMetadata += tr( "Projected" );
142  myMetadata += QLatin1String( "<br />" );
143  myMetadata += QStringLiteral( "<strong>" ) + tr( "X Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMinimum() ) + QStringLiteral( "<br />" );
144  myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMinimum() ) + QStringLiteral( "<br />" );
145  myMetadata += QStringLiteral( "<strong>" ) + tr( "X Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.xMaximum() ) + QStringLiteral( "<br />" );
146  myMetadata += QStringLiteral( "<strong>" ) + tr( "Y Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.yMaximum() ) + QStringLiteral( "<br />" );
147  if ( spatialExtent.bounds.zMinimum() || spatialExtent.bounds.zMaximum() )
148  {
149  myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Minimum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMinimum() ) + QStringLiteral( "<br />" );
150  myMetadata += QStringLiteral( "<strong>" ) + tr( "Z Maximum:" ) + QStringLiteral( " </strong>" ) + qgsDoubleToString( spatialExtent.bounds.zMaximum() );
151  }
152  notFirstRow = true;
153  }
154  myMetadata += QLatin1String( "</td></tr>\n" );
155  }
156  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Temporal Extent" ) + QStringLiteral( "</td><td>" );
157  const QList< QgsDateTimeRange > temporalExtents = extent.temporalExtents();
158  notFirstRow = false;
159  for ( const QgsDateTimeRange &temporalExtent : temporalExtents )
160  {
161  if ( notFirstRow )
162  {
163  myMetadata += QLatin1String( "<br />\n" );
164  }
165  if ( temporalExtent.isInstant() )
166  {
167  myMetadata += QStringLiteral( "<strong>" ) + tr( "Instant:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
168  }
169  else
170  {
171  myMetadata += QStringLiteral( "<strong>" ) + tr( "Start:" ) + QStringLiteral( " </strong>" ) + temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) + QStringLiteral( "<br />\n" );
172  myMetadata += QStringLiteral( "<strong>" ) + tr( "End:" ) + QStringLiteral( " </strong>" ) + temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate );
173  }
174  notFirstRow = true;
175  }
176  myMetadata += QLatin1String( "</td></tr>\n" );
177  myMetadata += QLatin1String( "</table>\n" );
178  return myMetadata;
179 }
180 
182 {
183  QString myMetadata = QStringLiteral( "<table class=\"list-view\">\n" );
184 
185  // Identifier
186  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.identifier() + QStringLiteral( "</td></tr>\n" );
187 
188  // Parent Identifier
189  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Parent Identifier" ) + QStringLiteral( "</td><td>" ) + mMetadata.parentIdentifier() + QStringLiteral( "</td></tr>\n" );
190 
191  // Title
192  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Title" ) + QStringLiteral( "</td><td>" ) + mMetadata.title() + QStringLiteral( "</td></tr>\n" );
193 
194  // Type
195  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Type" ) + QStringLiteral( "</td><td>" ) + mMetadata.type() + QStringLiteral( "</td></tr>\n" );
196 
197  // Language
198  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Language" ) + QStringLiteral( "</td><td>" ) + mMetadata.language() + QStringLiteral( "</td></tr>\n" );
199 
200  // Abstract
201  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Abstract" ) + QStringLiteral( "</td><td>" ) + mMetadata.abstract() + QStringLiteral( "</td></tr>\n" );
202 
203  // Categories
204  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Categories" ) + QStringLiteral( "</td><td>" ) + mMetadata.categories().join( QLatin1String( ", " ) ) + QStringLiteral( "</td></tr>\n" );
205 
206  // Keywords
207  myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Keywords" ) + QStringLiteral( "</td><td>\n" );
208  QMapIterator<QString, QStringList> i( mMetadata.keywords() );
209  if ( i.hasNext() )
210  {
211  myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
212  myMetadata += QLatin1String( "<tr><th>" ) + tr( "Vocabulary" ) + QLatin1String( "</th><th>" ) + tr( "Items" ) + QLatin1String( "</th></tr>\n" );
213  int j = 1;
214  while ( i.hasNext() )
215  {
216  i.next();
217  QString rowClass;
218  if ( j % 2 )
219  rowClass = QStringLiteral( "class=\"odd-row\"" );
220  myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + i.key() + QLatin1String( "</td><td>" ) + i.value().join( QLatin1String( ", " ) ) + QLatin1String( "</td></tr>\n" );
221  j++;
222  }
223  myMetadata += QLatin1String( "</table>\n" ); // End keywords table
224  }
225  myMetadata += QLatin1String( "</td></tr>\n" ); // End of keywords row
226  myMetadata += QLatin1String( "</table>\n" ); // End identification table
227  return myMetadata;
228 }
229 
231 {
232  QString myMetadata;
233  const QStringList historyItems = mMetadata.history();
234  if ( historyItems.isEmpty() )
235  {
236  myMetadata += QStringLiteral( "<p>" ) + tr( "No history yet." ) + QStringLiteral( "</p>\n" );
237  }
238  else
239  {
240  myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
241  myMetadata += QLatin1String( "<tr><th>" ) + tr( "ID" ) + QLatin1String( "</th><th>" ) + tr( "Action" ) + QLatin1String( "</th></tr>\n" );
242  int i = 1;
243  for ( const QString &history : historyItems )
244  {
245  QString rowClass;
246  if ( i % 2 )
247  rowClass = QStringLiteral( "class=\"odd-row\"" );
248  myMetadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td width=\"5%\">" ) + QString::number( i ) + QLatin1String( "</td><td>" ) + history + QLatin1String( "</td></tr>\n" );
249  i++;
250  }
251  myMetadata += QLatin1String( "</table>\n" );
252  }
253  return myMetadata;
254 }
255 
257 {
258  QString myMetadata;
259  const QList<QgsAbstractMetadataBase::Link> &links = mMetadata.links();
260  if ( links.isEmpty() )
261  {
262  myMetadata += QStringLiteral( "<p>" ) + tr( "No links yet." ) + QStringLiteral( "</p>\n" );
263  }
264  else
265  {
266  myMetadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
267  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" );
268  int i = 1;
269  for ( const QgsAbstractMetadataBase::Link &link : links )
270  {
271  QString rowClass;
272  if ( i % 2 )
273  rowClass = QStringLiteral( "class=\"odd-row\"" );
274  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" );
275  i++;
276  }
277  myMetadata += QLatin1String( "</table>\n" );
278  }
279  return myMetadata;
280 }
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:276
QString administrativeArea
Administrative area (state, province/territory, etc.).
Metadata extent structure.
QgsAbstractMetadataBase::ContactList contacts() const
Returns a list of contact persons or entities associated with the resource.
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
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 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...