Commit 5d91598d authored by Valentin Platzgummer's avatar Valentin Platzgummer

service area depot issue solved.

parent 0397d607
......@@ -10,139 +10,145 @@
#ifndef QGCMapPolygon_H
#define QGCMapPolygon_H
#include <QObject>
#include <QGeoCoordinate>
#include <QVariantList>
#include <QObject>
#include <QPolygon>
#include <QVariantList>
#include "QmlObjectListModel.h"
/// 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
/// 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
public:
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; }
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;
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;
signals:
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);
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);
public slots:
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);
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);
private slots:
void _polygonModelCountChanged (int count);
void _polygonModelDirtyChanged (bool dirty);
void _updateCenter (void);
void _polygonModelCountChanged(int count);
void _polygonModelDirtyChanged(bool dirty);
void _updateCenter(void);
private:
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;
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;
};
#endif
......@@ -23,10 +23,16 @@ WimaServiceArea &WimaServiceArea::operator=(const WimaServiceArea &other) {
return *this;
}
const QGeoCoordinate &WimaServiceArea::depot() const { return _depot; }
QGeoCoordinate WimaServiceArea::depotQml() const { return _depot; }
bool WimaServiceArea::setDepot(const QGeoCoordinate &coordinate) {
if (_depot != coordinate) {
if (_depot.latitude() != coordinate.latitude() ||
_depot.longitude() != coordinate.longitude()) {
if (this->containsCoordinate(coordinate)) {
_depot = coordinate;
_depot.setAltitude(0);
emit depotChanged();
return true;
}
......@@ -90,7 +96,27 @@ void WimaServiceArea::init() {
this->setObjectName(wimaServiceAreaName);
connect(this, &WimaArea::pathChanged, [this] {
if (!this->_depot.isValid() || !this->containsCoordinate(this->_depot)) {
this->setDepot(this->center());
if (this->containsCoordinate(this->center())) {
// Use center.
this->setDepot(this->center());
} else if (this->_depot.isValid()) {
// Use nearest coordinate.
auto minDist = std::numeric_limits<double>::infinity();
auto minIt = this->pathReference().begin();
for (auto it = this->pathReference().begin();
it < this->pathReference().end(); ++it) {
const auto vertex = it->value<QGeoCoordinate>();
auto d = vertex.distanceTo(this->_depot);
if (d < minDist) {
minDist = d;
minIt = it;
}
}
this->setDepot(minIt->value<QGeoCoordinate>());
} else if (this->pathReference().size() > 0) {
// Use first coordinate.
this->setDepot(this->pathReference().value(0).value<QGeoCoordinate>());
}
}
});
}
......@@ -11,14 +11,16 @@ public:
WimaServiceArea(const WimaServiceArea &other, QObject *parent);
WimaServiceArea &operator=(const WimaServiceArea &other);
Q_PROPERTY(QGeoCoordinate depot READ depot WRITE setDepot NOTIFY depotChanged)
Q_PROPERTY(
QGeoCoordinate depot READ depotQml WRITE setDepot NOTIFY depotChanged)
// Overrides from WimaPolygon
QString mapVisualQML(void) const { return "WimaServiceAreaMapVisual.qml"; }
QString editorQML(void) const { return "WimaServiceAreaEditor.qml"; }
// Property acessors
const QGeoCoordinate &depot(void) const { return _depot; }
const QGeoCoordinate &depot(void) const;
QGeoCoordinate depotQml(void) const;
// Member Methodes
void saveToJson(QJsonObject &json);
......
......@@ -7,12 +7,12 @@ WaypointManager::EmptyManager::EmptyManager(Settings &settings, AreaInterface &)
void WaypointManager::EmptyManager::clear() {}
bool WaypointManager::EmptyManager::update() {}
bool WaypointManager::EmptyManager::update() { return true; }
bool WaypointManager::EmptyManager::next() {}
bool WaypointManager::EmptyManager::next() { return true; }
bool WaypointManager::EmptyManager::previous() {}
bool WaypointManager::EmptyManager::previous() { return true; }
bool WaypointManager::EmptyManager::reset() {}
bool WaypointManager::EmptyManager::reset() { return true; }
} // namespace WaypointManager
......@@ -29,10 +29,8 @@ Item {
property bool checked
property string label: "Reference"
property var _itemVisual
property bool _itemVisualShowing: false
property var _dragArea
property bool _dragAreaShowing: false
property var _itemVisual: undefined
property var _dragArea: undefined
signal clicked()
signal released()
......@@ -45,31 +43,30 @@ Item {
signal dragReleased()
function hideItemVisuals() {
if (_itemVisualShowing) {
if (_itemVisual) {
map.removeMapItem(_itemVisual)
_itemVisual.destroy()
_itemVisualShowing = false
_itemVisual = undefined
}
}
function showItemVisuals() {
if (!_itemVisualShowing) {
if (!_itemVisual) {
_itemVisual = indicatorComponent.createObject(map)
map.addMapItem(_itemVisual)
_itemVisualShowing = true
}
}
function hideDragArea() {
if (_dragAreaShowing) {
if (_dragArea) {
_dragArea.destroy()
_dragAreaShowing = false
_dragArea = undefined
}
}
function showDragArea() {
if (!_dragAreaShowing) {
if (!_dragArea) {
_dragArea = dragAreaComponent.createObject(map)
_dragAreaShowing = true
}
}
......@@ -102,7 +99,9 @@ Item {
itemIndicator: _itemVisual
Component.onCompleted: itemCoordinate = _root.coordinate
onItemCoordinateChanged: _root.coordinate = itemCoordinate
onItemCoordinateChanged: {
_root.coordinate = itemCoordinate
}
onDragStart: _root.dragStart()
onDragStop: _root.dragStop()
......
......@@ -26,35 +26,32 @@ Item {
property var areaItem: object
property var _polygon: areaItem
property var _depot
property bool showDepot: areaItem.interactive || areaItem.borderPolygon.interactive
property bool _depotVisible: false
onShowDepotChanged: {
if (showDepot){
if (!_depotVisible){
_addDepot()
}
property var _depot: undefined
property bool _showDepot: areaItem.interactive || areaItem.borderPolygon.interactive
on_ShowDepotChanged: {
if (_showDepot){
_addDepot()
} else {
if (_depotVisible){
_destroyDepot()
}
_destroyDepot()
}
}
signal clicked(int sequenceNumber)
function _addDepot() {
_depot = depotPointComponent.createObject(map)
map.addMapItem(_depot)
_depotVisible = true
if (!_depot){
_depot = depotPointComponent.createObject(_root)
map.addMapItem(_depot)
}
}
function _destroyDepot() {
if (_depot){
map.removeMapItem(_depot)
_depot.destroy()
_depot = undefined
}
_depotVisible = false
}
/// Add an initial 4 sided polygon if there is none
......@@ -104,7 +101,7 @@ Item {
Component.onCompleted: {
_addInitialPolygon()
if (showDepot){
if (_showDepot){
_addDepot()
}
}
......@@ -137,21 +134,33 @@ Item {
Component {
id: depotPointComponent
DragCoordinate {
property var depot: areaItem.depot
property var depot: _root.areaItem.depot
map: _root.map
qgcView: _root.qgcView
z: QGroundControl.zOrderMapItems
checked: showDepot
coordinate: depot
checked: _root._showDepot
coordinate: _root.areaItem.depot
label: "Depot"
onDragReleased: {
if (areaItem.containsCoordinate(coordinate)){
areaItem.depot = coordinate
function syncAndBind(){
if (coordinate.latitude !== depot.latitude ||
coordinate.longitude !== depot.longitude){
if (_root.areaItem.containsCoordinate(coordinate)){
_root.areaItem.depot = coordinate
}
}
coordinate = Qt.binding(function() { return areaItem.depot; })
coordinate = Qt.binding(function(){return _root.areaItem.depot})
}
onDragReleased: {
syncAndBind()
}
Component.onCompleted: {
syncAndBind()
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment