QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgslayermetadata.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayermetadata.cpp
3  --------------------
4  begin : April 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgslayermetadata.h"
19 #include "qgsmaplayer.h"
20 
22 {
23  return new QgsLayerMetadata( *this );
24 }
25 
26 QString QgsLayerMetadata::fees() const
27 {
28  return mFees;
29 }
30 
31 void QgsLayerMetadata::setFees( const QString &fees )
32 {
33  mFees = fees;
34 }
35 
37 {
38  mConstraints << constraint;
39 }
40 
41 QList<QgsLayerMetadata::Constraint> QgsLayerMetadata::constraints() const
42 {
43  return mConstraints;
44 }
45 
46 void QgsLayerMetadata::setConstraints( const QList<Constraint> &constraints )
47 {
48  mConstraints = constraints;
49 }
50 
51 QStringList QgsLayerMetadata::rights() const
52 {
53  return mRights;
54 }
55 
56 void QgsLayerMetadata::setRights( const QStringList &rights )
57 {
58  mRights = rights;
59 }
60 
61 QStringList QgsLayerMetadata::licenses() const
62 {
63  return mLicenses;
64 }
65 
66 void QgsLayerMetadata::setLicenses( const QStringList &licenses )
67 {
68  mLicenses = licenses;
69 }
70 
72 {
73  return mEncoding;
74 }
75 
77 {
78  mEncoding = encoding;
79 }
80 
82 {
83  return mCrs;
84 }
85 
87 {
88  mCrs = crs;
89 }
90 
92 {
93  layer->setCustomProperty( QStringLiteral( "metadata/identifier" ), mIdentifier );
94  layer->setCustomProperty( QStringLiteral( "metadata/parentIdentifier" ), mParentIdentifier );
95  layer->setCustomProperty( QStringLiteral( "metadata/language" ), mLanguage );
96  layer->setCustomProperty( QStringLiteral( "metadata/type" ), mType );
97  layer->setCustomProperty( QStringLiteral( "metadata/title" ), mTitle );
98  layer->setCustomProperty( QStringLiteral( "metadata/extent" ), QVariant::fromValue( mExtent ) );
99  layer->setCustomProperty( QStringLiteral( "metadata/abstract" ), mAbstract );
100  layer->setCustomProperty( QStringLiteral( "metadata/fees" ), mFees );
101  layer->setCustomProperty( QStringLiteral( "metadata/rights" ), mRights );
102  layer->setCustomProperty( QStringLiteral( "metadata/licenses" ), mLicenses );
103  layer->setCustomProperty( QStringLiteral( "metadata/history" ), mHistory );
104  layer->setCustomProperty( QStringLiteral( "metadata/encoding" ), mEncoding );
105  layer->setCustomProperty( QStringLiteral( "metadata/crs" ), mCrs.authid() );
106  layer->setCustomProperty( QStringLiteral( "metadata/constraints" ), QVariant::fromValue( mConstraints ) );
107  layer->setCustomProperty( QStringLiteral( "metadata/keywords" ), QVariant::fromValue( mKeywords ) );
108  layer->setCustomProperty( QStringLiteral( "metadata/contacts" ), QVariant::fromValue( mContacts ) );
109  layer->setCustomProperty( QStringLiteral( "metadata/links" ), QVariant::fromValue( mLinks ) );
110 }
111 
113 {
114  mIdentifier = layer->customProperty( QStringLiteral( "metadata/identifier" ) ).toString();
115  mParentIdentifier = layer->customProperty( QStringLiteral( "metadata/parentIdentifier" ) ).toString();
116  mLanguage = layer->customProperty( QStringLiteral( "metadata/language" ) ).toString();
117  mType = layer->customProperty( QStringLiteral( "metadata/type" ) ).toString();
118  mTitle = layer->customProperty( QStringLiteral( "metadata/title" ) ).toString();
119  mAbstract = layer->customProperty( QStringLiteral( "metadata/abstract" ) ).toString();
120  mFees = layer->customProperty( QStringLiteral( "metadata/fees" ) ).toString();
121  mRights = layer->customProperty( QStringLiteral( "metadata/rights" ) ).toStringList();
122  mLicenses = layer->customProperty( QStringLiteral( "metadata/licenses" ) ).toStringList();
123  mHistory = layer->customProperty( QStringLiteral( "metadata/history" ) ).toStringList();
124  mEncoding = layer->customProperty( QStringLiteral( "metadata/encoding" ) ).toString();
125  QString crsAuthId = layer->customProperty( QStringLiteral( "metadata/crs" ) ).toString();
127  mExtent = layer->customProperty( QStringLiteral( "metadata/extent" ) ).value<Extent>();
128  mConstraints = layer->customProperty( QStringLiteral( "metadata/constraints" ) ).value<ConstraintList>();
129  mKeywords = layer->customProperty( QStringLiteral( "metadata/keywords" ) ).value<QgsAbstractMetadataBase::KeywordMap>();
130  mContacts = layer->customProperty( QStringLiteral( "metadata/contacts" ) ).value<QgsAbstractMetadataBase::ContactList>();
131  mLinks = layer->customProperty( QStringLiteral( "metadata/links" ) ).value<QgsAbstractMetadataBase::LinkList>();
132 }
133 
134 bool QgsLayerMetadata::readMetadataXml( const QDomElement &metadataElement )
135 {
136  QgsAbstractMetadataBase::readMetadataXml( metadataElement );
137 
138  QDomNode mnl;
139  QDomElement mne;
140 
141  // set fees
142  mnl = metadataElement.namedItem( QStringLiteral( "fees" ) );
143  mFees = mnl.toElement().text();
144 
145  // constraints
146  QDomNodeList constraintsList = metadataElement.elementsByTagName( QStringLiteral( "constraints" ) );
147  mConstraints.clear();
148  for ( int i = 0; i < constraintsList.size(); i++ )
149  {
150  mnl = constraintsList.at( i );
151  mne = mnl.toElement();
152  addConstraint( QgsLayerMetadata::Constraint( mne.text(), mne.attribute( QStringLiteral( "type" ) ) ) );
153  }
154 
155  // rights
156  QDomNodeList rightsNodeList = metadataElement.elementsByTagName( QStringLiteral( "rights" ) );
157  QStringList rightsList;
158  for ( int i = 0; i < rightsNodeList.size(); i++ )
159  {
160  mnl = rightsNodeList.at( i );
161  mne = mnl.toElement();
162  rightsList.append( mne.text() );
163  }
164  setRights( rightsList );
165 
166  // licenses
167  QDomNodeList licensesNodeList = metadataElement.elementsByTagName( QStringLiteral( "license" ) );
168  QStringList licensesList;
169  for ( int i = 0; i < licensesNodeList.size(); i++ )
170  {
171  mnl = licensesNodeList.at( i );
172  mne = mnl.toElement();
173  licensesList.append( mne.text() );
174  }
175  setLicenses( licensesList );
176 
177  // encoding
178  mnl = metadataElement.namedItem( QStringLiteral( "encoding" ) );
179  mEncoding = mnl.toElement().text();
180 
181  // crs
182  mnl = metadataElement.namedItem( QStringLiteral( "crs" ) );
183  if ( !mCrs.readXml( mnl ) )
185 
186  // extent
187  mnl = metadataElement.namedItem( QStringLiteral( "extent" ) );
188  QgsLayerMetadata::Extent metadataExtent;
189 
190  // spatial extent
191  QDomNodeList spatialList = mnl.toElement().elementsByTagName( QStringLiteral( "spatial" ) );
192  QList< QgsLayerMetadata::SpatialExtent > metadataSpatialExtents;
193  for ( int i = 0; i < spatialList.size(); i++ )
194  {
195  mnl = spatialList.at( i );
196  mne = mnl.toElement();
198  se.extentCrs = QgsCoordinateReferenceSystem( mne.attribute( QStringLiteral( "crs" ) ) );
199  se.bounds = QgsBox3d();
200  se.bounds.setXMinimum( mne.attribute( QStringLiteral( "minx" ) ).toDouble() );
201  se.bounds.setYMinimum( mne.attribute( QStringLiteral( "miny" ) ).toDouble() );
202  se.bounds.setZMinimum( mne.attribute( QStringLiteral( "minz" ) ).toDouble() );
203  se.bounds.setXMaximum( mne.attribute( QStringLiteral( "maxx" ) ).toDouble() );
204  se.bounds.setYMaximum( mne.attribute( QStringLiteral( "maxy" ) ).toDouble() );
205  se.bounds.setZMaximum( mne.attribute( QStringLiteral( "maxz" ) ).toDouble() );
206  metadataSpatialExtents.append( se );
207  }
208  metadataExtent.setSpatialExtents( metadataSpatialExtents );
209 
210  // temporal extent
211  mnl = metadataElement.namedItem( QStringLiteral( "extent" ) );
212  QDomNodeList temporalList = mnl.toElement().elementsByTagName( QStringLiteral( "temporal" ) );
213  QList<QgsDateTimeRange> metadataDates;
214  for ( int j = 0; j < temporalList.size(); j++ )
215  {
216  mnl = temporalList.at( j );
217  QDomNodeList instantList = mnl.toElement().elementsByTagName( QStringLiteral( "instant" ) );
218  for ( int i = 0; i < instantList.size(); i++ )
219  {
220  mnl = instantList.at( i );
221  QDateTime d = QDateTime().fromString( mnl.toElement().text(), Qt::ISODate );
222  QgsDateTimeRange date = QgsDateTimeRange( d, d );
223  metadataDates << date;
224  }
225  QDomNodeList periodList = mnl.toElement().elementsByTagName( QStringLiteral( "period" ) );
226  for ( int i = 0; i < periodList.size(); i++ )
227  {
228  QDomNode begin = periodList.at( i ).namedItem( QStringLiteral( "start" ) );
229  QDomNode end = periodList.at( i ).namedItem( QStringLiteral( "end" ) );
230  QDateTime beginDate = QDateTime().fromString( begin.toElement().text(), Qt::ISODate );
231  QDateTime endDate = QDateTime().fromString( end.toElement().text(), Qt::ISODate );
232  QgsDateTimeRange date = QgsDateTimeRange( beginDate, endDate );
233  metadataDates << date;
234  }
235  }
236  metadataExtent.setTemporalExtents( metadataDates );
237  setExtent( metadataExtent );
238 
239  return true;
240 }
241 
242 bool QgsLayerMetadata::writeMetadataXml( QDomElement &metadataElement, QDomDocument &document ) const
243 {
244  QgsAbstractMetadataBase::writeMetadataXml( metadataElement, document );
245 
246  // fees
247  QDomElement fees = document.createElement( QStringLiteral( "fees" ) );
248  QDomText feesText = document.createTextNode( mFees );
249  fees.appendChild( feesText );
250  metadataElement.appendChild( fees );
251 
252  // constraints
253  for ( const QgsLayerMetadata::Constraint &constraint : mConstraints )
254  {
255  QDomElement constraintElement = document.createElement( QStringLiteral( "constraints" ) );
256  constraintElement.setAttribute( QStringLiteral( "type" ), constraint.type );
257  QDomText constraintText = document.createTextNode( constraint.constraint );
258  constraintElement.appendChild( constraintText );
259  metadataElement.appendChild( constraintElement );
260  }
261 
262  // rights
263  for ( const QString &right : mRights )
264  {
265  QDomElement rightElement = document.createElement( QStringLiteral( "rights" ) );
266  QDomText rightText = document.createTextNode( right );
267  rightElement.appendChild( rightText );
268  metadataElement.appendChild( rightElement );
269  }
270 
271  // license
272  for ( const QString &license : mLicenses )
273  {
274  QDomElement licenseElement = document.createElement( QStringLiteral( "license" ) );
275  QDomText licenseText = document.createTextNode( license );
276  licenseElement.appendChild( licenseText );
277  metadataElement.appendChild( licenseElement );
278  }
279 
280  // encoding
281  QDomElement encoding = document.createElement( QStringLiteral( "encoding" ) );
282  QDomText encodingText = document.createTextNode( mEncoding );
283  encoding.appendChild( encodingText );
284  metadataElement.appendChild( encoding );
285 
286  // crs
287  QDomElement crsElement = document.createElement( QStringLiteral( "crs" ) );
288  mCrs.writeXml( crsElement, document );
289  metadataElement.appendChild( crsElement );
290 
291  // extent
292  QDomElement extentElement = document.createElement( QStringLiteral( "extent" ) );
293 
294  // spatial extents
295  const QList< QgsLayerMetadata::SpatialExtent > sExtents = extent().spatialExtents();
296  for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : sExtents )
297  {
298  QDomElement spatialElement = document.createElement( QStringLiteral( "spatial" ) );
299  // Dimensions fixed in the XSD
300  spatialElement.setAttribute( QStringLiteral( "dimensions" ), QStringLiteral( "2" ) );
301  spatialElement.setAttribute( QStringLiteral( "crs" ), spatialExtent.extentCrs.authid() );
302  spatialElement.setAttribute( QStringLiteral( "minx" ), qgsDoubleToString( spatialExtent.bounds.xMinimum() ) );
303  spatialElement.setAttribute( QStringLiteral( "miny" ), qgsDoubleToString( spatialExtent.bounds.yMinimum() ) );
304  spatialElement.setAttribute( QStringLiteral( "minz" ), qgsDoubleToString( spatialExtent.bounds.zMinimum() ) );
305  spatialElement.setAttribute( QStringLiteral( "maxx" ), qgsDoubleToString( spatialExtent.bounds.xMaximum() ) );
306  spatialElement.setAttribute( QStringLiteral( "maxy" ), qgsDoubleToString( spatialExtent.bounds.yMaximum() ) );
307  spatialElement.setAttribute( QStringLiteral( "maxz" ), qgsDoubleToString( spatialExtent.bounds.zMaximum() ) );
308  extentElement.appendChild( spatialElement );
309  }
310 
311  // temporal extents
312  const QList< QgsDateTimeRange > tExtents = extent().temporalExtents();
313  for ( const QgsDateTimeRange &temporalExtent : tExtents )
314  {
315  QDomElement temporalElement = document.createElement( QStringLiteral( "temporal" ) );
316  if ( temporalExtent.isInstant() )
317  {
318  QDomElement instantElement = document.createElement( QStringLiteral( "instant" ) );
319  QDomText instantText = document.createTextNode( temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
320  instantElement.appendChild( instantText );
321  temporalElement.appendChild( instantElement );
322  }
323  else
324  {
325  QDomElement periodElement = document.createElement( QStringLiteral( "period" ) );
326  QDomElement startElement = document.createElement( QStringLiteral( "start" ) );
327  QDomElement endElement = document.createElement( QStringLiteral( "end" ) );
328  QDomText startText = document.createTextNode( temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
329  QDomText endText = document.createTextNode( temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
330  startElement.appendChild( startText );
331  endElement.appendChild( endText );
332  periodElement.appendChild( startElement );
333  periodElement.appendChild( endElement );
334  temporalElement.appendChild( periodElement );
335  }
336  extentElement.appendChild( temporalElement );
337  }
338 
339  metadataElement.appendChild( extentElement );
340 
341  return true;
342 }
343 
345 {
346  return mExtent;
347 }
348 
350 {
351  return mExtent;
352 }
353 
355 {
356  mExtent = extent;
357 }
358 
359 QList<QgsLayerMetadata::SpatialExtent> QgsLayerMetadata::Extent::spatialExtents() const
360 {
361  return mSpatialExtents;
362 }
363 
364 void QgsLayerMetadata::Extent::setSpatialExtents( const QList<QgsLayerMetadata::SpatialExtent> &spatialExtents )
365 {
366  mSpatialExtents = spatialExtents;
367 }
368 
369 QList<QgsDateTimeRange> QgsLayerMetadata::Extent::temporalExtents() const
370 {
371  return mTemporalExtents;
372 }
373 
374 void QgsLayerMetadata::Extent::setTemporalExtents( const QList<QgsDateTimeRange> &temporalExtents )
375 {
376  mTemporalExtents = temporalExtents;
377 }
378 
380 {
381  return mSpatialExtents == other.mSpatialExtents && mTemporalExtents == other.mTemporalExtents;
382 }
383 
385 {
386  return equals( other ) &&
387  mFees == other.mFees &&
388  mConstraints == other.mConstraints &&
389  mRights == other.mRights &&
390  mLicenses == other.mLicenses &&
391  mEncoding == other.mEncoding &&
392  mCrs == other.mCrs &&
393  mExtent == other.mExtent;
394 }
395 
397 {
398  return extentCrs == other.extentCrs &&
399  bounds == other.bounds;
400 }
401 
403 {
404  return type == other.type && constraint == other.constraint;
405 }
Base class for all map layer types.
Definition: qgsmaplayer.h:78
QList< QgsAbstractMetadataBase::Link > LinkList
A list of links.
void setXMinimum(double x)
Sets the minimum x value.
Definition: qgsbox3d.cpp:40
QgsAbstractMetadataBase::ContactList mContacts
void saveToLayer(QgsMapLayer *layer) const
Saves the metadata to a layer&#39;s custom properties (see QgsMapLayer::setCustomProperty() )...
void addConstraint(const QgsLayerMetadata::Constraint &constraint)
Adds an individual constraint to the existing constraints.
virtual bool readMetadataXml(const QDomElement &metadataElement)
Sets state from DOM document.
QStringList rights() const
Returns a list of attribution or copyright strings associated with the resource.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
QgsAbstractMetadataBase::LinkList mLinks
QList< QgsAbstractMetadataBase::Contact > ContactList
A list of contacts.
void setLicenses(const QStringList &licenses)
Sets a list of licenses associated with the resource.
QList< QgsDateTimeRange > temporalExtents() const
Temporal extents of the resource.
void setXMaximum(double x)
Sets the maximum x value.
Definition: qgsbox3d.cpp:45
QString type() const
Returns the nature of the resource.
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:36
const QgsLayerMetadata::Extent & extent() const
Returns the spatial and temporal extents associated with the resource.
void setExtent(const QgsLayerMetadata::Extent &extent)
Sets the spatial and temporal extents associated with the resource.
QgsCoordinateReferenceSystem extentCrs
Coordinate reference system for spatial extent.
void setYMaximum(double y)
Sets the maximum y value.
Definition: qgsbox3d.cpp:55
QString type
Constraint type.
Metadata constraint structure.
bool operator==(const QgsLayerMetadata &metadataOther) const
bool readMetadataXml(const QDomElement &metadataElement) override
Sets state from DOM document.
bool equals(const QgsAbstractMetadataBase &other) const
Tests whether the common metadata fields in this object are equal to other.
QgsLayerMetadata()=default
Constructor for QgsLayerMetadata.
void setConstraints(const QgsLayerMetadata::ConstraintList &constraints)
Sets the list of constraints associated with using the resource.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:225
bool operator==(const QgsLayerMetadata::Extent &other) const
void setFees(const QString &fees)
Sets the fees associated with using the resource.
Metadata extent structure.
virtual bool writeMetadataXml(QDomElement &metadataElement, QDomDocument &document) const
Stores state in a DOM node.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the coordinate reference system for the layer&#39;s metadata.
QgsAbstractMetadataBase::KeywordMap mKeywords
Keywords map.
void setRights(const QStringList &rights)
Sets a list of rights (attribution or copyright strings) associated with the resource.
void setZMinimum(double z)
Sets the minimum z value.
Definition: qgsbox3d.cpp:60
bool writeMetadataXml(QDomElement &metadataElement, QDomDocument &document) const override
Stores state in a DOM node.
A structured metadata store for a map layer.
bool operator==(const QgsLayerMetadata::SpatialExtent &other) const
void setSpatialExtents(const QList< QgsLayerMetadata::SpatialExtent > &extents)
Sets the spatial extents of the resource.
void setYMinimum(double y)
Sets the minimum y value.
Definition: qgsbox3d.cpp:50
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
QgsLayerMetadata * clone() const override
Clones the metadata object.
QgsLayerMetadata::ConstraintList constraints() const
Returns a list of constraints associated with using the resource.
QMap< QString, QStringList > KeywordMap
Map of vocabulary string to keyword list.
QgsBox3d bounds
Geospatial extent of the resource.
This class represents a coordinate reference system (CRS).
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system described by the layer&#39;s metadata.
void readFromLayer(const QgsMapLayer *layer)
Reads the metadata state from a layer&#39;s custom properties (see QgsMapLayer::customProperty() )...
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
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 encoding() const
Returns the character encoding of the data in the resource.
QString fees() const
Returns any fees associated with using the resource.
void setEncoding(const QString &encoding)
Sets the character encoding of the data in the resource.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
QString constraint
Free-form constraint string.
bool operator==(const QgsLayerMetadata::Constraint &other) const
QList< QgsLayerMetadata::Constraint > ConstraintList
A list of constraints.
Metadata spatial extent structure.
QString authid() const
Returns the authority identifier for the CRS.
void setTemporalExtents(const QList< QgsDateTimeRange > &extents)
Sets the temporal extents of the resource.
void setZMaximum(double z)
Sets the maximum z value.
Definition: qgsbox3d.cpp:65