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