JsonHelper.h 10.2 KB
Newer Older
1 2
/****************************************************************************
 *
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8 9
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10
#pragma once
Don Gagne's avatar
Don Gagne committed
11

12 13
#include <QCoreApplication>
#include <QGeoCoordinate>
Don Gagne's avatar
Don Gagne committed
14
#include <QJsonObject>
15
#include <QVariantList>
16 17 18

/// @file
/// @author Don Gagne <don@thegagnes.com>
Don Gagne's avatar
Don Gagne committed
19

20 21
class QmlObjectListModel;

22 23
/// @brief Json manipulation helper class.
/// Primarily used for parsing and processing Fact metadata.
24 25
class JsonHelper {
  Q_DECLARE_TR_FUNCTIONS(JsonHelper)
26

Don Gagne's avatar
Don Gagne committed
27
public:
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
  /// Determines is the specified file is a json file
  /// @return true: file is json, false: file is not json
  static bool isJsonFile(const QString &fileName, ///< filename
                         QJsonDocument &jsonDoc,  ///< returned json document
                         QString &errorString);   ///< error on parse failure

  /// Determines is the specified data is a json file
  /// @return true: file is json, false: file is not json
  static bool isJsonFile(const QByteArray &bytes, ///< json bytes
                         QJsonDocument &jsonDoc,  ///< returned json document
                         QString &errorString);   ///< error on parse failure

  /// Saves the standard file header the json object
  static void
  saveQGCJsonFileHeader(QJsonObject &jsonObject, ///< root json object
                        const QString &fileType, ///< file type for file
                        int version);            ///< version number for file

  /// Validates the standard parts of an external QGC json file (Plan file,
  /// ...):
  ///     jsonFileTypeKey - Required and checked to be equal to expectedFileType
  ///     jsonVersionKey - Required and checked to be below
  ///     supportedMajorVersion, supportedMinorVersion jsonGroundStationKey -
  ///     Required and checked to be string type
  /// @return false: validation failed, errorString set
  static bool validateExternalQGCJsonFile(
      const QJsonObject &jsonObject,   ///< json object to validate
      const QString &expectedFileType, ///< correct file type for file
      int minSupportedVersion,         ///< minimum supported version
      int maxSupportedVersion,         ///< maximum supported major version
      int &version,                    ///< returned file version
      QString &errorString); ///< returned error string if validation fails

  /// Validates the standard parts of a internal QGC json file (FactMetaData,
  /// ...):
  ///     jsonFileTypeKey - Required and checked to be equal to expectedFileType
  ///     jsonVersionKey - Required and checked to be below
  ///     supportedMajorVersion, supportedMinorVersion jsonGroundStationKey -
  ///     Required and checked to be string type
  /// @return false: validation failed, errorString set
  static bool validateInternalQGCJsonFile(
      const QJsonObject &jsonObject,   ///< json object to validate
      const QString &expectedFileType, ///< correct file type for file
      int minSupportedVersion,         ///< minimum supported version
      int maxSupportedVersion,         ///< maximum supported major version
      int &version,                    ///< returned file version
      QString &errorString); ///< returned error string if validation fails

  // Opens, validates and translates an internal QGC json file.
  // @return Json root object for file. Empty QJsonObject if error.
  static QJsonObject openInternalQGCJsonFile(
      const QString &jsonFilename,     ///< Json file to open
      const QString &expectedFileType, ///< correct file type for file
      int minSupportedVersion,         ///< minimum supported version
      int maxSupportedVersion,         ///< maximum supported major version
      int &version,                    ///< returned file version
      QString &errorString); ///< returned error string if validation fails

  /// Validates that the specified keys are in the object
  /// @return false: validation failed, errorString set
  static bool validateRequiredKeys(
      const QJsonObject &jsonObject, ///< json object to validate
      const QStringList &keys,       ///< keys which are required to be present
      QString &errorString); ///< returned error string if validation fails

  /// Validates the types of specified keys are in the object
  /// @return false: validation failed, errorString set
  static bool validateKeyTypes(
      const QJsonObject &jsonObject, ///< json object to validate
      const QStringList &keys,       ///< keys to validate
      const QList<QJsonValue::Type>
          &types, ///< required type for each key, QJsonValue::Null specifies
                  ///< double with possible NaN
      QString &errorString); ///< returned error string if validation fails

  typedef struct {
    const char *key;       ///< json key name
    QJsonValue::Type type; ///< required type for key, QJsonValue::Null
                           ///< specifies double with possible NaN
    bool required;         ///< true: key must be present
  } KeyValidateInfo;

  static bool validateKeys(const QJsonObject &jsonObject,
                           const QList<KeyValidateInfo> &keyInfo,
                           QString &errorString);

  /// Loads a QGeoCoordinate
  ///     Stored as array [ lat, lon, alt ]
  /// @return false: validation failed
  static bool loadGeoCoordinate(
      const QJsonValue &jsonValue, ///< json value to load from
      bool altitudeRequired,       ///< true: altitude must be specified
      QGeoCoordinate &coordinate,  ///< returned QGeoCordinate
      QString &errorString,        ///< returned error string if load failure
      bool geoJsonFormat =
          false); ///< if true, use [lon, lat], [lat, lon] otherwise

  /// Saves a QGeoCoordinate
  ///     Stored as array [ lat, lon, alt ]
  static void saveGeoCoordinate(
      const QGeoCoordinate &coordinate, ///< QGeoCoordinate to save
      bool writeAltitude,               ///< true: write altitude to json
      QJsonValue &jsonValue);           ///< json value to save to

  /// Loads a QGeoCoordinate
  ///     Stored as array [ lon, lat, alt ]
  /// @return false: validation failed
  static bool loadGeoJsonCoordinate(
      const QJsonValue &jsonValue, ///< json value to load from
      bool altitudeRequired,       ///< true: altitude must be specified
      QGeoCoordinate &coordinate,  ///< returned QGeoCordinate
      QString &errorString);       ///< returned error string if load failure

  /// Saves a QGeoCoordinate
  ///     Stored as array [ lon, lat, alt ]
  static void saveGeoJsonCoordinate(
      const QGeoCoordinate &coordinate, ///< QGeoCoordinate to save
      bool writeAltitude,               ///< true: write altitude to json
      QJsonValue &jsonValue);           ///< json value to save to

  /// Loads a polygon from an array
  static bool loadPolygon(
      const QJsonObject &polygonArray, ///< Array of coordinates
      QmlObjectListModel &list,        ///< Empty list to add vertices to
      QObject *parent,       ///< parent for newly allocated QGCQGeoCoordinates
      QString &errorString); ///< returned error string if load failure

  /// Loads a list of QGeoCoordinates from a json array
  /// @return false: validation failed
  static bool loadGeoCoordinateArray(
      const QJsonValue &jsonValue, ///< json value which contains points
      bool altitudeRequired,       ///< true: altitude field must be specified
      QVariantList &rgVarPoints,   ///< returned points
      QString &errorString);       ///< returned error string if load failure
  static bool loadGeoCoordinateArray(
      const QJsonValue &jsonValue, ///< json value which contains points
      bool altitudeRequired,       ///< true: altitude field must be specified
      QList<QGeoCoordinate> &rgPoints, ///< returned points
      QString &errorString); ///< returned error string if load failure

  /// Saves a list of QGeoCoordinates to a json array
  static void
  saveGeoCoordinateArray(const QVariantList &rgVarPoints, ///< points to save
                         bool writeAltitude,     ///< true: write altitide value
                         QJsonValue &jsonValue); ///< json value to save to
  static void saveGeoCoordinateArray(
      const QList<QGeoCoordinate> &rgPoints, ///< points to save
      bool writeAltitude,                    ///< true: write altitide value
      QJsonValue &jsonValue);                ///< json value to save to

  /// Saves a polygon to a json array
  static void
  savePolygon(QmlObjectListModel &list,   ///< List which contains vertices
              QJsonObject &polygonArray); ///< Array to save into

  /// Returns NaN if the value is null, or if not, the double value
  static double possibleNaNJsonValue(const QJsonValue &value);

  static const char *jsonVersionKey;
  static const char *jsonGroundStationKey;
  static const char *jsonGroundStationValue;
  static const char *jsonFileTypeKey;
190 191

private:
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
  static QString _jsonValueTypeToString(QJsonValue::Type type);
  static bool _loadGeoCoordinate(const QJsonValue &jsonValue,
                                 bool altitudeRequired,
                                 QGeoCoordinate &coordinate,
                                 QString &errorString, bool geoJsonFormat);
  static void _saveGeoCoordinate(const QGeoCoordinate &coordinate,
                                 bool writeAltitude, QJsonValue &jsonValue,
                                 bool geoJsonFormat);
  static QStringList _addDefaultLocKeys(QJsonObject &jsonObject);
  static QJsonObject _translateRoot(QJsonObject &jsonObject,
                                    const QString &translateContext,
                                    const QStringList &translateKeys);
  static QJsonObject _translateObject(QJsonObject &jsonObject,
                                      const QString &translateContext,
                                      const QStringList &translateKeys);
  static QJsonObject _translateArray(QJsonObject &jsonArray,
                                     const QString &translateContext,
                                     const QStringList &translateKeys);

  static const char *_translateKeysKey;
  static const char *_arrayIDKeysKey;
Don Gagne's avatar
Don Gagne committed
213
};