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

#ifndef QGCMapPolygon_H
#define QGCMapPolygon_H

#include <QGeoCoordinate>
14
#include <QObject>
15
#include <QPolygon>
16
#include <QVariantList>
17

18 19
#include "QmlObjectListModel.h"

20 21 22 23 24
/// The QGCMapPolygon class provides a polygon which can be displayed on a map
/// using a map visuals control. It maintains a representation of the polygon on
/// QVariantList and QmlObjectListModel format.
class QGCMapPolygon : public QObject {
  Q_OBJECT
25 26

public:
27 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
  QGCMapPolygon(QObject *parent = nullptr);
  QGCMapPolygon(const QGCMapPolygon &other, QObject *parent = nullptr);

  const QGCMapPolygon &operator=(const QGCMapPolygon &other);

  Q_PROPERTY(int count READ count NOTIFY countChanged)
  Q_PROPERTY(QVariantList path READ path NOTIFY pathChanged)
  Q_PROPERTY(QmlObjectListModel *pathModel READ qmlPathModel CONSTANT)
  Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
  Q_PROPERTY(
      QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
  Q_PROPERTY(bool centerDrag READ centerDrag WRITE setCenterDrag NOTIFY
                 centerDragChanged)
  Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY
                 interactiveChanged)
  Q_PROPERTY(double area READ area NOTIFY areaChanged)

  Q_INVOKABLE void clear(void);
  Q_INVOKABLE void appendVertex(const QGeoCoordinate &coordinate);
  Q_INVOKABLE void removeVertex(int vertexIndex);
  Q_INVOKABLE void appendVertices(const QList<QGeoCoordinate> &coordinates);

  /// Adjust the value for the specified coordinate
  ///     @param vertexIndex Polygon point index to modify (0-based)
  ///     @param coordinate New coordinate for point
  Q_INVOKABLE void adjustVertex(int vertexIndex,
                                const QGeoCoordinate coordinate);

  /// Splits the segment comprised of vertextIndex -> vertexIndex + 1
  Q_INVOKABLE void splitPolygonSegment(int vertexIndex);

  /// Returns true if the specified coordinate is within the polygon
  Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate &coordinate) const;

  /// Offsets the current polygon edges by the specified distance in meters
  Q_INVOKABLE void offset(double distance);

  /// Loads a polygon from a KML/SH{ file
  /// @return true: success
  Q_INVOKABLE bool loadKMLOrSHPFile(const QString &file);

  /// Returns the path in a list of QGeoCoordinate's format
  QList<QGeoCoordinate> coordinateList(void) const;

  /// Returns the QGeoCoordinate for the vertex specified
  Q_INVOKABLE QGeoCoordinate vertexCoordinate(int vertex) const;

  /// Adjust polygon winding order to be clockwise (if needed)
  Q_INVOKABLE void verifyClockwiseWinding(void);

  /// Saves the polygon to the json object.
  ///     @param json Json object to save to
  void saveToJson(QJsonObject &json);

  /// Load a polygon from json
  ///     @param json Json object to load from
  ///     @param required true: no polygon in object will generate error
  ///     @param errorString Error string if return is false
  /// @return true: success, false: failure (errorString set)
  bool loadFromJson(const QJsonObject &json, bool required,
                    QString &errorString);

  /// Convert polygon to NED and return (D is ignored)
  QList<QPointF> nedPolygon(void) const;

  /// Returns the area of the polygon in meters squared
  double area(void) const;

  // Property methods

  int count(void) const { return _polygonPath.count(); }
  bool dirty(void) const { return _dirty; }
  void setDirty(bool dirty);
  QGeoCoordinate center(void) const { return _center; }
  bool centerDrag(void) const { return _centerDrag; }
  bool interactive(void) const { return _interactive; }

  QVariantList path(void) const { return _polygonPath; }
  const QVariantList &pathReference(void) const { return _polygonPath; }
  QmlObjectListModel *qmlPathModel(void) { return &_polygonModel; }
  QmlObjectListModel &pathModel(void) { return _polygonModel; }

  // Friends
  friend void print(const QGCMapPolygon &poly, QString &outputString);
  friend void print(const QGCMapPolygon &poly);

  // static Variables
  static const char *jsonPolygonKey;
115

116
signals:
117 118 119 120 121 122 123 124
  void countChanged(int count);
  void pathChanged(void);
  void dirtyChanged(bool dirty);
  void cleared(void);
  void centerChanged(QGeoCoordinate center);
  void centerDragChanged(bool centerDrag);
  void interactiveChanged(bool interactive);
  void areaChanged(void);
125

126
public slots:
127 128 129 130 131 132
  void setPath(const QList<QGeoCoordinate> &path);
  void setPath(const QVector<QGeoCoordinate> &path);
  void setPath(const QVariantList &path);
  void setCenter(QGeoCoordinate newCenter);
  void setCenterDrag(bool centerDrag);
  void setInteractive(bool interactive);
133

134
private slots:
135 136 137
  void _polygonModelCountChanged(int count);
  void _polygonModelDirtyChanged(bool dirty);
  void _updateCenter(void);
138

139
private:
140 141 142 143 144 145 146 147 148 149 150 151
  void _init(void);
  QPolygonF _toPolygonF(void) const;
  QGeoCoordinate _coordFromPointF(const QPointF &point) const;
  QPointF _pointFFromCoord(const QGeoCoordinate &coordinate) const;

  QVariantList _polygonPath;
  QmlObjectListModel _polygonModel;
  bool _dirty;
  QGeoCoordinate _center;
  bool _centerDrag;
  bool _ignoreCenterUpdates;
  bool _interactive;
152 153 154
};

#endif