Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsjsonutils.h 3 : : ------------- 4 : : Date : May 206 5 : : Copyright : (C) 2016 Nyall Dawson 6 : : Email : nyall dot dawson at gmail dot com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #ifndef QGSJSONUTILS_H 17 : : #define QGSJSONUTILS_H 18 : : 19 : : #include "qgis_core.h" 20 : : #include "qgsfeature.h" 21 : : #include "qgscoordinatereferencesystem.h" 22 : : #include "qgscoordinatetransform.h" 23 : : #include "qgsfields.h" 24 : : 25 : : #ifndef SIP_RUN 26 : : #include <json_fwd.hpp> 27 : : using namespace nlohmann; 28 : : #endif 29 : : 30 : : #include <QPointer> 31 : : #include <QJsonObject> 32 : : 33 : : class QTextCodec; 34 : : 35 : : /** 36 : : * \ingroup core 37 : : * \class QgsJsonExporter 38 : : * \brief Handles exporting QgsFeature features to GeoJSON features. 39 : : * 40 : : * Note that geometries will be automatically reprojected to WGS84 to match GeoJSON spec 41 : : * if either the source vector layer or source CRS is set. 42 : : * \since QGIS 2.16 43 : : */ 44 : : 45 : 0 : class CORE_EXPORT QgsJsonExporter 46 : : { 47 : : public: 48 : : 49 : : /** 50 : : * Constructor for QgsJsonExporter. 51 : : * \param vectorLayer associated vector layer (required for related attribute export) 52 : : * \param precision maximum number of decimal places to use for geometry coordinates, 53 : : * the RFC 7946 GeoJSON specification recommends limiting coordinate precision to 6 54 : : */ 55 : : QgsJsonExporter( QgsVectorLayer *vectorLayer = nullptr, int precision = 6 ); 56 : : 57 : : /** 58 : : * Sets the maximum number of decimal places to use in geometry coordinates. 59 : : * The RFC 7946 GeoJSON specification recommends limiting coordinate precision to 6 60 : : * \param precision number of decimal places 61 : : * \see precision() 62 : : */ 63 : : void setPrecision( int precision ) { mPrecision = precision; } 64 : : 65 : : /** 66 : : * Returns the maximum number of decimal places to use in geometry coordinates. 67 : : * \see setPrecision() 68 : : */ 69 : : int precision() const { return mPrecision; } 70 : : 71 : : /** 72 : : * Sets whether to include geometry in the JSON exports. 73 : : * \param includeGeometry set to FALSE to prevent geometry inclusion 74 : : * \see includeGeometry() 75 : : */ 76 : : void setIncludeGeometry( bool includeGeometry ) { mIncludeGeometry = includeGeometry; } 77 : : 78 : : /** 79 : : * Returns whether geometry will be included in the JSON exports. 80 : : * \see setIncludeGeometry() 81 : : */ 82 : : bool includeGeometry() const { return mIncludeGeometry; } 83 : : 84 : : /** 85 : : * Sets whether to include attributes in the JSON exports. 86 : : * \param includeAttributes set to FALSE to prevent attribute inclusion 87 : : * \see includeAttributes() 88 : : */ 89 : : void setIncludeAttributes( bool includeAttributes ) { mIncludeAttributes = includeAttributes; } 90 : : 91 : : /** 92 : : * Returns whether attributes will be included in the JSON exports. 93 : : * \see setIncludeAttributes() 94 : : */ 95 : : bool includeAttributes() const { return mIncludeAttributes; } 96 : : 97 : : /** 98 : : * Sets whether to include attributes of features linked via references in the JSON exports. 99 : : * \param includeRelated set to TRUE to include attributes for any related child features 100 : : * within the exported properties element. 101 : : * \note associated vector layer must be set with setVectorLayer() 102 : : * \see includeRelated() 103 : : */ 104 : 0 : void setIncludeRelated( bool includeRelated ) { mIncludeRelatedAttributes = includeRelated; } 105 : : 106 : : /** 107 : : * Returns whether attributes of related (child) features will be included in the JSON exports. 108 : : * \see setIncludeRelated() 109 : : */ 110 : : bool includeRelated() const { return mIncludeRelatedAttributes; } 111 : : 112 : : /** 113 : : * Sets whether to print original names of attributes or aliases if 114 : : * defined. 115 : : * \since QGIS 3.6 116 : : */ 117 : : void setAttributeDisplayName( bool displayName ) { mAttributeDisplayName = displayName; } 118 : : 119 : : /** 120 : : * Returns whether original names of attributes or aliases are printed. 121 : : * \since QGIS 3.6 122 : : */ 123 : : 124 : : bool attributeDisplayName() const { return mAttributeDisplayName; } 125 : : 126 : : /** 127 : : * Sets the associated vector layer (required for related attribute export). This will automatically 128 : : * update the sourceCrs() to match. 129 : : * \param vectorLayer vector layer 130 : : * \see vectorLayer() 131 : : */ 132 : : void setVectorLayer( QgsVectorLayer *vectorLayer ); 133 : : 134 : : /** 135 : : * Returns the associated vector layer, if set. 136 : : * \see setVectorLayer() 137 : : */ 138 : : QgsVectorLayer *vectorLayer() const; 139 : : 140 : : /** 141 : : * Sets the source CRS for feature geometries. The source CRS must be set if geometries are to be 142 : : * correctly automatically reprojected to WGS 84, to match GeoJSON specifications. 143 : : * \param crs source CRS for input feature geometries 144 : : * \note the source CRS will be overwritten when a vector layer is specified via setVectorLayer() 145 : : * \see sourceCrs() 146 : : */ 147 : : void setSourceCrs( const QgsCoordinateReferenceSystem &crs ); 148 : : 149 : : /** 150 : : * Returns the source CRS for feature geometries. The source CRS must be set if geometries are to be 151 : : * correctly automatically reprojected to WGS 84, to match GeoJSON specifications. 152 : : * \see setSourceCrs() 153 : : */ 154 : : QgsCoordinateReferenceSystem sourceCrs() const; 155 : : 156 : : /** 157 : : * Sets whether geometries should be transformed in EPSG 4326 (default 158 : : * behavior) or just keep as it is. 159 : : * \since QGIS 3.12 160 : : */ 161 : : void setTransformGeometries( bool activate ) { mTransformGeometries = activate; } 162 : : 163 : : /** 164 : : * Sets the list of attributes to include in the JSON exports. 165 : : * \param attributes list of attribute indexes, or an empty list to include all 166 : : * attributes 167 : : * \see attributes() 168 : : * \see setExcludedAttributes() 169 : : * \note Attributes excluded via setExcludedAttributes() take precedence over 170 : : * attributes specified by this method. 171 : : */ 172 : : void setAttributes( const QgsAttributeList &attributes ) { mAttributeIndexes = attributes; } 173 : : 174 : : /** 175 : : * Returns the list of attributes which will be included in the JSON exports, or 176 : : * an empty list if all attributes will be included. 177 : : * \see setAttributes() 178 : : * \see excludedAttributes() 179 : : * \note Attributes excluded via excludedAttributes() take precedence over 180 : : * attributes returned by this method. 181 : : */ 182 : : QgsAttributeList attributes() const { return mAttributeIndexes; } 183 : : 184 : : /** 185 : : * Sets a list of attributes to specifically exclude from the JSON exports. Excluded attributes 186 : : * take precedence over attributes included via setAttributes(). 187 : : * \param attributes list of attribute indexes to exclude 188 : : * \see excludedAttributes() 189 : : * \see setAttributes() 190 : : */ 191 : : void setExcludedAttributes( const QgsAttributeList &attributes ) { mExcludedAttributeIndexes = attributes; } 192 : : 193 : : /** 194 : : * Returns a list of attributes which will be specifically excluded from the JSON exports. Excluded attributes 195 : : * take precedence over attributes included via attributes(). 196 : : * \see setExcludedAttributes() 197 : : * \see attributes() 198 : : */ 199 : : QgsAttributeList excludedAttributes() const { return mExcludedAttributeIndexes; } 200 : : 201 : : /** 202 : : * Returns a GeoJSON string representation of a feature. 203 : : * \param feature feature to convert 204 : : * \param extraProperties map of extra attributes to include in feature's properties 205 : : * \param id optional ID to use as GeoJSON feature's ID instead of input feature's ID. If omitted, feature's 206 : : * ID is used. 207 : : * \param indent number of indentation spaces for generated JSON (defaults to none) 208 : : * \returns GeoJSON string 209 : : * \see exportFeatures() 210 : : * \see exportFeatureToJsonObject() 211 : : */ 212 : : QString exportFeature( const QgsFeature &feature, 213 : : const QVariantMap &extraProperties = QVariantMap(), 214 : : const QVariant &id = QVariant(), 215 : : int indent = -1 ) const; 216 : : 217 : : /** 218 : : * Returns a QJsonObject representation of a feature. 219 : : * \param feature feature to convert 220 : : * \param extraProperties map of extra attributes to include in feature's properties 221 : : * \param id optional ID to use as GeoJSON feature's ID instead of input feature's ID. If omitted, feature's 222 : : * ID is used. 223 : : * \returns json object 224 : : * \see exportFeatures() 225 : : */ 226 : : json exportFeatureToJsonObject( const QgsFeature &feature, 227 : : const QVariantMap &extraProperties = QVariantMap(), 228 : : const QVariant &id = QVariant() ) const SIP_SKIP; 229 : : 230 : : 231 : : /** 232 : : * Returns a GeoJSON string representation of a list of features (feature collection). 233 : : * \param features features to convert 234 : : * \param indent number of indentation spaces for generated JSON (defaults to none) 235 : : * \returns GeoJSON string 236 : : * \see exportFeature() 237 : : */ 238 : : QString exportFeatures( const QgsFeatureList &features, int indent = -1 ) const; 239 : : 240 : : /** 241 : : * Returns a JSON object representation of a list of features (feature collection). 242 : : * \param features features to convert 243 : : * \returns json object 244 : : * \see exportFeatures() 245 : : * \since QGIS 3.10 246 : : */ 247 : : json exportFeaturesToJsonObject( const QgsFeatureList &features ) const SIP_SKIP; 248 : : 249 : : private: 250 : : 251 : : //! Maximum number of decimal places for geometry coordinates 252 : : int mPrecision; 253 : : 254 : : /** 255 : : * List of attribute indexes to include in export, or empty list to include all attributes 256 : : * \see mExcludedAttributeIndexes 257 : : */ 258 : : QgsAttributeList mAttributeIndexes; 259 : : 260 : : //! List of attribute indexes to exclude from export 261 : : QgsAttributeList mExcludedAttributeIndexes; 262 : : 263 : : //! Whether to include geometry in JSON export 264 : : bool mIncludeGeometry = true; 265 : : 266 : : //! Whether to include attributes in JSON export 267 : : bool mIncludeAttributes = true; 268 : : 269 : : //! Whether to include attributes from related features in JSON export 270 : : bool mIncludeRelatedAttributes = false; 271 : : 272 : : //! Associated vector layer. Required for related attribute export. 273 : : QPointer< QgsVectorLayer > mLayer; 274 : : 275 : : QgsCoordinateReferenceSystem mCrs; 276 : : 277 : : QgsCoordinateTransform mTransform; 278 : : 279 : : bool mAttributeDisplayName = false; 280 : : 281 : : bool mTransformGeometries = true; 282 : : }; 283 : : 284 : : /** 285 : : * \ingroup core 286 : : * \class QgsJsonUtils 287 : : * \brief Helper utilities for working with JSON and GeoJSON conversions. 288 : : * \since QGIS 2.16 289 : : */ 290 : : 291 : : class CORE_EXPORT QgsJsonUtils 292 : : { 293 : : public: 294 : : 295 : : /** 296 : : * Attempts to parse a GeoJSON \a string to a collection of features. 297 : : * It is possible to specify \a fields to parse specific fields, if not provided, no fields will be included. 298 : : * An \a encoding can be specified which defaults to UTF-8 if it is `nullptr`. 299 : : * \returns a list of parsed features, or an empty list if no features could be parsed 300 : : * \see stringToFields() 301 : : * \note this function is a wrapper around QgsOgrUtils::stringToFeatureList() 302 : : */ 303 : : static QgsFeatureList stringToFeatureList( const QString &string, const QgsFields &fields = QgsFields(), QTextCodec *encoding = nullptr ); 304 : : 305 : : /** 306 : : * Attempts to retrieve the fields from a GeoJSON \a string representing a collection of features. 307 : : * An \a encoding can be specified which defaults to UTF-8 if it is `nullptr`. 308 : : * \returns retrieved fields collection, or an empty list if no fields could be determined from the string 309 : : * \see stringToFeatureList() 310 : : * \note this function is a wrapper around QgsOgrUtils::stringToFields() 311 : : */ 312 : : static QgsFields stringToFields( const QString &string, QTextCodec *encoding = nullptr ); 313 : : 314 : : /** 315 : : * Encodes a value to a JSON string representation, adding appropriate quotations and escaping 316 : : * where required. 317 : : * \param value value to encode 318 : : * \returns encoded value 319 : : */ 320 : : static QString encodeValue( const QVariant &value ); 321 : : 322 : : /** 323 : : * Exports all attributes from a QgsFeature as a JSON map type. 324 : : * \param feature feature to export 325 : : * \param layer optional associated vector layer. If specified, this allows 326 : : * richer export utilising settings like the layer's fields widget configuration. 327 : : * \param attributeWidgetCaches optional widget configuration cache. Can be used 328 : : * to speed up exporting the attributes for multiple features from the same layer. 329 : : */ 330 : : static QString exportAttributes( const QgsFeature &feature, QgsVectorLayer *layer = nullptr, 331 : : const QVector<QVariant> &attributeWidgetCaches = QVector<QVariant>() ); 332 : : 333 : : /** 334 : : * Exports all attributes from a QgsFeature as a json object. 335 : : * \param feature feature to export 336 : : * \param layer optional associated vector layer. If specified, this allows 337 : : * richer export utilising settings like the layer's fields widget configuration. 338 : : * \param attributeWidgetCaches optional widget configuration cache. Can be used 339 : : * to speed up exporting the attributes for multiple features from the same layer. 340 : : * \note Not available in Python bindings 341 : : * \since QGIS 3.8 342 : : */ 343 : : static json exportAttributesToJsonObject( const QgsFeature &feature, QgsVectorLayer *layer = nullptr, 344 : : const QVector<QVariant> &attributeWidgetCaches = QVector<QVariant>() ) SIP_SKIP; 345 : : 346 : : /** 347 : : * Parse a simple array (depth=1) 348 : : * \param json the JSON to parse 349 : : * \param type optional variant type of the elements, if specified (and not Invalid), 350 : : * the array items will be converted to the type, and discarded if 351 : : * the conversion is not possible. 352 : : * \since QGIS 3.0 353 : : */ 354 : : static QVariantList parseArray( const QString &json, QVariant::Type type = QVariant::Invalid ); 355 : : 356 : : 357 : : /** 358 : : * Converts a QVariant \a v to a json object 359 : : * \note Not available in Python bindings 360 : : * \since QGIS 3.8 361 : : */ 362 : : static json jsonFromVariant( const QVariant &v ) SIP_SKIP; 363 : : 364 : : /** 365 : : * Converts JSON \a jsonString to a QVariant, in case of parsing error an invalid QVariant is returned. 366 : : * \note Not available in Python bindings 367 : : * \since QGIS 3.8 368 : : */ 369 : : static QVariant parseJson( const std::string &jsonString ) SIP_SKIP; 370 : : 371 : : /** 372 : : * Converts JSON \a jsonString to a QVariant, in case of parsing error an invalid QVariant is returned. 373 : : * \note Not available in Python bindings 374 : : * \since QGIS 3.8 375 : : */ 376 : : static QVariant parseJson( const QString &jsonString ) SIP_SKIP; 377 : : 378 : : }; 379 : : 380 : : #endif // QGSJSONUTILS_H