Branch data Line data Source code
1 : : /***************************************************************************
2 : : QgsAbstractMetadataBase.h
3 : : -------------------
4 : : begin : March 2018
5 : : copyright : (C) 2018 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 : : #ifndef QGSABSTRACTMETADATABASE_H
19 : : #define QGSABSTRACTMETADATABASE_H
20 : :
21 : : #include "qgis_sip.h"
22 : : #include "qgis_core.h"
23 : : #include <QMap>
24 : : #include <QString>
25 : : #include <QMetaType>
26 : :
27 : : class QDomElement;
28 : : class QDomDocument;
29 : :
30 : : /**
31 : : * \ingroup core
32 : : * \class QgsAbstractMetadataBase
33 : : * \brief An abstract base class for metadata stores.
34 : : *
35 : : * QgsAbstractMetadataBase is the base class for handling storage and management of the metadata
36 : : * for various map related assets. This class is an internal QGIS format with a common
37 : : * metadata structure. It is subclassed by layer and project specific metadata classes,
38 : : * such as QgsLayerMetadata and QgsProjectMetadata.
39 : : *
40 : : * The metadata store is designed to be compatible with the Dublin Core metadata
41 : : * specifications, and will be expanded to allow compatibility with ISO specifications
42 : : * in future releases. However, the QGIS internal schema does not represent a superset
43 : : * of all existing metadata schemas and accordingly conversion from specific
44 : : * metadata formats to QgsAbstractMetadataBase may result in a loss of information.
45 : : *
46 : : * This class is designed to follow the specifications detailed in
47 : : * the schema definition available at resources/qgis-base-metadata.xsd
48 : : * within the QGIS source code.
49 : : *
50 : : * Metadata can be validated through the use of QgsAbstractMetadataBaseValidator
51 : : * subclasses. E.g. validating against the native QGIS metadata schema can be performed
52 : : * using QgsNativeMetadataValidator.
53 : : *
54 : : * \since QGIS 3.2
55 : : */
56 : 136 : class CORE_EXPORT QgsAbstractMetadataBase
57 : : {
58 : :
59 : : #ifdef SIP_RUN
60 : : SIP_CONVERT_TO_SUBCLASS_CODE
61 : : if ( dynamic_cast< QgsLayerMetadata * >( sipCpp ) != NULL )
62 : : sipType = sipType_QgsLayerMetadata;
63 : : else if ( dynamic_cast< QgsProjectMetadata * >( sipCpp ) != NULL )
64 : : sipType = sipType_QgsProjectMetadata;
65 : : else
66 : : sipType = NULL;
67 : : SIP_END
68 : : #endif
69 : :
70 : : public:
71 : :
72 : : // NOTE - these really belong in a separate namespace, but SIP says no, I want to make you waste more time
73 : : // TODO: dump sip
74 : :
75 : : /**
76 : : * Map of vocabulary string to keyword list.
77 : : */
78 : : typedef QMap< QString, QStringList > KeywordMap;
79 : :
80 : : /**
81 : : * \brief Metadata address structure.
82 : : * \ingroup core
83 : : * \since QGIS 3.2
84 : : */
85 : 0 : struct CORE_EXPORT Address
86 : : {
87 : :
88 : : /**
89 : : * Constructor for Address.
90 : : */
91 : 0 : Address( const QString &type = QString(), const QString &address = QString(), const QString &city = QString(), const QString &administrativeArea = QString(), const QString &postalCode = QString(), const QString &country = QString() )
92 : 0 : : type( type )
93 : 0 : , address( address )
94 : 0 : , city( city )
95 : 0 : , administrativeArea( administrativeArea )
96 : 0 : , postalCode( postalCode )
97 : 0 : , country( country )
98 : 0 : {}
99 : :
100 : : /**
101 : : * Type of address, e.g. 'postal'.
102 : : */
103 : : QString type;
104 : :
105 : : /**
106 : : * Free-form physical address component, e.g. '221B Baker St' or 'P.O. Box 196'.
107 : : */
108 : : QString address;
109 : :
110 : : /**
111 : : * City or locality name.
112 : : */
113 : : QString city;
114 : :
115 : : /**
116 : : * Administrative area (state, province/territory, etc.).
117 : : */
118 : : QString administrativeArea;
119 : :
120 : : /**
121 : : * Postal (or ZIP) code.
122 : : */
123 : : QString postalCode;
124 : :
125 : : /**
126 : : * Free-form country string.
127 : : */
128 : : QString country;
129 : :
130 : : bool operator==( const QgsAbstractMetadataBase::Address &other ) const;
131 : : };
132 : :
133 : : /**
134 : : * \brief Metadata contact structure.
135 : : * \ingroup core
136 : : * \since QGIS 3.2
137 : : */
138 : 0 : struct CORE_EXPORT Contact
139 : : {
140 : :
141 : : /**
142 : : * Constructor for Contact.
143 : : */
144 : 0 : Contact( const QString &name = QString() )
145 : 0 : : name( name )
146 : 0 : {}
147 : :
148 : : /**
149 : : * Name of contact.
150 : : */
151 : : QString name;
152 : :
153 : : /**
154 : : * Organization contact belongs to/represents.
155 : : */
156 : : QString organization;
157 : :
158 : : /**
159 : : * Position/title of contact.
160 : : */
161 : : QString position;
162 : :
163 : : /**
164 : : * List of addresses associated with this contact.
165 : : */
166 : : QList< QgsAbstractMetadataBase::Address > addresses;
167 : :
168 : : /**
169 : : * Voice telephone.
170 : : */
171 : : QString voice;
172 : :
173 : : /**
174 : : * Facsimile telephone.
175 : : */
176 : : QString fax;
177 : :
178 : : /**
179 : : * Electronic mail address.
180 : : * \note Do not include mailto: protocol as part of the email address.
181 : : */
182 : : QString email;
183 : :
184 : : /**
185 : : * Role of contact. Acceptable values are those from the ISO 19115 CI_RoleCode specifications
186 : : * (see http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml).
187 : : * E.g. 'custodian', 'owner', 'distributor', etc.
188 : : */
189 : : QString role;
190 : :
191 : : bool operator==( const QgsAbstractMetadataBase::Contact &other ) const;
192 : : };
193 : :
194 : : /**
195 : : * \brief A list of contacts.
196 : : * \ingroup core
197 : : * \since QGIS 3.2
198 : : */
199 : : typedef QList< QgsAbstractMetadataBase::Contact > ContactList;
200 : :
201 : :
202 : : /**
203 : : * \brief Metadata link structure.
204 : : * \ingroup core
205 : : * \since QGIS 3.2
206 : : */
207 : 0 : struct CORE_EXPORT Link
208 : : {
209 : :
210 : : /**
211 : : * Constructor for Link.
212 : : */
213 : 0 : Link( const QString &name = QString(), const QString &type = QString(), const QString &url = QString() )
214 : 0 : : name( name )
215 : 0 : , type( type )
216 : 0 : , url( url )
217 : 0 : {}
218 : :
219 : : /**
220 : : * Short link name. E.g. WMS layer name.
221 : : */
222 : : QString name;
223 : :
224 : : /**
225 : : * Link type. It is strongly suggested to use values from the 'identifier'
226 : : * column in https://github.com/OSGeo/Cat-Interop/blob/master/LinkPropertyLookupTable.csv
227 : : */
228 : : QString type;
229 : :
230 : : /**
231 : : * Abstract text about link.
232 : : */
233 : : QString description;
234 : :
235 : : /**
236 : : * Link url. If the URL is an OWS server, specify the *base* URL only without parameters like service=xxx....
237 : : */
238 : : QString url;
239 : :
240 : : /**
241 : : * Format specification of online resource. It is strongly suggested to use GDAL/OGR format values.
242 : : */
243 : : QString format;
244 : :
245 : : /**
246 : : * MIME type representative of the online resource response (image/png, application/json, etc.)
247 : : */
248 : : QString mimeType;
249 : :
250 : : /**
251 : : * Estimated size (in bytes) of the online resource response.
252 : : */
253 : : QString size;
254 : :
255 : : bool operator==( const QgsAbstractMetadataBase::Link &other ) const;
256 : : };
257 : :
258 : : /**
259 : : * \brief A list of links.
260 : : * \ingroup core
261 : : * \since QGIS 3.2
262 : : */
263 : : typedef QList< QgsAbstractMetadataBase::Link > LinkList;
264 : :
265 : 201 : virtual ~QgsAbstractMetadataBase() = default;
266 : :
267 : : /**
268 : : * Clones the metadata object.
269 : : * \since QGIS 3.2
270 : : */
271 : : virtual QgsAbstractMetadataBase *clone() const = 0 SIP_FACTORY;
272 : :
273 : : /**
274 : : * A reference, URI, URL or some other mechanism to identify the resource.
275 : : * \see setIdentifier()
276 : : */
277 : : QString identifier() const;
278 : :
279 : : /**
280 : : * Sets the reference, URI, URL or some other mechanism to identify the resource.
281 : : * \see identifier()
282 : : */
283 : : void setIdentifier( const QString &identifier );
284 : :
285 : : /**
286 : : * A reference, URI, URL or some other mechanism to identify the parent resource that this resource is a part (child) of.
287 : : * Returns an empty string if no parent identifier is set.
288 : : * \see setParentIdentifier()
289 : : */
290 : : QString parentIdentifier() const;
291 : :
292 : : /**
293 : : * Sets a reference, URI, URL or some other mechanism to identify the parent resource that this resource is a part (child) of.
294 : : * Set an empty string if no parent identifier is required.
295 : : * \see parentIdentifier()
296 : : */
297 : : void setParentIdentifier( const QString &parentIdentifier );
298 : :
299 : : /**
300 : : * Returns the human language associated with the resource. Usually the returned string
301 : : * will follow either the ISO 639.2 or ISO 3166 specifications, e.g. 'ENG' or 'SPA', however
302 : : * this is not a hard requirement and the caller must account for non compliant
303 : : * values.
304 : : * \see setLanguage()
305 : : */
306 : : QString language() const;
307 : :
308 : : /**
309 : : * Sets the human \a language associated with the resource. While a formal vocabulary is not imposed,
310 : : * ideally values should be taken from the ISO 639.2 or ISO 3166 specifications,
311 : : * e.g. 'ENG' or 'SPA' (ISO 639.2) or 'EN-AU' (ISO 3166).
312 : : * \see language()
313 : : */
314 : : void setLanguage( const QString &language );
315 : :
316 : : /**
317 : : * Returns the nature of the resource. While a formal vocabulary is not imposed, it is advised
318 : : * to use the ISO 19115 MD_ScopeCode values. E.g. 'dataset' or 'series'.
319 : : * \see setType()
320 : : */
321 : : QString type() const;
322 : :
323 : : /**
324 : : * Sets the \a type (nature) of the resource. While a formal vocabulary is not imposed, it is advised
325 : : * to use the ISO 19115 MD_ScopeCode values. E.g. 'dataset' or 'series'.
326 : : * \see type()
327 : : */
328 : : void setType( const QString &type );
329 : :
330 : : /**
331 : : * Returns the human readable name of the resource, typically displayed in search results.
332 : : * \see setTitle()
333 : : */
334 : : QString title() const;
335 : :
336 : : /**
337 : : * Sets the human readable \a title (name) of the resource, typically displayed in search results.
338 : : * \see title()
339 : : */
340 : : void setTitle( const QString &title );
341 : :
342 : : /**
343 : : * Returns a free-form description of the resource.
344 : : * \see setAbstract()
345 : : */
346 : : QString abstract() const;
347 : :
348 : : /**
349 : : * Sets a free-form \a abstract (description) of the resource.
350 : : * \see abstract()
351 : : */
352 : : void setAbstract( const QString &abstract );
353 : :
354 : : /**
355 : : * Returns a freeform description of the history or lineage of the resource.
356 : : * \see setHistory()
357 : : */
358 : : QStringList history() const;
359 : :
360 : : /**
361 : : * Sets the freeform description of the \a history or lineage of the resource.
362 : : * Any existing history items will be overwritten.
363 : : * \see addHistoryItem()
364 : : * \see history()
365 : : */
366 : : void setHistory( const QStringList &history );
367 : :
368 : : /**
369 : : * Adds a single history \a text to the end of the existing history list.
370 : : * \see history()
371 : : * \see setHistory()
372 : : */
373 : : void addHistoryItem( const QString &text );
374 : :
375 : : /**
376 : : * Returns the keywords map, which is a set of descriptive keywords associated with the resource.
377 : : *
378 : : * The map key is the vocabulary string and map value is a list of keywords for that vocabulary.
379 : : *
380 : : * The vocabulary string is a reference (URI/URL preferred) to a codelist or vocabulary
381 : : * associated with keyword list.
382 : : *
383 : : * \see setKeywords()
384 : : * \see keywordVocabularies()
385 : : */
386 : : QgsAbstractMetadataBase::KeywordMap keywords() const;
387 : :
388 : : /**
389 : : * Sets the \a keywords map, which is a set of descriptive keywords associated with the resource.
390 : : *
391 : : * The map key is the vocabulary string and map value is a list of keywords for that vocabulary.
392 : : * Calling this replaces any existing keyword vocabularies.
393 : : *
394 : : * The vocabulary string is a reference (URI/URL preferred) to a codelist or vocabulary
395 : : * associated with keyword list.
396 : : *
397 : : * \see keywords()
398 : : * \see addKeywords()
399 : : */
400 : : void setKeywords( const QgsAbstractMetadataBase::KeywordMap &keywords );
401 : :
402 : : /**
403 : : * Adds a list of descriptive \a keywords for a specified \a vocabulary. Any existing
404 : : * keywords for the same vocabulary will be replaced. Other vocabularies
405 : : * will not be affected.
406 : : *
407 : : * The vocabulary string is a reference (URI/URL preferred) to a codelist or vocabulary
408 : : * associated with keyword list.
409 : : *
410 : : * \see setKeywords()
411 : : */
412 : : void addKeywords( const QString &vocabulary, const QStringList &keywords );
413 : :
414 : : /**
415 : : * Remove a vocabulary from the list.
416 : : *
417 : : * \see setKeywords()
418 : : * \see addKeywords()
419 : : */
420 : : bool removeKeywords( const QString &vocabulary );
421 : :
422 : : /**
423 : : * Returns a list of keyword vocabularies contained in the metadata.
424 : : *
425 : : * The vocabulary string is a reference (URI/URL preferred) to a codelist or vocabulary
426 : : * associated with keyword list.
427 : : *
428 : : * \see keywords()
429 : : */
430 : : QStringList keywordVocabularies() const;
431 : :
432 : : /**
433 : : * Returns a list of keywords for the specified \a vocabulary.
434 : : * If the vocabulary is not contained in the metadata, an empty
435 : : * list will be returned.
436 : : *
437 : : * The vocabulary string is a reference (URI/URL preferred) to a codelist or vocabulary
438 : : * associated with keyword list.
439 : : *
440 : : * \see keywordVocabularies()
441 : : */
442 : : QStringList keywords( const QString &vocabulary ) const;
443 : :
444 : : /**
445 : : * Returns categories of the resource.
446 : : * Categories are stored using a special vocabulary 'gmd:topicCategory' in keywords.
447 : : *
448 : : * \see keywords()
449 : : */
450 : : QStringList categories() const;
451 : :
452 : : /**
453 : : * Sets categories of the resource.
454 : : * Categories are stored using a special vocabulary 'gmd:topicCategory' in keywords.
455 : : *
456 : : * \see keywords()
457 : : */
458 : : void setCategories( const QStringList &categories );
459 : :
460 : : /**
461 : : * Returns a list of contact persons or entities associated with the resource.
462 : : * \see setContacts()
463 : : */
464 : : QgsAbstractMetadataBase::ContactList contacts() const;
465 : :
466 : : /**
467 : : * Sets the list of \a contacts or entities associated with the resource. Any existing contacts
468 : : * will be replaced.
469 : : * \see contacts()
470 : : * \see addContact()
471 : : */
472 : : void setContacts( const QgsAbstractMetadataBase::ContactList &contacts );
473 : :
474 : : /**
475 : : * Adds an individual \a contact to the existing contacts.
476 : : * \see contacts()
477 : : * \see setContacts()
478 : : */
479 : : void addContact( const QgsAbstractMetadataBase::Contact &contact );
480 : :
481 : : /**
482 : : * Returns a list of online resources associated with the resource.
483 : : * \see setLinks()
484 : : */
485 : : QgsAbstractMetadataBase::LinkList links() const;
486 : :
487 : : /**
488 : : * Sets the list of online resources associated with the resource. Any existing links
489 : : * will be replaced.
490 : : * \see links()
491 : : * \see addLink()
492 : : */
493 : : void setLinks( const QgsAbstractMetadataBase::LinkList &links );
494 : :
495 : : /**
496 : : * Adds an individual \a link to the existing links.
497 : : * \see links()
498 : : * \see setLinks()
499 : : */
500 : : void addLink( const QgsAbstractMetadataBase::Link &link );
501 : :
502 : : /**
503 : : * Sets state from DOM document.
504 : : *
505 : : * \param metadataElement The DOM element corresponding to ``resourceMetadata'' tag
506 : : *
507 : : * \returns TRUE if successful
508 : : *
509 : : * Subclasses which override this method should take care to also call the base
510 : : * class method in order to read common metadata properties.
511 : : */
512 : : virtual bool readMetadataXml( const QDomElement &metadataElement );
513 : :
514 : : /**
515 : : * Stores state in a DOM node.
516 : : *
517 : : * \param metadataElement is a DOM element corresponding to ``resourceMetadata'' tag
518 : : * \param document is a the DOM document being written
519 : : *
520 : : * \returns TRUE if successful
521 : : *
522 : : * Subclasses which override this method should take care to also call the base
523 : : * class method in order to write common metadata properties.
524 : : */
525 : : virtual bool writeMetadataXml( QDomElement &metadataElement, QDomDocument &document ) const;
526 : :
527 : : protected:
528 : :
529 : : /**
530 : : * Constructor for QgsAbstractMetadataBase.
531 : : *
532 : : * QgsAbstractMetadataBase cannot be instantiated directly, it must be subclassed.
533 : : */
534 : 160 : QgsAbstractMetadataBase() = default;
535 : :
536 : : /*
537 : : * IMPORTANT!!!!!!
538 : : *
539 : : * Do NOT add anything to this class without also updating the schema
540 : : * definition located at resources/qgis-resource-metadata.xsd
541 : : *
542 : : */
543 : :
544 : : QString mIdentifier;
545 : : QString mParentIdentifier;
546 : : QString mLanguage;
547 : : QString mType;
548 : : QString mTitle;
549 : : QString mAbstract;
550 : : QStringList mHistory;
551 : :
552 : : // IMPORTANT - look up before adding anything here!!
553 : :
554 : : /**
555 : : * Keywords map. Key is the vocabulary, value is a list of keywords for that vocabulary.
556 : : */
557 : : QgsAbstractMetadataBase::KeywordMap mKeywords;
558 : :
559 : : QgsAbstractMetadataBase::ContactList mContacts;
560 : :
561 : : QgsAbstractMetadataBase::LinkList mLinks;
562 : :
563 : : /*
564 : : * IMPORTANT!!!!!!
565 : : *
566 : : * Do NOT add anything to this class without also updating the schema
567 : : * definition located at resources/qgis-resource-metadata.xsd
568 : : *
569 : : */
570 : :
571 : :
572 : : /**
573 : : * Tests whether the common metadata fields in this object are equal to \a other.
574 : : *
575 : : * Subclasses should utilize this method from their equality operators to test
576 : : * equality of base class members.
577 : : *
578 : : * \since QGIS 3.2
579 : : */
580 : : bool equals( const QgsAbstractMetadataBase &other ) const;
581 : :
582 : : };
583 : :
584 : 0 : Q_DECLARE_METATYPE( QgsAbstractMetadataBase::KeywordMap )
585 : 0 : Q_DECLARE_METATYPE( QgsAbstractMetadataBase::ContactList )
586 : 0 : Q_DECLARE_METATYPE( QgsAbstractMetadataBase::LinkList )
587 : :
588 : : #endif // QGSABSTRACTMETADATABASE_H
|