1 /*************************************************************************** 2 qgslayermetadata.h 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 #ifndef QGSLAYERMETADATA_H 19 #define QGSLAYERMETADATA_H 20 21 #include "qgis_sip.h" 22 #include "qgis_core.h" 23 #include "qgscoordinatereferencesystem.h" 24 #include "qgsbox3d.h" 25 #include "qgsrange.h" 26 #include "qgsabstractmetadatabase.h" 27 28 class QgsMapLayer; 29 30 /** 31 * \ingroup core 32 * \class QgsLayerMetadata 33 * \brief A structured metadata store for a map layer. 34 * 35 * QgsLayerMetadata handles storage and management of the metadata 36 * for a QgsMapLayer. This class is an internal QGIS format with a common 37 * metadata structure, which allows for code to access the metadata properties for 38 * layers in a uniform way. 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 QgsLayerMetadata 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-resource-metadata.xsd 48 * within the QGIS source code. 49 * 50 * Metadata can be validated through the use of QgsLayerMetadataValidator 51 * subclasses. E.g. validating against the native QGIS metadata schema can be performed 52 * using QgsNativeMetadataValidator. 53 * 54 * \since QGIS 3.0 55 */ 56 class CORE_EXPORT QgsLayerMetadata : public QgsAbstractMetadataBase 57 { 58 public: 59 60 /** 61 * Metadata spatial extent structure. 62 */ 63 struct CORE_EXPORT SpatialExtent 64 { 65 66 /** 67 * Coordinate reference system for spatial extent. 68 * The CRS should match the CRS defined in the QgsLayerMetadata CRS property. 69 * \see QgsLayerMetadata::crs() 70 * \see spatial 71 */ 72 QgsCoordinateReferenceSystem extentCrs; 73 74 /** 75 * Geospatial extent of the resource. X and Y coordinates are in the 76 * CRS defined by the metadata (see extentCrs). 77 * 78 * While the spatial extent can include a Z dimension, this is not 79 * compulsory. 80 * \see extentCrs 81 */ 82 QgsBox3d bounds; 83 84 bool operator==( const QgsLayerMetadata::SpatialExtent &other ) const; 85 }; 86 87 /** 88 * Metadata extent structure. 89 */ 90 struct CORE_EXPORT Extent 91 { 92 public: 93 94 /** 95 * Spatial extents of the resource. 96 * \see setSpatialExtents() 97 */ 98 QList< QgsLayerMetadata::SpatialExtent > spatialExtents() const; 99 100 /** 101 * Sets the spatial \a extents of the resource. 102 * \see spatialExtents() 103 */ 104 void setSpatialExtents( const QList< QgsLayerMetadata::SpatialExtent > &extents ); 105 106 /** 107 * Temporal extents of the resource. Use QgsDateTimeRange::isInstant() to determine 108 * whether the temporal extent is a range or a single point in time. 109 * If QgsDateTimeRange::isInfinite() returns TRUE then the temporal extent 110 * is considered to be indeterminate and continuous. 111 * \see setTemporalExtents() 112 */ 113 QList< QgsDateTimeRange > temporalExtents() const; 114 115 /** 116 * Sets the temporal \a extents of the resource. 117 * \see temporalExtents() 118 */ 119 void setTemporalExtents( const QList< QgsDateTimeRange > &extents ); 120 121 bool operator==( const QgsLayerMetadata::Extent &other ) const; 122 123 #ifndef SIP_RUN 124 private: 125 126 QList< QgsLayerMetadata::SpatialExtent > mSpatialExtents; 127 QList< QgsDateTimeRange > mTemporalExtents; 128 129 #endif 130 131 }; 132 133 /** 134 * Metadata constraint structure. 135 */ 136 struct CORE_EXPORT Constraint 137 { 138 139 /** 140 * Constructor for Constraint. 141 */ 142 Constraint( const QString &constraint = QString(), const QString &type = QString() ) typeConstraint143 : type( type ) 144 , constraint( constraint ) 145 {} 146 147 /** 148 * Constraint type. Standard values include 'access' and 'other', however any 149 * string can be used for the type. 150 */ 151 QString type; 152 153 /** 154 * Free-form constraint string. 155 */ 156 QString constraint; 157 158 bool operator==( const QgsLayerMetadata::Constraint &other ) const; 159 160 }; 161 162 /** 163 * A list of constraints. 164 */ 165 typedef QList< QgsLayerMetadata::Constraint > ConstraintList; 166 167 /** 168 * Constructor for QgsLayerMetadata. 169 */ 170 QgsLayerMetadata() = default; 171 172 QgsLayerMetadata *clone() const override SIP_FACTORY; 173 174 /** 175 * Returns any fees associated with using the resource. 176 * An empty string will be returned if no fees are set. 177 * \see setFees() 178 */ 179 QString fees() const; 180 181 /** 182 * Sets the \a fees associated with using the resource. 183 * Use an empty string if no fees are set. 184 * \see fees() 185 */ 186 void setFees( const QString &fees ); 187 188 /** 189 * Returns a list of constraints associated with using the resource. 190 * \see setConstraints() 191 */ 192 QgsLayerMetadata::ConstraintList constraints() const; 193 194 /** 195 * Adds an individual constraint to the existing constraints. 196 * \see constraints() 197 * \see setConstraints() 198 */ 199 void addConstraint( const QgsLayerMetadata::Constraint &constraint ); 200 201 /** 202 * Sets the list of \a constraints associated with using the resource. 203 * \see constraints() 204 */ 205 void setConstraints( const QgsLayerMetadata::ConstraintList &constraints ); 206 207 /** 208 * Returns a list of attribution or copyright strings associated with the resource. 209 * \see setRights() 210 */ 211 QStringList rights() const; 212 213 /** 214 * Sets a list of \a rights (attribution or copyright strings) associated with the resource. 215 * \see rights() 216 */ 217 void setRights( const QStringList &rights ); 218 219 /** 220 * Returns a list of licenses associated with the resource (examples: http://opendefinition.org/licenses/). 221 * \see setLicenses() 222 */ 223 QStringList licenses() const; 224 225 /** 226 * Sets a list of \a licenses associated with the resource. 227 * (examples: http://opendefinition.org/licenses/). 228 * \see licenses() 229 */ 230 void setLicenses( const QStringList &licenses ); 231 232 /** 233 * Returns the character encoding of the data in the resource. An empty string will be returned if no encoding is set. 234 * \see setEncoding() 235 */ 236 QString encoding() const; 237 238 /** 239 * Sets the character \a encoding of the data in the resource. Use an empty string if no encoding is set. 240 * \see encoding() 241 */ 242 void setEncoding( const QString &encoding ); 243 244 /** 245 * Returns the spatial and temporal extents associated with the resource. 246 * \see setExtent() 247 */ 248 SIP_SKIP const QgsLayerMetadata::Extent &extent() const; 249 250 /** 251 * Returns the spatial and temporal extents associated with the resource. 252 * \see setExtent() 253 */ 254 QgsLayerMetadata::Extent &extent(); 255 256 /** 257 * Sets the spatial and temporal extents associated with the resource. 258 * \see setExtent() 259 */ 260 void setExtent( const QgsLayerMetadata::Extent &extent ); 261 262 /** 263 * Returns the coordinate reference system described by the layer's metadata. 264 * 265 * Note that this has no link to QgsMapLayer::crs(). While in most cases these 266 * two systems are likely to be identical, it is possible to have a layer 267 * with a different CRS described by it's accompanying metadata versus the 268 * CRS which is actually used to display and manipulate the layer within QGIS. 269 * This may be the case when a layer has an incorrect CRS within its metadata 270 * and a user has manually overridden the layer's CRS within QGIS. 271 * 272 * The CRS described here should either match the CRS from the layer QgsMapLayer::crs() 273 * or the CRS from the data provider. 274 * 275 * This property should also match the CRS property used in the spatial extent. 276 * 277 * \see setCrs() 278 */ 279 QgsCoordinateReferenceSystem crs() const; 280 281 /** 282 * Sets the coordinate reference system for the layer's metadata. 283 * 284 * Note that this has no link to QgsMapLayer::setCrs(). Setting the layer's 285 * CRS via QgsMapLayer::setCrs() does not affect the layer's metadata CRS, 286 * and changing the CRS from the metadata will not change the layer's 287 * CRS or how it is projected within QGIS. 288 * 289 * While ideally these two systems are likely to be identical, it is possible to have a layer 290 * with a different CRS described by it's accompanying metadata versus the 291 * CRS which is actually used to display and manipulate the layer within QGIS. 292 * This may be the case when a layer has an incorrect CRS within its metadata 293 * and a user has manually overridden the layer's CRS within QGIS. 294 * 295 * The CRS described here should either match the CRS from the layer QgsMapLayer::crs() 296 * or the CRS from the data provider. 297 * 298 * This property should also match the CRS property used in the spatial extent. 299 * 300 * \see crs() 301 */ 302 void setCrs( const QgsCoordinateReferenceSystem &crs ); 303 304 /** 305 * Saves the metadata to a \a layer's custom properties (see QgsMapLayer::setCustomProperty() ). 306 * \see readFromLayer() 307 */ 308 void saveToLayer( QgsMapLayer *layer ) const; 309 310 /** 311 * Reads the metadata state from a \a layer's custom properties (see QgsMapLayer::customProperty() ). 312 * \see saveToLayer() 313 */ 314 void readFromLayer( const QgsMapLayer *layer ); 315 316 bool readMetadataXml( const QDomElement &metadataElement ) override; 317 bool writeMetadataXml( QDomElement &metadataElement, QDomDocument &document ) const override; 318 319 bool operator==( const QgsLayerMetadata &metadataOther ) const; 320 321 private: 322 323 /* 324 * IMPORTANT!!!!!! 325 * 326 * Do NOT add anything to this class without also updating the schema 327 * definition located at resources/qgis-resource-metadata.xsd 328 * 329 */ 330 331 QString mFees; 332 ConstraintList mConstraints; 333 QStringList mRights; 334 QStringList mLicenses; 335 336 // IMPORTANT - look up before adding anything here!! 337 338 QString mEncoding; 339 QgsCoordinateReferenceSystem mCrs; 340 341 Extent mExtent; 342 343 /* 344 * IMPORTANT!!!!!! 345 * 346 * Do NOT add anything to this class without also updating the schema 347 * definition located at resources/qgis-resource-metadata.xsd 348 * 349 */ 350 351 }; 352 353 Q_DECLARE_METATYPE( QgsLayerMetadata::ConstraintList ) 354 Q_DECLARE_METATYPE( QgsLayerMetadata::Extent ) 355 356 #endif // QGSLAYERMETADATA_H 357