QGIS API Documentation  3.0.2-Girona (307d082)
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 mIdentifier;
24 }
25 
27 {
28  mIdentifier = identifier;
29 }
30 
32 {
33  return mParentIdentifier;
34 }
35 
37 {
38  mParentIdentifier = parentIdentifier;
39 }
40 
41 QString QgsLayerMetadata::type() const
42 {
43  return mType;
44 }
45 
46 void QgsLayerMetadata::setType( const QString &type )
47 {
48  mType = type;
49 }
50 
51 QString QgsLayerMetadata::title() const
52 {
53  return mTitle;
54 }
55 
56 void QgsLayerMetadata::setTitle( const QString &title )
57 {
58  mTitle = title;
59 }
60 
62 {
63  return mAbstract;
64 }
65 
66 void QgsLayerMetadata::setAbstract( const QString &abstract )
67 {
68  mAbstract = abstract;
69 }
70 
71 QString QgsLayerMetadata::fees() const
72 {
73  return mFees;
74 }
75 
76 void QgsLayerMetadata::setFees( const QString &fees )
77 {
78  mFees = fees;
79 }
80 
82 {
83  mConstraints << constraint;
84 }
85 
86 QList<QgsLayerMetadata::Constraint> QgsLayerMetadata::constraints() const
87 {
88  return mConstraints;
89 }
90 
91 void QgsLayerMetadata::setConstraints( const QList<Constraint> &constraints )
92 {
93  mConstraints = constraints;
94 }
95 
96 QStringList QgsLayerMetadata::rights() const
97 {
98  return mRights;
99 }
100 
101 void QgsLayerMetadata::setRights( const QStringList &rights )
102 {
103  mRights = rights;
104 }
105 
106 QStringList QgsLayerMetadata::licenses() const
107 {
108  return mLicenses;
109 }
110 
111 void QgsLayerMetadata::setLicenses( const QStringList &licenses )
112 {
113  mLicenses = licenses;
114 }
115 
116 QStringList QgsLayerMetadata::history() const
117 {
118  return mHistory;
119 }
120 
121 void QgsLayerMetadata::setHistory( const QStringList &history )
122 {
123  mHistory = history;
124 }
125 
126 void QgsLayerMetadata::addHistoryItem( const QString &text )
127 {
128  mHistory << text;
129 }
130 
132 {
133  return mEncoding;
134 }
135 
137 {
138  mEncoding = encoding;
139 }
140 
142 {
143  return mCrs;
144 }
145 
147 {
148  mCrs = crs;
149 }
150 
151 QMap<QString, QStringList> QgsLayerMetadata::keywords() const
152 {
153  return mKeywords;
154 }
155 
156 void QgsLayerMetadata::setKeywords( const QMap<QString, QStringList> &keywords )
157 {
158  mKeywords = keywords;
159 }
160 
161 void QgsLayerMetadata::addKeywords( const QString &vocabulary, const QStringList &keywords )
162 {
163  mKeywords.insert( vocabulary, keywords );
164 }
165 
166 bool QgsLayerMetadata::removeKeywords( const QString &vocabulary )
167 {
168  return mKeywords.remove( vocabulary );
169 }
170 
172 {
173  return mKeywords.keys();
174 }
175 
176 QStringList QgsLayerMetadata::keywords( const QString &vocabulary ) const
177 {
178  return mKeywords.value( vocabulary );
179 }
180 
181 QStringList QgsLayerMetadata::categories() const
182 {
183  if ( mKeywords.contains( QStringLiteral( "gmd:topicCategory" ) ) )
184  {
185  return mKeywords.value( QStringLiteral( "gmd:topicCategory" ) );
186  }
187  else
188  {
189  return QStringList();
190  }
191 }
192 
193 void QgsLayerMetadata::setCategories( const QStringList &category )
194 {
195  mKeywords.insert( QStringLiteral( "gmd:topicCategory" ), category );
196 }
197 
198 QList<QgsLayerMetadata::Contact> QgsLayerMetadata::contacts() const
199 {
200  return mContacts;
201 }
202 
203 void QgsLayerMetadata::setContacts( const QList<Contact> &contacts )
204 {
205  mContacts = contacts;
206 }
207 
209 {
210  mContacts << contact;
211 }
212 
213 QList<QgsLayerMetadata::Link> QgsLayerMetadata::links() const
214 {
215  return mLinks;
216 }
217 
218 void QgsLayerMetadata::setLinks( const QList<QgsLayerMetadata::Link> &links )
219 {
220  mLinks = links;
221 }
222 
224 {
225  mLinks << link;
226 }
227 
229 {
230  return mLanguage;
231 }
232 
234 {
235  mLanguage = language;
236 }
237 
239 {
240  layer->setCustomProperty( QStringLiteral( "metadata/identifier" ), mIdentifier );
241  layer->setCustomProperty( QStringLiteral( "metadata/parentIdentifier" ), mParentIdentifier );
242  layer->setCustomProperty( QStringLiteral( "metadata/language" ), mLanguage );
243  layer->setCustomProperty( QStringLiteral( "metadata/type" ), mType );
244  layer->setCustomProperty( QStringLiteral( "metadata/title" ), mTitle );
245  layer->setCustomProperty( QStringLiteral( "metadata/extent" ), QVariant::fromValue( mExtent ) );
246  layer->setCustomProperty( QStringLiteral( "metadata/abstract" ), mAbstract );
247  layer->setCustomProperty( QStringLiteral( "metadata/fees" ), mFees );
248  layer->setCustomProperty( QStringLiteral( "metadata/rights" ), mRights );
249  layer->setCustomProperty( QStringLiteral( "metadata/licenses" ), mLicenses );
250  layer->setCustomProperty( QStringLiteral( "metadata/history" ), mHistory );
251  layer->setCustomProperty( QStringLiteral( "metadata/encoding" ), mEncoding );
252  layer->setCustomProperty( QStringLiteral( "metadata/crs" ), mCrs.authid() );
253  layer->setCustomProperty( QStringLiteral( "metadata/constraints" ), QVariant::fromValue( mConstraints ) );
254  layer->setCustomProperty( QStringLiteral( "metadata/keywords" ), QVariant::fromValue( mKeywords ) );
255  layer->setCustomProperty( QStringLiteral( "metadata/contacts" ), QVariant::fromValue( mContacts ) );
256  layer->setCustomProperty( QStringLiteral( "metadata/links" ), QVariant::fromValue( mLinks ) );
257 }
258 
260 {
261  mIdentifier = layer->customProperty( QStringLiteral( "metadata/identifier" ) ).toString();
262  mParentIdentifier = layer->customProperty( QStringLiteral( "metadata/parentIdentifier" ) ).toString();
263  mLanguage = layer->customProperty( QStringLiteral( "metadata/language" ) ).toString();
264  mType = layer->customProperty( QStringLiteral( "metadata/type" ) ).toString();
265  mTitle = layer->customProperty( QStringLiteral( "metadata/title" ) ).toString();
266  mAbstract = layer->customProperty( QStringLiteral( "metadata/abstract" ) ).toString();
267  mFees = layer->customProperty( QStringLiteral( "metadata/fees" ) ).toString();
268  mRights = layer->customProperty( QStringLiteral( "metadata/rights" ) ).toStringList();
269  mLicenses = layer->customProperty( QStringLiteral( "metadata/licenses" ) ).toStringList();
270  mHistory = layer->customProperty( QStringLiteral( "metadata/history" ) ).toStringList();
271  mEncoding = layer->customProperty( QStringLiteral( "metadata/encoding" ) ).toString();
272  QString crsAuthId = layer->customProperty( QStringLiteral( "metadata/crs" ) ).toString();
274  mExtent = layer->customProperty( QStringLiteral( "metadata/extent" ) ).value<Extent>();
275  mConstraints = layer->customProperty( QStringLiteral( "metadata/constraints" ) ).value<ConstraintList>();
276  mKeywords = layer->customProperty( QStringLiteral( "metadata/keywords" ) ).value<KeywordMap>();
277  mContacts = layer->customProperty( QStringLiteral( "metadata/contacts" ) ).value<ContactList>();
278  mLinks = layer->customProperty( QStringLiteral( "metadata/links" ) ).value<LinkList>();
279 }
280 
281 bool QgsLayerMetadata::readMetadataXml( const QDomElement &metadataElement )
282 {
283  QDomNode mnl;
284  QDomElement mne;
285 
286  // set identifier
287  mnl = metadataElement.namedItem( QStringLiteral( "identifier" ) );
288  mIdentifier = mnl.toElement().text();
289 
290  // set parent identifier
291  mnl = metadataElement.namedItem( QStringLiteral( "parentidentifier" ) );
292  mParentIdentifier = mnl.toElement().text();
293 
294  // set language
295  mnl = metadataElement.namedItem( QStringLiteral( "language" ) );
296  mLanguage = mnl.toElement().text();
297 
298  // set type
299  mnl = metadataElement.namedItem( QStringLiteral( "type" ) );
300  mType = mnl.toElement().text();
301 
302  // set title
303  mnl = metadataElement.namedItem( QStringLiteral( "title" ) );
304  mTitle = mnl.toElement().text();
305 
306  // set abstract
307  mnl = metadataElement.namedItem( QStringLiteral( "abstract" ) );
308  mAbstract = mnl.toElement().text();
309 
310  // set keywords
311  QDomNodeList keywords = metadataElement.elementsByTagName( QStringLiteral( "keywords" ) );
312  mKeywords.clear();
313  for ( int i = 0; i < keywords.size(); i++ )
314  {
315  QStringList keywordsList;
316  mnl = keywords.at( i );
317  mne = mnl.toElement();
318 
319  QDomNodeList el = mne.elementsByTagName( QStringLiteral( "keyword" ) );
320  for ( int j = 0; j < el.size(); j++ )
321  {
322  keywordsList.append( el.at( j ).toElement().text() );
323  }
324  addKeywords( mne.attribute( QStringLiteral( "vocabulary" ) ), keywordsList );
325  }
326 
327  // set fees
328  mnl = metadataElement.namedItem( QStringLiteral( "fees" ) );
329  mFees = mnl.toElement().text();
330 
331  // constraints
332  QDomNodeList constraintsList = metadataElement.elementsByTagName( QStringLiteral( "constraints" ) );
333  mConstraints.clear();
334  for ( int i = 0; i < constraintsList.size(); i++ )
335  {
336  mnl = constraintsList.at( i );
337  mne = mnl.toElement();
338  addConstraint( QgsLayerMetadata::Constraint( mne.text(), mne.attribute( QStringLiteral( "type" ) ) ) );
339  }
340 
341  // rights
342  QDomNodeList rightsNodeList = metadataElement.elementsByTagName( QStringLiteral( "rights" ) );
343  QStringList rightsList;
344  for ( int i = 0; i < rightsNodeList.size(); i++ )
345  {
346  mnl = rightsNodeList.at( i );
347  mne = mnl.toElement();
348  rightsList.append( mne.text() );
349  }
350  setRights( rightsList );
351 
352  // licenses
353  QDomNodeList licensesNodeList = metadataElement.elementsByTagName( QStringLiteral( "license" ) );
354  QStringList licensesList;
355  for ( int i = 0; i < licensesNodeList.size(); i++ )
356  {
357  mnl = licensesNodeList.at( i );
358  mne = mnl.toElement();
359  licensesList.append( mne.text() );
360  }
361  setLicenses( licensesList );
362 
363  // encoding
364  mnl = metadataElement.namedItem( QStringLiteral( "encoding" ) );
365  mEncoding = mnl.toElement().text();
366 
367  // crs
368  mnl = metadataElement.namedItem( QStringLiteral( "crs" ) );
369  if ( !mCrs.readXml( mnl ) )
371 
372  // extent
373  mnl = metadataElement.namedItem( QStringLiteral( "extent" ) );
374  QgsLayerMetadata::Extent metadataExtent;
375 
376  // spatial extent
377  QDomNodeList spatialList = mnl.toElement().elementsByTagName( QStringLiteral( "spatial" ) );
378  QList< QgsLayerMetadata::SpatialExtent > metadataSpatialExtents;
379  for ( int i = 0; i < spatialList.size(); i++ )
380  {
381  mnl = spatialList.at( i );
382  mne = mnl.toElement();
384  se.extentCrs = QgsCoordinateReferenceSystem( mne.attribute( QStringLiteral( "crs" ) ) );
385  se.bounds = QgsBox3d();
386  se.bounds.setXMinimum( mne.attribute( QStringLiteral( "minx" ) ).toDouble() );
387  se.bounds.setYMinimum( mne.attribute( QStringLiteral( "miny" ) ).toDouble() );
388  se.bounds.setZMinimum( mne.attribute( QStringLiteral( "minz" ) ).toDouble() );
389  se.bounds.setXMaximum( mne.attribute( QStringLiteral( "maxx" ) ).toDouble() );
390  se.bounds.setYMaximum( mne.attribute( QStringLiteral( "maxy" ) ).toDouble() );
391  se.bounds.setZMaximum( mne.attribute( QStringLiteral( "maxz" ) ).toDouble() );
392  metadataSpatialExtents.append( se );
393  }
394  metadataExtent.setSpatialExtents( metadataSpatialExtents );
395 
396  // temporal extent
397  mnl = metadataElement.namedItem( QStringLiteral( "extent" ) );
398  QDomNodeList temporalList = mnl.toElement().elementsByTagName( QStringLiteral( "temporal" ) );
399  QList<QgsDateTimeRange> metadataDates;
400  for ( int j = 0; j < temporalList.size(); j++ )
401  {
402  mnl = temporalList.at( j );
403  QDomNodeList instantList = mnl.toElement().elementsByTagName( QStringLiteral( "instant" ) );
404  for ( int i = 0; i < instantList.size(); i++ )
405  {
406  mnl = instantList.at( i );
407  QDateTime d = QDateTime().fromString( mnl.toElement().text(), Qt::ISODate );
408  QgsDateTimeRange date = QgsDateTimeRange( d, d );
409  metadataDates << date;
410  }
411  QDomNodeList periodList = mnl.toElement().elementsByTagName( QStringLiteral( "period" ) );
412  for ( int i = 0; i < periodList.size(); i++ )
413  {
414  QDomNode begin = periodList.at( i ).namedItem( QStringLiteral( "start" ) );
415  QDomNode end = periodList.at( i ).namedItem( QStringLiteral( "end" ) );
416  QDateTime beginDate = QDateTime().fromString( begin.toElement().text(), Qt::ISODate );
417  QDateTime endDate = QDateTime().fromString( end.toElement().text(), Qt::ISODate );
418  QgsDateTimeRange date = QgsDateTimeRange( beginDate, endDate );
419  metadataDates << date;
420  }
421  }
422  metadataExtent.setTemporalExtents( metadataDates );
423  setExtent( metadataExtent );
424 
425  // contact
426  QDomNodeList contactsList = metadataElement.elementsByTagName( QStringLiteral( "contact" ) );
427  mContacts.clear();
428  for ( int i = 0; i < contactsList.size(); i++ )
429  {
430  mnl = contactsList.at( i );
431  mne = mnl.toElement();
432 
433  QgsLayerMetadata::Contact oneContact;
434  oneContact.name = mne.namedItem( QStringLiteral( "name" ) ).toElement().text();
435  oneContact.organization = mne.namedItem( QStringLiteral( "organization" ) ).toElement().text();
436  oneContact.position = mne.namedItem( QStringLiteral( "position" ) ).toElement().text();
437  oneContact.voice = mne.namedItem( QStringLiteral( "voice" ) ).toElement().text();
438  oneContact.fax = mne.namedItem( QStringLiteral( "fax" ) ).toElement().text();
439  oneContact.email = mne.namedItem( QStringLiteral( "email" ) ).toElement().text();
440  oneContact.role = mne.namedItem( QStringLiteral( "role" ) ).toElement().text();
441 
442  QList< QgsLayerMetadata::Address > addresses;
443  QDomNodeList addressList = mne.elementsByTagName( QStringLiteral( "contactAddress" ) );
444  for ( int j = 0; j < addressList.size(); j++ )
445  {
446  QDomElement addressElement = addressList.at( j ).toElement();
447  QgsLayerMetadata::Address oneAddress;
448  oneAddress.address = addressElement.namedItem( QStringLiteral( "address" ) ).toElement().text();
449  oneAddress.administrativeArea = addressElement.namedItem( QStringLiteral( "administrativearea" ) ).toElement().text();
450  oneAddress.city = addressElement.namedItem( QStringLiteral( "city" ) ).toElement().text();
451  oneAddress.country = addressElement.namedItem( QStringLiteral( "country" ) ).toElement().text();
452  oneAddress.postalCode = addressElement.namedItem( QStringLiteral( "postalcode" ) ).toElement().text();
453  oneAddress.type = addressElement.namedItem( QStringLiteral( "type" ) ).toElement().text();
454  addresses << oneAddress;
455  }
456  oneContact.addresses = addresses;
457  addContact( oneContact );
458  }
459 
460  // links
461  mnl = metadataElement.namedItem( QStringLiteral( "links" ) );
462  mne = mnl.toElement();
463  mLinks.clear();
464  QDomNodeList el = mne.elementsByTagName( QStringLiteral( "link" ) );
465  for ( int i = 0; i < el.size(); i++ )
466  {
467  mne = el.at( i ).toElement();
468  QgsLayerMetadata::Link oneLink;
469  oneLink.name = mne.attribute( QStringLiteral( "name" ) );
470  oneLink.type = mne.attribute( QStringLiteral( "type" ) );
471  oneLink.url = mne.attribute( QStringLiteral( "url" ) );
472  oneLink.description = mne.attribute( QStringLiteral( "description" ) );
473  oneLink.format = mne.attribute( QStringLiteral( "format" ) );
474  oneLink.mimeType = mne.attribute( QStringLiteral( "mimeType" ) );
475  oneLink.size = mne.attribute( QStringLiteral( "size" ) );
476  addLink( oneLink );
477  }
478 
479  // history
480  QDomNodeList historyNodeList = metadataElement.elementsByTagName( QStringLiteral( "history" ) );
481  QStringList historyList;
482  for ( int i = 0; i < historyNodeList.size(); i++ )
483  {
484  mnl = historyNodeList.at( i );
485  mne = mnl.toElement();
486  historyList.append( mne.text() );
487  }
488  setHistory( historyList );
489 
490  return true;
491 }
492 
493 bool QgsLayerMetadata::writeMetadataXml( QDomElement &metadataElement, QDomDocument &document ) const
494 {
495  // identifier
496  QDomElement identifier = document.createElement( QStringLiteral( "identifier" ) );
497  QDomText identifierText = document.createTextNode( mIdentifier );
498  identifier.appendChild( identifierText );
499  metadataElement.appendChild( identifier );
500 
501  // parent identifier
502  QDomElement parentIdentifier = document.createElement( QStringLiteral( "parentidentifier" ) );
503  QDomText parentIdentifierText = document.createTextNode( mParentIdentifier );
504  parentIdentifier.appendChild( parentIdentifierText );
505  metadataElement.appendChild( parentIdentifier );
506 
507  // language
508  QDomElement language = document.createElement( QStringLiteral( "language" ) );
509  QDomText languageText = document.createTextNode( mLanguage );
510  language.appendChild( languageText );
511  metadataElement.appendChild( language );
512 
513  // type
514  QDomElement type = document.createElement( QStringLiteral( "type" ) );
515  QDomText typeText = document.createTextNode( mType );
516  type.appendChild( typeText );
517  metadataElement.appendChild( type );
518 
519  // title
520  QDomElement title = document.createElement( QStringLiteral( "title" ) );
521  QDomText titleText = document.createTextNode( mTitle );
522  title.appendChild( titleText );
523  metadataElement.appendChild( title );
524 
525  // abstract
526  QDomElement abstract = document.createElement( QStringLiteral( "abstract" ) );
527  QDomText abstractText = document.createTextNode( mAbstract );
528  abstract.appendChild( abstractText );
529  metadataElement.appendChild( abstract );
530 
531  // keywords
532  QMapIterator<QString, QStringList> i( mKeywords );
533  while ( i.hasNext() )
534  {
535  i.next();
536  QDomElement keywordsElement = document.createElement( QStringLiteral( "keywords" ) );
537  keywordsElement.setAttribute( QStringLiteral( "vocabulary" ), i.key() );
538  const QStringList values = i.value();
539  for ( const QString &kw : values )
540  {
541  QDomElement keyword = document.createElement( QStringLiteral( "keyword" ) );
542  QDomText keywordText = document.createTextNode( kw );
543  keyword.appendChild( keywordText );
544  keywordsElement.appendChild( keyword );
545  }
546  metadataElement.appendChild( keywordsElement );
547  }
548 
549  // fees
550  QDomElement fees = document.createElement( QStringLiteral( "fees" ) );
551  QDomText feesText = document.createTextNode( mFees );
552  fees.appendChild( feesText );
553  metadataElement.appendChild( fees );
554 
555  // constraints
556  for ( const QgsLayerMetadata::Constraint &constraint : mConstraints )
557  {
558  QDomElement constraintElement = document.createElement( QStringLiteral( "constraints" ) );
559  constraintElement.setAttribute( QStringLiteral( "type" ), constraint.type );
560  QDomText constraintText = document.createTextNode( constraint.constraint );
561  constraintElement.appendChild( constraintText );
562  metadataElement.appendChild( constraintElement );
563  }
564 
565  // rights
566  for ( const QString &right : mRights )
567  {
568  QDomElement rightElement = document.createElement( QStringLiteral( "rights" ) );
569  QDomText rightText = document.createTextNode( right );
570  rightElement.appendChild( rightText );
571  metadataElement.appendChild( rightElement );
572  }
573 
574  // license
575  for ( const QString &license : mLicenses )
576  {
577  QDomElement licenseElement = document.createElement( QStringLiteral( "license" ) );
578  QDomText licenseText = document.createTextNode( license );
579  licenseElement.appendChild( licenseText );
580  metadataElement.appendChild( licenseElement );
581  }
582 
583  // encoding
584  QDomElement encoding = document.createElement( QStringLiteral( "encoding" ) );
585  QDomText encodingText = document.createTextNode( mEncoding );
586  encoding.appendChild( encodingText );
587  metadataElement.appendChild( encoding );
588 
589  // crs
590  QDomElement crsElement = document.createElement( QStringLiteral( "crs" ) );
591  mCrs.writeXml( crsElement, document );
592  metadataElement.appendChild( crsElement );
593 
594  // extent
595  QDomElement extentElement = document.createElement( QStringLiteral( "extent" ) );
596 
597  // spatial extents
598  const QList< QgsLayerMetadata::SpatialExtent > sExtents = extent().spatialExtents();
599  for ( const QgsLayerMetadata::SpatialExtent &spatialExtent : sExtents )
600  {
601  QDomElement spatialElement = document.createElement( QStringLiteral( "spatial" ) );
602  // Dimensions fixed in the XSD
603  spatialElement.setAttribute( QStringLiteral( "dimensions" ), QStringLiteral( "2" ) );
604  spatialElement.setAttribute( QStringLiteral( "crs" ), spatialExtent.extentCrs.authid() );
605  spatialElement.setAttribute( QStringLiteral( "minx" ), qgsDoubleToString( spatialExtent.bounds.xMinimum() ) );
606  spatialElement.setAttribute( QStringLiteral( "miny" ), qgsDoubleToString( spatialExtent.bounds.yMinimum() ) );
607  spatialElement.setAttribute( QStringLiteral( "minz" ), qgsDoubleToString( spatialExtent.bounds.zMinimum() ) );
608  spatialElement.setAttribute( QStringLiteral( "maxx" ), qgsDoubleToString( spatialExtent.bounds.xMaximum() ) );
609  spatialElement.setAttribute( QStringLiteral( "maxy" ), qgsDoubleToString( spatialExtent.bounds.yMaximum() ) );
610  spatialElement.setAttribute( QStringLiteral( "maxz" ), qgsDoubleToString( spatialExtent.bounds.zMaximum() ) );
611  extentElement.appendChild( spatialElement );
612  }
613 
614  // temporal extents
615  const QList< QgsDateTimeRange > tExtents = extent().temporalExtents();
616  for ( const QgsDateTimeRange &temporalExtent : tExtents )
617  {
618  QDomElement temporalElement = document.createElement( QStringLiteral( "temporal" ) );
619  if ( temporalExtent.isInstant() )
620  {
621  QDomElement instantElement = document.createElement( QStringLiteral( "instant" ) );
622  QDomText instantText = document.createTextNode( temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
623  instantElement.appendChild( instantText );
624  temporalElement.appendChild( instantElement );
625  }
626  else
627  {
628  QDomElement periodElement = document.createElement( QStringLiteral( "period" ) );
629  QDomElement startElement = document.createElement( QStringLiteral( "start" ) );
630  QDomElement endElement = document.createElement( QStringLiteral( "end" ) );
631  QDomText startText = document.createTextNode( temporalExtent.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
632  QDomText endText = document.createTextNode( temporalExtent.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
633  startElement.appendChild( startText );
634  endElement.appendChild( endText );
635  periodElement.appendChild( startElement );
636  periodElement.appendChild( endElement );
637  temporalElement.appendChild( periodElement );
638  }
639  extentElement.appendChild( temporalElement );
640  }
641 
642  metadataElement.appendChild( extentElement );
643 
644  // contact
645  for ( const QgsLayerMetadata::Contact &contact : mContacts )
646  {
647  QDomElement contactElement = document.createElement( QStringLiteral( "contact" ) );
648  QDomElement nameElement = document.createElement( QStringLiteral( "name" ) );
649  QDomElement organizationElement = document.createElement( QStringLiteral( "organization" ) );
650  QDomElement positionElement = document.createElement( QStringLiteral( "position" ) );
651  QDomElement voiceElement = document.createElement( QStringLiteral( "voice" ) );
652  QDomElement faxElement = document.createElement( QStringLiteral( "fax" ) );
653  QDomElement emailElement = document.createElement( QStringLiteral( "email" ) );
654  QDomElement roleElement = document.createElement( QStringLiteral( "role" ) );
655 
656  QDomText nameText = document.createTextNode( contact.name );
657  QDomText orgaText = document.createTextNode( contact.organization );
658  QDomText positionText = document.createTextNode( contact.position );
659  QDomText voiceText = document.createTextNode( contact.voice );
660  QDomText faxText = document.createTextNode( contact.fax );
661  QDomText emailText = document.createTextNode( contact.email );
662  QDomText roleText = document.createTextNode( contact.role );
663 
664  for ( const QgsLayerMetadata::Address &oneAddress : contact.addresses )
665  {
666  QDomElement addressElement = document.createElement( QStringLiteral( "contactAddress" ) );
667  QDomElement typeElement = document.createElement( QStringLiteral( "type" ) );
668  QDomElement addressDetailedElement = document.createElement( QStringLiteral( "address" ) );
669  QDomElement cityElement = document.createElement( QStringLiteral( "city" ) );
670  QDomElement administrativeAreaElement = document.createElement( QStringLiteral( "administrativearea" ) );
671  QDomElement postalCodeElement = document.createElement( QStringLiteral( "postalcode" ) );
672  QDomElement countryElement = document.createElement( QStringLiteral( "country" ) );
673 
674  typeElement.appendChild( document.createTextNode( oneAddress.type ) );
675  addressDetailedElement.appendChild( document.createTextNode( oneAddress.address ) );
676  cityElement.appendChild( document.createTextNode( oneAddress.city ) );
677  administrativeAreaElement.appendChild( document.createTextNode( oneAddress.administrativeArea ) );
678  postalCodeElement.appendChild( document.createTextNode( oneAddress.postalCode ) );
679  countryElement.appendChild( document.createTextNode( oneAddress.country ) );
680 
681  addressElement.appendChild( typeElement );
682  addressElement.appendChild( addressDetailedElement );
683  addressElement.appendChild( cityElement );
684  addressElement.appendChild( administrativeAreaElement );
685  addressElement.appendChild( postalCodeElement );
686  addressElement.appendChild( countryElement );
687  contactElement.appendChild( addressElement );
688  }
689 
690  nameElement.appendChild( nameText );
691  organizationElement.appendChild( orgaText );
692  positionElement.appendChild( positionText );
693  voiceElement.appendChild( voiceText );
694  faxElement.appendChild( faxText );
695  emailElement.appendChild( emailText );
696  roleElement.appendChild( roleText );
697 
698  contactElement.appendChild( nameElement );
699  contactElement.appendChild( organizationElement );
700  contactElement.appendChild( positionElement );
701  contactElement.appendChild( voiceElement );
702  contactElement.appendChild( faxElement );
703  contactElement.appendChild( emailElement );
704  contactElement.appendChild( roleElement );
705  metadataElement.appendChild( contactElement );
706  }
707 
708  // links
709  QDomElement links = document.createElement( QStringLiteral( "links" ) );
710  for ( const QgsLayerMetadata::Link &link : mLinks )
711  {
712  QDomElement linkElement = document.createElement( QStringLiteral( "link" ) );
713  linkElement.setAttribute( QStringLiteral( "name" ), link.name );
714  linkElement.setAttribute( QStringLiteral( "type" ), link.type );
715  linkElement.setAttribute( QStringLiteral( "url" ), link.url );
716  linkElement.setAttribute( QStringLiteral( "description" ), link.description );
717  linkElement.setAttribute( QStringLiteral( "format" ), link.format );
718  linkElement.setAttribute( QStringLiteral( "mimeType" ), link.mimeType );
719  linkElement.setAttribute( QStringLiteral( "size" ), link.size );
720  links.appendChild( linkElement );
721  }
722  metadataElement.appendChild( links );
723 
724  // history
725  for ( const QString &history : mHistory )
726  {
727  QDomElement historyElement = document.createElement( QStringLiteral( "history" ) );
728  QDomText historyText = document.createTextNode( history );
729  historyElement.appendChild( historyText );
730  metadataElement.appendChild( historyElement );
731  }
732 
733  return true;
734 }
735 
737 {
738  return mExtent;
739 }
740 
742 {
743  return mExtent;
744 }
745 
747 {
748  mExtent = extent;
749 }
750 
751 QList<QgsLayerMetadata::SpatialExtent> QgsLayerMetadata::Extent::spatialExtents() const
752 {
753  return mSpatialExtents;
754 }
755 
756 void QgsLayerMetadata::Extent::setSpatialExtents( const QList<QgsLayerMetadata::SpatialExtent> &spatialExtents )
757 {
758  mSpatialExtents = spatialExtents;
759 }
760 
761 QList<QgsDateTimeRange> QgsLayerMetadata::Extent::temporalExtents() const
762 {
763  return mTemporalExtents;
764 }
765 
766 void QgsLayerMetadata::Extent::setTemporalExtents( const QList<QgsDateTimeRange> &temporalExtents )
767 {
768  mTemporalExtents = temporalExtents;
769 }
770 
772 {
773  return mSpatialExtents == other.mSpatialExtents && mTemporalExtents == other.mTemporalExtents;
774 }
775 
776 bool QgsLayerMetadata::operator==( const QgsLayerMetadata &metadataOther ) const
777 {
778  return ( ( mIdentifier == metadataOther.mIdentifier ) &&
779  ( mParentIdentifier == metadataOther.mParentIdentifier ) &&
780  ( mLanguage == metadataOther.mLanguage ) &&
781  ( mType == metadataOther.mType ) &&
782  ( mTitle == metadataOther.mTitle ) &&
783  ( mAbstract == metadataOther.mAbstract ) &&
784  ( mFees == metadataOther.mFees ) &&
785  ( mConstraints == metadataOther.mConstraints ) &&
786  ( mRights == metadataOther.mRights ) &&
787  ( mLicenses == metadataOther.mLicenses ) &&
788  ( mHistory == metadataOther.mHistory ) &&
789  ( mEncoding == metadataOther.mEncoding ) &&
790  ( mCrs == metadataOther.mCrs ) &&
791  ( mExtent == metadataOther.mExtent ) &&
792  ( mKeywords == metadataOther.mKeywords ) &&
793  ( mContacts == metadataOther.mContacts ) &&
794  ( mLinks == metadataOther.mLinks ) );
795 }
796 
798 {
799  return extentCrs == other.extentCrs &&
800  bounds == other.bounds;
801 }
802 
804 {
805  return type == other.type && constraint == other.constraint;
806 }
807 
809 {
810  return name == other.name &&
811  organization == other.organization &&
812  position == other.position &&
813  addresses == other.addresses &&
814  voice == other.voice &&
815  fax == other.fax &&
816  email == other.email &&
817  role == other.role;
818 }
819 
821 {
822  return name == other.name &&
823  type == other.type &&
824  description == other.description &&
825  url == other.url &&
826  format == other.format &&
827  mimeType == other.mimeType &&
828  size == other.size;
829 }
830 
832 {
833  return type == other.type &&
834  address == other.address &&
835  city == other.city &&
836  administrativeArea == other.administrativeArea &&
837  postalCode == other.postalCode &&
838  country == other.country;
839 }
void addContact(const QgsLayerMetadata::Contact &contact)
Adds an individual contact to the existing contacts.
Base class for all map layer types.
Definition: qgsmaplayer.h:56
QString parentIdentifier() const
A reference, URI, URL or some other mechanism to identify the parent resource that this resource is a...
QString name
Name of contact.
void setXMinimum(double x)
Sets the minimum x value.
Definition: qgsbox3d.cpp:39
void addKeywords(const QString &vocabulary, const QStringList &keywords)
Adds a list of descriptive keywords for a specified vocabulary.
void setKeywords(const KeywordMap &keywords)
Sets the keywords map, which is a set of descriptive keywords associated with the resource...
void saveToLayer(QgsMapLayer *layer) const
Saves the metadata to a layer&#39;s custom properties (see QgsMapLayer::setCustomProperty() )...
void setCategories(const QStringList &categories)
Sets categories of the resource.
void addConstraint(const QgsLayerMetadata::Constraint &constraint)
Adds an individual constraint to the existing constraints.
QString role
Role of contact.
QStringList rights() const
Returns a list of attribution or copyright strings associated with the resource.
QString position
Position/title of contact.
QString title() const
Returns the human readable name of the resource, typically displayed in search results.
QString abstract() const
Returns a free-form description of the resource.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
QString organization
Organization contact belongs to/represents.
QString fax
Facsimile telephone.
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:44
bool writeMetadataXml(QDomElement &metadataElement, QDomDocument &document) const
Stores state in Dom node.
bool removeKeywords(const QString &vocabulary)
Remove a vocabulary from the list.
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:35
QString identifier() const
A reference, URI, URL or some other mechanism to identify the resource.
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.
QList< QgsLayerMetadata::Link > LinkList
A list of links.
QgsCoordinateReferenceSystem extentCrs
Coordinate reference system for spatial extent.
void setYMaximum(double y)
Sets the maximum y value.
Definition: qgsbox3d.cpp:54
QString type
Constraint type.
void addHistoryItem(const QString &text)
Adds a single history text to the end of the existing history list.
QStringList keywordVocabularies() const
Returns a list of keyword vocabularies contained in the metadata.
QList< QgsLayerMetadata::Contact > ContactList
A list of contacts.
void setLinks(const QgsLayerMetadata::LinkList &links)
Sets the list of online resources associated with the resource.
bool operator==(const QgsLayerMetadata::Contact &other) const
QgsLayerMetadata::ContactList contacts() const
Returns a list of contact persons or entities associated with the resource.
Metadata address structure.
Metadata constraint structure.
bool operator==(const QgsLayerMetadata &metadataOther) const
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:237
QString language() const
Returns the human language associated with the resource.
bool operator==(const QgsLayerMetadata::Extent &other) const
QStringList history() const
Returns a freeform description of the history or lineage of the resource.
QString postalCode
Postal (or ZIP) code.
void setFees(const QString &fees)
Sets the fees associated with using the resource.
Metadata extent structure.
QString type() const
Returns the nature of the resource.
QString email
Electronic mail address.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the coordinate reference system for the layer&#39;s metadata.
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:59
KeywordMap keywords() const
Returns the keywords map, which is a set of descriptive keywords associated with the resource...
bool readMetadataXml(const QDomElement &metadataElement)
Sets state from Dom document.
QMap< QString, QStringList > KeywordMap
Map of vocabulary string to keyword list.
A structured metadata store for a map layer.
QString voice
Voice telephone.
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:49
QgsLayerMetadata::LinkList links() const
Returns a list of online resources associated with the resource.
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
void setContacts(const QgsLayerMetadata::ContactList &contacts)
Sets the list of contacts or entities associated with the resource.
void setAbstract(const QString &abstract)
Sets a free-form abstract (description) of the resource.
Metadata contact structure.
QgsLayerMetadata::ConstraintList constraints() const
Returns a list of constraints associated with using the resource.
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.
void setHistory(const QStringList &history)
Sets the freeform description of the history or lineage of the resource.
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system described by the layer&#39;s metadata.
bool operator==(const QgsLayerMetadata::Address &other) const
void readFromLayer(const QgsMapLayer *layer)
Reads the metadata state from a layer&#39;s custom properties (see QgsMapLayer::customProperty() )...
void setParentIdentifier(const QString &parentIdentifier)
Sets a reference, URI, URL or some other mechanism to identify the parent resource that this resource...
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QString city
City or locality name.
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.
void setLanguage(const QString &language)
Sets the human language associated with 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.
QList< QgsLayerMetadata::Address > addresses
List of addresses associated with this contact.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
QStringList categories() const
Returns categories of the resource.
QString constraint
Free-form constraint string.
bool operator==(const QgsLayerMetadata::Constraint &other) const
QList< QgsLayerMetadata::Constraint > ConstraintList
A list of constraints.
void setTitle(const QString &title)
Sets the human readable title (name) of the resource, typically displayed in search results...
Metadata spatial extent structure.
void setType(const QString &type)
Sets the type (nature) of the resource.
QString address
Free-form physical address component, e.g.
QString authid() const
Returns the authority identifier for the CRS.
void addLink(const QgsLayerMetadata::Link &link)
Adds an individual link to the existing links.
void setIdentifier(const QString &identifier)
Sets the reference, URI, URL or some other mechanism to identify the resource.
QString administrativeArea
Administrative area (state, province/territory, etc.).
QString country
Free-form country string.
QString type
Type of address, e.g.
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:64