31#include <QJsonDocument> 
   34#include <nlohmann/json.hpp> 
   38  , mLayer( vectorLayer )
 
   78                                        const QVariant &
id, 
int indent )
 const 
   87    {  
"type",  
"Feature" },
 
   92    auto intId = 
id.toLongLong( &ok );
 
   95      featureJson[
"id"] = intId;
 
   99      featureJson[
"id"] = 
id.toString().toStdString();
 
  104    featureJson[
"id"] = 
nullptr;
 
  108    featureJson[
"id"] = feature.
id();
 
  112  if ( !geom.
isNull() && mIncludeGeometry )
 
  131      featureJson[ 
"bbox" ] =
 
  139    featureJson[ 
"geometry" ] = geom.
asJsonObject( mPrecision );
 
  143    featureJson[ 
"geometry"  ] = 
nullptr;
 
  148  if ( mIncludeAttributes || !extraProperties.isEmpty() )
 
  151    if ( mIncludeAttributes )
 
  155      QStringList formattersAllowList;
 
  156      formattersAllowList << QStringLiteral( 
"KeyValue" )
 
  157                          << QStringLiteral( 
"List" )
 
  158                          << QStringLiteral( 
"ValueRelation" )
 
  159                          << QStringLiteral( 
"ValueMap" );
 
  161      for ( 
int i = 0; i < fields.
count(); ++i )
 
  163        if ( ( !mAttributeIndexes.isEmpty() && !mAttributeIndexes.contains( i ) ) || mExcludedAttributeIndexes.contains( i ) )
 
  172          if ( formattersAllowList.contains( fieldFormatter->
id() ) )
 
  176        QString name = fields.
at( i ).
name();
 
  177        if ( mAttributeDisplayName )
 
  179          name = mLayer->attributeDisplayName( i );
 
  185    if ( !extraProperties.isEmpty() )
 
  187      QVariantMap::const_iterator it = extraProperties.constBegin();
 
  188      for ( ; it != extraProperties.constEnd(); ++it )
 
  195    if ( mLayer && mIncludeRelatedAttributes )
 
  198      for ( 
const auto &relation : std::as_const( relations ) )
 
  203        json relatedFeatureAttributes;
 
  207          QVector<QVariant> attributeWidgetCaches;
 
  214            attributeWidgetCaches.append( fieldFormatter->
createCache( childLayer, fieldIndex, setup.
config() ) );
 
  223        properties[ relation.name().toStdString() ] = relatedFeatureAttributes;
 
  227  featureJson[ 
"properties" ] = properties;
 
  240    { 
"type", 
"FeatureCollection" },
 
  241    { 
"features", json::array() }
 
  243  for ( 
const QgsFeature &feature : std::as_const( features ) )
 
  252  mDestinationCrs = destinationCrs;
 
  263    encoding = QTextCodec::codecForName( 
"UTF-8" );
 
  271    encoding = QTextCodec::codecForName( 
"UTF-8" );
 
  279    return QStringLiteral( 
"null" );
 
  281  switch ( value.type() )
 
  285    case QVariant::LongLong:
 
  286    case QVariant::ULongLong:
 
  287    case QVariant::Double:
 
  288      return value.toString();
 
  291      return value.toBool() ? 
"true" : 
"false";
 
  293    case QVariant::StringList:
 
  296      return QString::fromUtf8( QJsonDocument::fromVariant( value ).toJson( QJsonDocument::Compact ) );
 
  299    case QVariant::String:
 
  300      QString v = value.toString()
 
  301                  .replace( 
'\\', QLatin1String( 
"\\\\" ) )
 
  302                  .replace( 
'"', QLatin1String( 
"\\\"" ) )
 
  303                  .replace( 
'\r', QLatin1String( 
"\\r" ) )
 
  304                  .replace( 
'\b', QLatin1String( 
"\\b" ) )
 
  305                  .replace( 
'\t', QLatin1String( 
"\\t" ) )
 
  306                  .replace( 
'/', QLatin1String( 
"\\/" ) )
 
  307                  .replace( 
'\n', QLatin1String( 
"\\n" ) );
 
  309      return v.prepend( 
'"' ).append( 
'"' );
 
  317  for ( 
int i = 0; i < fields.
count(); ++i )
 
  320      attrs += QLatin1String( 
",\n" );
 
  329        val = fieldFormatter->
representValue( layer, i, setup.
config(), attributeWidgetCaches.count() >= i ? attributeWidgetCaches.at( i ) : QVariant(), val );
 
  334  return attrs.prepend( 
'{' ).append( 
'}' );
 
  339  QString errorMessage;
 
  343    const auto jObj( 
json::parse( json.toStdString() ) );
 
  344    if ( ! jObj.is_array() )
 
  346      throw json::parse_error::create( 0, 0, QStringLiteral( 
"JSON value must be an array" ).toStdString() );
 
  348    for ( 
const auto &item : jObj )
 
  352      if ( item.is_number_integer() )
 
  356      else if ( item.is_number_unsigned() )
 
  358        v = item.get<
unsigned>();
 
  360      else if ( item.is_number_float() )
 
  363        v = item.get<
double>();
 
  365      else if ( item.is_string() )
 
  367        v = QString::fromStdString( item.get<std::string>() );
 
  369      else if ( item.is_boolean() )
 
  371        v = item.get<
bool>();
 
  373      else if ( item.is_null() )
 
  376        v = QVariant( type == QVariant::Type::Invalid ? QVariant::Type::Int : type );
 
  380      if ( type != QVariant::Invalid )
 
  382        if ( ! v.convert( 
static_cast<int>( type ) ) )
 
  384          QgsLogger::warning( QStringLiteral( 
"Cannot convert json array element to specified type, ignoring: %1" ).arg( v.toString() ) );
 
  388          result.push_back( v );
 
  393        result.push_back( v );
 
  397  catch ( json::parse_error &ex )
 
  399    errorMessage = ex.what();
 
  400    QgsLogger::warning( QStringLiteral( 
"Cannot parse json (%1): %2" ).arg( ex.what(), json ) );
 
  413  if ( val.type() == QVariant::Type::Map )
 
  415    const QVariantMap &vMap = val.toMap();
 
  416    json jMap = json::object();
 
  417    for ( 
auto it = vMap.constBegin(); it != vMap.constEnd(); it++ )
 
  423  else if ( val.type() == QVariant::Type::List || val.type() == QVariant::Type::StringList )
 
  425    const QVariantList &vList = val.toList();
 
  426    json jList = json::array();
 
  427    for ( 
const auto &v : vList )
 
  435    switch ( val.userType() )
 
  438      case QMetaType::UInt:
 
  439      case QMetaType::LongLong:
 
  440      case QMetaType::ULongLong:
 
  441        j = val.toLongLong();
 
  443      case QMetaType::Double:
 
  444      case QMetaType::Float:
 
  447      case QMetaType::Bool:
 
  450      case QMetaType::QByteArray:
 
  451        j = val.toByteArray().toBase64().toStdString();
 
  454        j = val.toString().toStdString();
 
  464  const QVariant res = 
parseJson( jsonString, error );
 
  466  if ( !error.isEmpty() )
 
  469                        QString::fromStdString( jsonString ) ) );
 
  477  bool isPrimitive = 
true;
 
  479  std::function<QVariant( json )> _parser { [ & ]( json jObj ) -> QVariant {
 
  481      if ( jObj.is_array() )
 
  484        QVariantList results;
 
  485        results.reserve( jObj.size() );
 
  486        for ( 
const auto &item : jObj )
 
  488          results.push_back( _parser( item ) );
 
  492      else if ( jObj.is_object() )
 
  496        for ( 
const auto  &item : jObj.items() )
 
  498          const auto key { QString::fromStdString( item.key() ) };
 
  499          const auto value {  _parser( item.value() ) };
 
  500          results[ key ] = value;
 
  506        if ( jObj.is_number_integer() )
 
  508          result = jObj.get<
int>();
 
  510        else if ( jObj.is_number_unsigned() )
 
  512          result = jObj.get<
unsigned>();
 
  514        else if ( jObj.is_boolean() )
 
  516          result = jObj.get<
bool>();
 
  518        else if ( jObj.is_number_float() )
 
  521          result = jObj.get<
double>();
 
  523        else if ( jObj.is_string() )
 
  525          if ( isPrimitive && jObj.get<std::string>().length() == 0 )
 
  527            result = QString::fromStdString( jObj.get<std::string>() ).append( 
"\"" ).insert( 0, 
"\"" );
 
  531            result = QString::fromStdString( jObj.get<std::string>() );
 
  534        else if ( jObj.is_null() )
 
  549  catch ( json::parse_error &ex )
 
  551    error = QString::fromStdString( ex.what() );
 
  558  return parseJson( jsonString.toStdString() );
 
  565  for ( 
int i = 0; i < fields.
count(); ++i )
 
  574        val = fieldFormatter->
representValue( layer, i, setup.
config(), attributeWidgetCaches.count() >= i ? attributeWidgetCaches.at( i ) : QVariant(), val );
 
@ Success
Operation succeeded.
 
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
 
This class represents a coordinate reference system (CRS).
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
 
Custom exception class for Coordinate Reference System related exceptions.
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
 
This class wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
 
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
Encapsulate a field in an attribute table or data source.
 
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
 
Container of fields for a vector layer.
 
int count() const
Returns number of items.
 
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
 
A geometry is the spatial representation of a feature.
 
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
 
Qgis::WkbType wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
 
virtual json asJsonObject(int precision=17) const
Exports the geometry to a json object.
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
 
json exportFeatureToJsonObject(const QgsFeature &feature, const QVariantMap &extraProperties=QVariantMap(), const QVariant &id=QVariant()) const
Returns a QJsonObject representation of a feature.
 
json exportFeaturesToJsonObject(const QgsFeatureList &features) const
Returns a JSON object representation of a list of features (feature collection).
 
void setSourceCrs(const QgsCoordinateReferenceSystem &crs)
Sets the source CRS for feature geometries.
 
void setDestinationCrs(const QgsCoordinateReferenceSystem &destinationCrs)
Set the destination CRS for feature geometry transformation to destinationCrs, this defaults to EPSG:...
 
QgsVectorLayer * vectorLayer() const
Returns the associated vector layer, if set.
 
QString exportFeature(const QgsFeature &feature, const QVariantMap &extraProperties=QVariantMap(), const QVariant &id=QVariant(), int indent=-1) const
Returns a GeoJSON string representation of a feature.
 
QString exportFeatures(const QgsFeatureList &features, int indent=-1) const
Returns a GeoJSON string representation of a list of features (feature collection).
 
void setVectorLayer(QgsVectorLayer *vectorLayer)
Sets the associated vector layer (required for related attribute export).
 
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source CRS for feature geometries.
 
QgsJsonExporter(QgsVectorLayer *vectorLayer=nullptr, int precision=6)
Constructor for QgsJsonExporter.
 
static QgsFeatureList stringToFeatureList(const QString &string, const QgsFields &fields=QgsFields(), QTextCodec *encoding=nullptr)
Attempts to parse a GeoJSON string to a collection of features.
 
static QString exportAttributes(const QgsFeature &feature, QgsVectorLayer *layer=nullptr, const QVector< QVariant > &attributeWidgetCaches=QVector< QVariant >())
Exports all attributes from a QgsFeature as a JSON map type.
 
static Q_INVOKABLE QString encodeValue(const QVariant &value)
Encodes a value to a JSON string representation, adding appropriate quotations and escaping where req...
 
static QVariant parseJson(const std::string &jsonString)
Converts JSON jsonString to a QVariant, in case of parsing error an invalid QVariant is returned and ...
 
static json exportAttributesToJsonObject(const QgsFeature &feature, QgsVectorLayer *layer=nullptr, const QVector< QVariant > &attributeWidgetCaches=QVector< QVariant >())
Exports all attributes from a QgsFeature as a json object.
 
static QgsFields stringToFields(const QString &string, QTextCodec *encoding=nullptr)
Attempts to retrieve the fields from a GeoJSON string representing a collection of features.
 
static Q_INVOKABLE QVariantList parseArray(const QString &json, QVariant::Type type=QVariant::Invalid)
Parse a simple array (depth=1)
 
static json jsonFromVariant(const QVariant &v)
Converts a QVariant v to a json object.
 
static void warning(const QString &msg)
Goes to qWarning.
 
QgsCoordinateReferenceSystem crs
 
static QgsFeatureList stringToFeatureList(const QString &string, const QgsFields &fields, QTextCodec *encoding)
Attempts to parse a string representing a collection of features using OGR.
 
static QgsFields stringToFields(const QString &string, QTextCodec *encoding)
Attempts to retrieve the fields from a string representing a collection of features using OGR.
 
QgsRelationManager * relationManager
 
static QgsProject * instance()
Returns the QgsProject singleton instance.
 
A rectangle specified with double values.
 
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
 
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
 
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
 
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
 
QList< QgsRelation > referencedRelations(const QgsVectorLayer *layer=nullptr) const
Gets all relations where this layer is the referenced part (i.e.
 
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
 
Represents a vector layer which manages a vector based data sets.
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
 
QgsFields fields() const FINAL
Returns the list of fields of this layer.
 
static Qgis::WkbType flatType(Qgis::WkbType type) SIP_HOLDGIL
Returns the flat type for a WKB type.
 
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
 
QList< QgsFeature > QgsFeatureList
 
QgsSQLStatement::Node * parse(const QString &str, QString &parserErrorMsg, bool allowFragments)
 
const QgsCoordinateReferenceSystem & crs