From 22be1d1a6b329b08866fec406fb5d3c80227d43f Mon Sep 17 00:00:00 2001 From: Valentin Platzgummer Date: Wed, 3 Jul 2019 18:59:38 +0200 Subject: [PATCH] adding areas to flyView, WimaPlanData restructured, WimaController and WimaPlaner edited --- master.qdocconf | 1 + qgroundcontrol.pro | 8 +- qgroundcontrol.qrc | 9 +- src/FlightDisplay/FlightDisplayView.qml | 7 +- src/FlightDisplay/FlightDisplayViewMap.qml | 17 +- src/MissionManager/QGCMapPolygon.cc | 19 +- src/MissionManager/QGCMapPolygon.h | 3 - src/QGCApplication.cc | 10 +- .../QGroundControl.Controls.qmldir | 6 +- src/Wima/WimaArea.cc | 183 +++++++++--------- src/Wima/WimaArea.h | 40 +--- src/Wima/WimaAreaData.cc | 69 ++++++- src/Wima/WimaAreaData.h | 33 +++- src/Wima/WimaController.cc | 115 +++++++++-- src/Wima/WimaController.h | 32 ++- src/Wima/WimaCorridor.cc | 17 +- src/Wima/WimaCorridor.h | 4 +- src/Wima/WimaCorridorData.cpp | 35 +++- src/Wima/WimaCorridorData.h | 12 +- src/Wima/WimaDataContainer.cc | 86 ++++---- src/Wima/WimaDataContainer.h | 41 ++-- ...=> WimaMeasurementArea.SettingsGroup.json} | 12 +- src/Wima/WimaMeasurementArea.cc | 65 +++++-- src/Wima/WimaMeasurementArea.h | 22 ++- src/Wima/WimaMeasurementAreaData.cc | 46 +++++ src/Wima/WimaMeasurementAreaData.h | 24 +-- src/Wima/WimaMeasurementAreaDataareadata.cc | 6 - src/Wima/WimaPlanData.cc | 122 ++++++++++++ src/Wima/WimaPlanData.h | 38 ++++ src/Wima/WimaPlaner.cc | 174 +++++++++++------ src/Wima/WimaPlaner.h | 47 +++-- src/Wima/WimaServiceArea.cc | 19 +- src/Wima/WimaServiceArea.h | 3 +- src/Wima/WimaServiceAreaData.cc | 38 +++- src/Wima/WimaServiceAreaData.h | 21 +- src/Wima/doc/wima.qdocconf | 12 -- ...apVisual.qml => WimaCorridorMapVisual.qml} | 0 src/WimaView/WimaItemEditor.qml | 17 +- src/WimaView/WimaItemEditor_old.qml | 142 -------------- ...itor.qml => WimaMeasurementAreaEditor.qml} | 0 ...l.qml => WimaMeasurementAreaMapVisual.qml} | 3 +- src/WimaView/WimaServicePolygonMapVisual.qml | 86 -------- src/WimaView/WimaView.qml | 81 ++++---- src/ui/MainWindowInner.qml | 4 +- 44 files changed, 990 insertions(+), 739 deletions(-) rename src/Wima/{WimaGOperationArea.SettingsGroup.json => WimaMeasurementArea.SettingsGroup.json} (65%) create mode 100644 src/Wima/WimaMeasurementAreaData.cc delete mode 100644 src/Wima/WimaMeasurementAreaDataareadata.cc create mode 100644 src/Wima/WimaPlanData.cc create mode 100644 src/Wima/WimaPlanData.h rename src/WimaView/{WimaVCorridorMapVisual.qml => WimaCorridorMapVisual.qml} (100%) delete mode 100644 src/WimaView/WimaItemEditor_old.qml rename src/WimaView/{WimaGOperationAreaEditor.qml => WimaMeasurementAreaEditor.qml} (100%) rename src/WimaView/{WimaGOperationAreaMapVisual.qml => WimaMeasurementAreaMapVisual.qml} (97%) delete mode 100644 src/WimaView/WimaServicePolygonMapVisual.qml diff --git a/master.qdocconf b/master.qdocconf index 254ca02c0..3f4eafd6d 100644 --- a/master.qdocconf +++ b/master.qdocconf @@ -6,6 +6,7 @@ sourcedirs = ./src/Wima headers = ./src/Wima/WimaArea.h sources = ./src/Wima/WimaArea.cc + sources.fileextensions = "*.cpp *.cc *.qdoc *.mm *.qml" headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index e930bb831..6ba3ab3d1 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -420,7 +420,8 @@ HEADERS += \ src/Wima/WimaAreaData.h \ src/Wima/WimaServiceAreaData.h \ src/Wima/WimaCorridorData.h \ - src/Wima/WimaMeasurementAreaData.h + src/Wima/WimaMeasurementAreaData.h \ + src/Wima/WimaPlanData.h SOURCES += \ src/api/QGCCorePlugin.cc \ src/api/QGCOptions.cc \ @@ -439,7 +440,8 @@ SOURCES += \ src/Wima/WimaAreaData.cc \ src/Wima/WimaServiceAreaData.cc \ src/Wima/WimaCorridorData.cpp \ - src/Wima/WimaMeasurementAreaDataareadata.cc + src/Wima/WimaPlanData.cc \ + src/Wima/WimaMeasurementAreaData.cc # # Unit Test specific configuration goes here (requires full debug build with all plugins) @@ -1321,4 +1323,4 @@ contains (CONFIG, QGC_DISABLE_INSTALLER_SETUP) { } DISTFILES += \ - src/Wima/WimaGOperationArea.SettingsGroup.json + src/WimaView/WimaMeasurementAreaEditor.qml diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 942ee057c..1487b504f 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -211,16 +211,15 @@ src/WimaView/WimaToolBar.qml src/WimaView/WimaView.qml src/WimaView/WimaMapVisual.qml - src/WimaView/WimaServicePolygonMapVisual.qml src/WimaView/WimaItemEditor.qml src/WimaView/WimaMapPolylineVisuals.qml src/WimaView/WimaMapPolygonVisuals.qml - src/WimaView/WimaGOperationAreaMapVisual.qml src/WimaView/WimaServiceAreaMapVisual.qml - src/WimaView/WimaGOperationAreaEditor.qml src/WimaView/WimaServiceAreaEditor.qml - src/WimaView/WimaVCorridorMapVisual.qml src/WimaView/WimaAreaMapVisual.qml + src/WimaView/WimaMeasurementAreaMapVisual.qml + src/WimaView/WimaCorridorMapVisual.qml + src/WimaView/WimaMeasurementAreaEditor.qml src/Settings/APMMavlinkStreamRate.SettingsGroup.json @@ -265,7 +264,7 @@ src/Vehicle/VibrationFact.json src/Vehicle/WindFact.json src/Settings/Video.SettingsGroup.json - src/Wima/WimaGOperationArea.SettingsGroup.json + src/Wima/WimaMeasurementArea.SettingsGroup.json src/comm/APMArduCopterMockLink.params diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index 98edc17e8..673974b02 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -117,7 +117,7 @@ QGCView { WimaController { id: wimaController Component.onCompleted: { - startWimaController(true /* flyView */) + wimaController.dataContainer = Qt.binding(function() { return dataContainerPointer }) } } @@ -136,9 +136,8 @@ QGCView { flyViewOverlay.source = QGroundControl.corePlugin.options.flyViewOverlay } - wimaController.masterController = masterController - wimaController.missionController = masterController.missionController - wimaController.dataContainer = dataContainer + wimaController.masterController = Qt.binding(function() { return masterController; }) + wimaController.missionController = Qt.binding(function() { return masterController.missionController; }) } // The following code is used to track vehicle states such that we prompt to remove mission from vehicle when mission completes diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlightDisplayViewMap.qml index 3ab72e3ca..8b8cdb543 100644 --- a/src/FlightDisplay/FlightDisplayViewMap.qml +++ b/src/FlightDisplay/FlightDisplayViewMap.qml @@ -194,13 +194,16 @@ FlightMap { } // Add wima Areas to the Map - WimaMapPolygonVisuals { - mapControl: flightMap - mapPolygon: wimaController.joinedArea - borderWidth: 1 - borderColor: "transparent" - interiorColor: "gray" - interiorOpacity: 0.25 + MapItemView { + model: wimaController.visualItems + + delegate: MapPolygon{ + path: object.path; + border.color: "black" + color: "green" + opacity: 0.25 + z: QGroundControl.zOrderTrajectoryLines-1 + } } // Add trajectory points to the map diff --git a/src/MissionManager/QGCMapPolygon.cc b/src/MissionManager/QGCMapPolygon.cc index af4d65fef..848ec6d4e 100644 --- a/src/MissionManager/QGCMapPolygon.cc +++ b/src/MissionManager/QGCMapPolygon.cc @@ -369,11 +369,6 @@ void QGCMapPolygon::setInteractive(bool interactive) } } -void QGCMapPolygon::update(const QGCMapPolygon &poly) -{ - this->setPath(poly.path()); -} - void print(const QGCMapPolygon &poly) { QString message; @@ -384,18 +379,18 @@ void print(const QGCMapPolygon &poly) void print(const QGCMapPolygon &poly, QString &outputString) { - outputString.append(QString("Coordinates:\n")); + outputString.append(QString("Coordinates:\r\n")); for (int i = 0; i < poly.count(); i++) { QGeoCoordinate coordinate = poly.vertexCoordinate(i); - outputString.append(QString("%s\n").arg(coordinate.toString(QGeoCoordinate::Degrees))); + outputString.append(QString("%1\n").arg(coordinate.toString(QGeoCoordinate::Degrees))); } - outputString.append(QString("Dirty: %s\n").arg(QVariant(poly._dirty).toString())); - outputString.append(QString("Center: %s\n").arg(poly._center.toString(QGeoCoordinate::Degrees))); - outputString.append(QString("Center Drag: %s\n").arg(QVariant(poly._centerDrag).toString())); - outputString.append(QString("Ignore Center Updates: %s\n").arg(QVariant(poly._centerDrag).toString())); - outputString.append(QString("Interactive: %s\n").arg(QVariant(poly._interactive).toString())); + outputString.append(QString("Dirty: %1\n").arg(QVariant(poly._dirty).toString())); + outputString.append(QString("Center: %1\n").arg(poly._center.toString(QGeoCoordinate::Degrees))); + outputString.append(QString("Center Drag: %1\n").arg(QVariant(poly._centerDrag).toString())); + outputString.append(QString("Ignore Center Updates: %1\n").arg(QVariant(poly._centerDrag).toString())); + outputString.append(QString("Interactive: %1\n").arg(QVariant(poly._interactive).toString())); } QGeoCoordinate QGCMapPolygon::vertexCoordinate(int vertex) const diff --git a/src/MissionManager/QGCMapPolygon.h b/src/MissionManager/QGCMapPolygon.h index f98a0f25b..1eea84ead 100644 --- a/src/MissionManager/QGCMapPolygon.h +++ b/src/MissionManager/QGCMapPolygon.h @@ -99,9 +99,6 @@ public: QmlObjectListModel* qmlPathModel(void) { return &_polygonModel; } QmlObjectListModel& pathModel (void) { return _polygonModel; } - /// Updates this with data from poly - void update(const QGCMapPolygon &poly); - // Friends friend void print(const QGCMapPolygon& poly, QString& outputString); friend void print(const QGCMapPolygon& poly); diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 07e9ebe64..c70779885 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -67,8 +67,9 @@ #include "FlightMapSettings.h" #include "CoordinateVector.h" #include "PlanMasterController.h" -#include "Wima/WimaController.h" //custom -#include "Wima/WimaDataContainer.h" //custom +#include "Wima/WimaController.h" +#include "Wima/WimaDataContainer.h" +#include "Wima/WimaPlaner.h" #include "VideoManager.h" #include "VideoSurface.h" #include "VideoReceiver.h" @@ -465,8 +466,9 @@ void QGCApplication::_initCommon(void) qmlRegisterType (kQGCControllers, 1, 0, "MavlinkConsoleController"); #endif // Wima - qmlRegisterType ("Wima", 1, 0, "WimaController"); //custom - qmlRegisterType ("Wima", 1, 0, "WimaDataContainer"); //custom + qmlRegisterType ("Wima", 1, 0, "WimaController"); + qmlRegisterType ("Wima", 1, 0, "WimaPlaner"); + qmlRegisterType ("Wima", 1, 0, "WimaDataContainer"); // Register Qml Singletons diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index d6d7e8ed2..65c3d97d7 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -86,12 +86,12 @@ ViewWidget 1.0 ViewWidget.qml FlyAreaItemEditor 1.0 FlyAreaItemEditor.qml WimaMapVisual 1.0 WimaMapVisual.qml -WimaGOperationAreaMapVisual 1.0 WimaGOperationAreaMapVisual.qml -WimaGOperationAreaEditor 1.0 WimaGOperationAreaEditor.qml +WimaMeasurementAreaMapVisual 1.0 WimaMeasurementAreaMapVisual.qml +WimaMeasurementAreaEditor 1.0 WimaMeasurementAreaEditor.qml WimaServiceAreaMapVisual 1.0 WimaServiceAreaMapVisual.qml WimaAreaMapVisual 1.0 WimaAreaMapVisual.qml WimaServiceAreaEditor 1.0 WimaServiceAreaEditor.qml -WimaVCorridorMapVisual 1.0 WimaVCorridorMapVisual.qml +WimaCorridorMapVisual 1.0 WimaCorridorMapVisual.qml WimaItemEditor 1.0 WimaItemEditor.qml WimaMapPolygonVisuals 1.0 WimaMapPolygonVisuals.qml WimaMapPolylineVisuals 1.0 WimaMapPolylineVisuals.qml diff --git a/src/Wima/WimaArea.cc b/src/Wima/WimaArea.cc index 835e46556..ed5e233f1 100644 --- a/src/Wima/WimaArea.cc +++ b/src/Wima/WimaArea.cc @@ -1,10 +1,10 @@ #include "WimaArea.h" /*! - * \variable WimaArea::numericalAccuracy - * \brief The accuracy used for calculations. + * \variable WimaArea::epsilonMeter + * \brief The accuracy used for distance calculations (unit: m). */ -const double WimaArea::numericalAccuracy = 1e-3; // meters +const double WimaArea::epsilonMeter = 1e-5; /*! * \variable WimaArea::maxAltitudeName * \brief A string containing the name of the \c _maxAltitude member. Among other used for storing. @@ -23,7 +23,7 @@ const char* WimaArea::areaTypeName = "AreaType"; - +// Constructors WimaArea::WimaArea(QObject *parent) : QGCMapPolygon (parent) { @@ -32,14 +32,26 @@ WimaArea::WimaArea(QObject *parent) } WimaArea::WimaArea(const WimaArea &other, QObject *parent) - : QGCMapPolygon (other, parent) + : QGCMapPolygon (parent) { init(); + *this = other; +} + +/*! + *\fn WimaArea &WimaArea::operator=(const WimaArea &other) + * + * Assigns \a other to this \c WimaArea and returns a reference to this \c WimaArea. + * + * Copies only path and maximum altitude. + */ +WimaArea &WimaArea::operator=(const WimaArea &other) +{ + QGCMapPolygon::operator=(other); + this->_maxAltitude = other.maxAltitude(); this->setPath(other.path()); - this->setCenter(other.center()); - this->setCenterDrag(other.centerDrag()); - this->setInteractive(other.interactive()); - _maxAltitude = other.maxAltitude(); + + return *this; } /*! @@ -118,29 +130,29 @@ QGCMapPolygon WimaArea::toQGCPolygon() const } /*! - * \fn void WimaArea::join(QList* polyList, WimaArea* joinedPoly) - * Not yet implemented \a polyList, \a joinedPoly. - * - * \sa QList - */ -void WimaArea::join(QList* polyList, WimaArea* joinedPoly) -{ - return; -} - -/*! - * \fn bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) + * \fn bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea, QString &errorString) * Joins the areas \a area1 and \a area2 such that a \l {Simple Polygon} is created. * Stores the result inside \a joinedArea. + * Stores error messages in \a errorString. * Returns \c true if the algorithm was able to join the areas; false else. * The algorithm will be able to join the areas, if either their edges intersect with each other, * or one area contains the other. */ -bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) +bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea, QString &errorString) { if (area1.count() >= 3 && area2.count() >= 3) { + if ( isSelfIntersecting(area1) ) { + errorString.append("Area 1 is self intersecting.\n"); + return false; + } + + if ( isSelfIntersecting(area2) ) { + errorString.append("Area 2 is self intersecting.\n"); + return false; + } + joinedArea.clear(); area1.verifyClockwiseWinding(); @@ -208,7 +220,7 @@ bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) //qDebug("MinDistIndex: %i", minDistIndex); QGeoCoordinate protoCurrentVertex = intersectionList.value(minDistIndex); // take numerical erros into account - if (protoCurrentVertex.distanceTo(currentVertex) > WimaArea::numericalAccuracy) { + if (protoCurrentVertex.distanceTo(currentVertex) > epsilonMeter) { currentVertex = protoCurrentVertex; QPair neighbours = neighbourList.value(minDistIndex); protoNextVertex = crossPoly->vertexCoordinate(neighbours.second); @@ -244,6 +256,21 @@ bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) } } + +/*! + * \fn bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) + * Joins the areas \a area1 and \a area2 such that a \l {Simple Polygon} is created. + * Stores the result inside \a joinedArea. + * Returns \c true if the algorithm was able to join the areas; false else. + * The algorithm will be able to join the areas, if either their edges intersect with each other, + * or one area contains the other. + */ +bool WimaArea::join(WimaArea &area1, WimaArea &area2, WimaArea &joinedArea) +{ + QString dummy; + return join(area1, area2, joinedArea, dummy); +} + /*! * \fn bool WimaArea::join(WimaArea &area) * Joins the calling \c WimaArea and the \a area such that a \l {Simple Polygon} is created. @@ -263,49 +290,25 @@ bool WimaArea::join(WimaArea &area) } } -/*! - * \fn bool WimaArea::isDisjunct(QList* polyList) - * Not yet implemented. - * - * \sa QList - */ -bool WimaArea::isDisjunct(QList* polyList) -{ - // needs improvement - if (polyList != nullptr){ - for (int i = 0;i < polyList->size()-1; i++) { - WimaArea* currPoly = polyList->value(i); - for (int j = i+1; i < polyList->size(); j++) { - if (isDisjunct(currPoly, polyList->value(j))) { - return false; - } - } - } - return true; - } else { - qWarning("WimaArea::isDisjunct(polyList): polyList == nullptr!"); - return false; - } -} /*! - * \fn bool WimaArea::isDisjunct(WimaArea *poly1, WimaArea *poly2) - * Not yet implemented. + * \fn bool WimaArea::join(WimaArea &area, QString &errorString) + * Joins the calling \c WimaArea and the \a area such that a \l {Simple Polygon} is created. + * Overwrites the calling \c WimaArea with the result, if the algorithm was successful. + * + * Returns \c true if the algorithm was able to join the areas; false else. + * Stores error messages in \a errorString. + * + * The algorithm will be able to join the areas, if either their edges intersect with each other, + * or one area contains the other. */ -bool WimaArea::isDisjunct(WimaArea *poly1, WimaArea *poly2) +bool WimaArea::join(WimaArea &area, QString &errorString) { - if (poly1 != nullptr && poly2 != nullptr) { - QGCMapPolygon* poly1Copy = new QGCMapPolygon(this); - poly1Copy->setPath(poly1->path()); - poly1Copy->offset(numericalAccuracy);// take numerical errors in account - for(int i = 0; i < poly2->count(); i++){ - if (poly1Copy->containsCoordinate(poly2->vertexCoordinate(i))){ - return false; - } - } + WimaArea joinedArea; + if ( join(*this, area, joinedArea, errorString) ) { + this->setPath(joinedArea.path()); return true; } else { - qWarning("WimaArea::isDisjunct(poly1, poly2): poly1 == nullptr || poly2 == nullptr!"); return false; } } @@ -404,13 +407,13 @@ bool WimaArea::intersects(const QGCMapPolyline &line1, const QGCMapPolyline &lin * * \sa QPair, QList */ -bool WimaArea::intersects(const QGCMapPolyline &line, const WimaArea &area, QList &intersectionList, QList> &neighbourList) +bool WimaArea::intersects(const QGCMapPolyline &line, const WimaArea &area, QList &intersectionList, QList> &neighbourList)// don't seperate parameters with new lines or documentation will break { intersectionList.clear(); neighbourList.clear(); - if (line.count() == 2 && area.count() >= 3) { // are line a proper line and poly a proper poly? + if (line.count() == 2 && area.count() >= 3) { // are line a proper line and poly a proper poly?other, // Asseble a line form each tow consecutive polygon vertices and check whether it intersects with line for (int i = 0; i < area.count(); i++) { @@ -443,7 +446,7 @@ bool WimaArea::intersects(const QGCMapPolyline &line, const WimaArea &area, QLis } } -/*! +/*!other, * \fn double WimaArea::distInsidePoly(const QGeoCoordinate &c1, const QGeoCoordinate &c2, WimaArea area) * Returns the distance between the coordinate \a c1 and coordinate \a c2, or infinity if the shortest path between * the two coordinates is not fully inside the \a area. @@ -475,21 +478,19 @@ double WimaArea::distInsidePoly(const QGeoCoordinate &c1, const QGeoCoordinate & } /*! - * \fn bool WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &end, const WimaArea &area, QList &dijkstraPath) + * \fn bool WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &end, const WimaArea &area, QList &dijkstraPath, QString &errorstring) * Calculates the shortest path (inside \a area) between \a start and \a end. * The \l {Dijkstra Algorithm} is used to find the shorest path. * Stores the result inside \a dijkstraPath when sucessfull. + * Stores error messages in \a errorString. * Returns \c true if successful, \c false else. * * \sa QList */ -bool WimaArea::dijkstraPath(const QGeoCoordinate &start, - const QGeoCoordinate &end, - const WimaArea &area, - QList &dijkstraPath) +bool WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &end, const WimaArea &area, QList &dijkstraPath, QString &errorString) // don't seperate parameters with new lines or documentation will break { - // Returns true if a valid path was found. if ( isSelfIntersecting(area) ) { + errorString.append("Area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"); return false; } @@ -568,21 +569,23 @@ bool WimaArea::dijkstraPath(const QGeoCoordinate &start, // end Djikstra Algorithm - // check it the Algorithm was sucessful + // check it the Algorithm was sucessfulepsilonMeter Node* Node = &nodeList.last(); if (Node->predecessorNode == nullptr) { - qWarning("WimaArea::dijkstraPath(): Error, no path found!"); - return false; + } - // assemble path + // reverse assemble path while (1) { dijkstraPath.prepend(Node->coordinate); //Update Node Node = Node->predecessorNode; if (Node == nullptr) { - break; + if (dijkstraPath[0].distanceTo(start) < epsilonMeter)// check if starting point was reached + break; + qWarning("WimaArea::dijkstraPath(): Error, no path found!\n"); + return false; } } @@ -600,18 +603,26 @@ bool WimaArea::isSelfIntersecting(const WimaArea &area) if (area.count() > 3) { // check if any edge of the area (formed by two adjacent vertices) intersects with any other edge of the area while(i < area.count()-1) { + QGeoCoordinate refBeginCoordinate = area.vertexCoordinate(i); + QGeoCoordinate refEndCoordinate = area.vertexCoordinate(area.nextVertexIndex(i)); QGCMapPolyline refLine; - refLine.appendVertex(area.vertexCoordinate(i)); - refLine.appendVertex(area.vertexCoordinate(area.nextVertexIndex(i))); + refLine.appendVertex(refBeginCoordinate); + refLine.appendVertex(refEndCoordinate); int j = area.nextVertexIndex(i); while(j < area.count()) { - QGeoCoordinate dummy; + QGeoCoordinate intersectionPt; QGCMapPolyline iteratorLine; iteratorLine.appendVertex(area.vertexCoordinate(j)); iteratorLine.appendVertex(area.vertexCoordinate(area.nextVertexIndex(j))); - if ( intersects(refLine, iteratorLine, dummy) ) - return true; + if ( intersects(refLine, iteratorLine, intersectionPt) ){ + if ( !(intersectionPt.distanceTo(refBeginCoordinate) < epsilonMeter) + && !(intersectionPt.distanceTo(refEndCoordinate) < epsilonMeter) ) { + return true; + } + } + + j++; } @@ -670,16 +681,6 @@ bool WimaArea::loadFromJson(const QJsonObject &json, QString& errorString) } } -/*! - * \fn void WimaArea::update(const WimaArea &area) - * Not yet implemented. - */ -void WimaArea::update(const WimaArea &area) -{ - this->QGCMapPolygon::update(area); - this->setMaxAltitude(area.maxAltitude()); -} - /*! * \fn void WimaArea::init() * Funtion to be called during construction. @@ -706,9 +707,9 @@ void print(const WimaArea &area) */ void print(const WimaArea &area, QString &outputString) { - outputString.append(QString("Type: %1").arg(area.objectName())); + outputString.append(QString("Type: %1\n").arg(area.objectName())); print(static_cast(area), outputString); - outputString.append(QString("Maximum Altitude: %1").arg(area._maxAltitude)); + outputString.append(QString("Maximum Altitude: %1\n").arg(area._maxAltitude)); } diff --git a/src/Wima/WimaArea.h b/src/Wima/WimaArea.h index 6ab10f3ed..1914f4ccc 100644 --- a/src/Wima/WimaArea.h +++ b/src/Wima/WimaArea.h @@ -17,6 +17,7 @@ class WimaArea : public QGCMapPolygon //abstract base class for all WimaAreas public: WimaArea(QObject* parent = nullptr); WimaArea(const WimaArea& other, QObject* parent = nullptr); + WimaArea &operator=(const WimaArea &other); Q_PROPERTY(double maxAltitude READ maxAltitude WRITE setMaxAltitude NOTIFY maxAltitudeChanged) @@ -31,20 +32,12 @@ public: virtual QString editorQML (void) const { return "WimaAreaEditor.qml";} // Member Methodes - //iterates over all vertices in _polygon and returns the index of that one closest to coordinate int getClosestVertexIndex (const QGeoCoordinate& coordinate) const; - //iterates over all vertices in _polygon and returns that one closest to coordinate QGeoCoordinate getClosestVertex (const QGeoCoordinate& coordinate) const; QGCMapPolygon toQGCPolygon () const; - void join (QList* polyList, WimaArea* joinedPoly);// change to & notation bool join (WimaArea &area); - bool isDisjunct (QList* polyList);// change to & notation, if necessary - bool isDisjunct (WimaArea* poly1, WimaArea* poly2);// change to & notation, if necessary - /// calculates the next polygon vertex index - /// @return index + 1 if index < poly->count()-1 && index >= 0, or 0 if index == poly->count()-1, -1 else + bool join (WimaArea &area, QString &errorString); int nextVertexIndex (int index) const; - /// calculates the previous polygon vertex index - /// @return index - 1 if index < poly->count() && index > 0, or poly->count()-1 if index == 0, -1 else int previousVertexIndex (int index) const; @@ -53,45 +46,26 @@ public: // static Methodes static QGCMapPolygon toQGCPolygon (const WimaArea& area); - /// joins the poly1 and poly2 if possible, joins the polygons to form a simple polygon (no holes) - /// see https://en.wikipedia.org/wiki/Simple_polygon - /// @return true if polygons have been joined, false else + static bool join (WimaArea &area1, WimaArea &area2, WimaArea& joinedArea, QString &errorString); static bool join (WimaArea &area1, WimaArea &area2, WimaArea& joinedArea); - /// checks if line1 and line2 intersect with each other, takes latitude and longitute into account only (height neglected) - /// @param line1 line containing two coordinates, height not taken into account - /// @param line2 line containing two coordinates, height not taken into account - /// @param intersectionPt Coordinate item to store intersection pt. in. - /// @return false on error or no intersection, true else static bool intersects (const QGCMapPolyline& line1, const QGCMapPolyline& line2, QGeoCoordinate& intersectionPt); - /// checks if line1 and poly intersect with each other, takes latitude and longitute into account only (height neglected) - /// @param line line containing two coordinates, height not taken into account - /// @param intersectionList Empty list to store intersection points in. - /// @param neighbourList Empty list to store the indices of the neighbours (the two Vertices of poly with the smallest distance to the intersection pt.) - /// @return false on error or no intersection, true else static bool intersects (const QGCMapPolyline& line, const WimaArea& area, QList& intersectionList, QList>& neighbourList); - /// calculates the distance between to geo coordinates, returns the distance if the path lies within the polygon and inf. else. - /// @return the distance if the path lies within the polygon and inf. else. static double distInsidePoly (const QGeoCoordinate& c1, const QGeoCoordinate& c2, WimaArea area); - /// calculates the shortes path between two geo coordinates inside a polygon using the Dijkstra Algorithm - /// @return true if path was found, false else static bool dijkstraPath (const QGeoCoordinate& c1, const QGeoCoordinate& c2, - const WimaArea& area, QList& dijkstraPath); - /// @return true if the polygon is self intersecting - static bool isSelfIntersectin contrast to \c WimaAreaing (const WimaArea& area); + const WimaArea& area, QList& dijkstraPath, QString &errorstring); + static bool isSelfIntersecting (const WimaArea& area); bool isSelfIntersecting (); // Friends - /// prints the member values of area to the outputString friend void print(const WimaArea& area, QString& outputString); - /// prints the member values of area to the console friend void print(const WimaArea& area); // static Members // Accurracy used to compute isDisjunct - static const double numericalAccuracy; + static const double epsilonMeter; static const char* maxAltitudeName; static const char* wimaAreaName; static const char* areaTypeName; @@ -101,8 +75,6 @@ signals: public slots: void setMaxAltitude (double altitude); - /// Updates this with data from area - void update(const WimaArea& area); private: double _maxAltitude; diff --git a/src/Wima/WimaAreaData.cc b/src/Wima/WimaAreaData.cc index 9498e8a4e..248699a8e 100644 --- a/src/Wima/WimaAreaData.cc +++ b/src/Wima/WimaAreaData.cc @@ -1,15 +1,50 @@ -#include "WimaAreaData.h" +#include "WimaAreaData.h" + +const char *WimaAreaData::typeString = "WimaAreaData"; WimaAreaData::WimaAreaData(QObject *parent) : QObject(parent) { _maxAltitude = 0; } -WimaAreaData::WimaAreaData(WimaAreaData &other, QObject *parent) +WimaAreaData::WimaAreaData(const WimaAreaData &other, QObject *parent) + : QObject (parent) +{ + *this = other; +} + +WimaAreaData::WimaAreaData(const WimaArea &other, QObject *parent) : QObject (parent) - , _maxAltitude(other.maxAltitude()) { - setPath(other.path()); + *this = other; +} + +/*! + * \fn WimaAreaData &WimaAreaData::operator=(const WimaAreaData &otherData) + * + * Copies the maximum altitude and the path of the \c WimaAreaData \a otherData to the calling object. + * Returns a reference to the calling object. + */ +WimaAreaData &WimaAreaData::operator=(const WimaAreaData &otherData) +{ + setMaxAltitude(otherData.maxAltitude()); + setPath(otherData.path()); + + return *this; +} + +/*! + * \overload operator=() + * + * Copies the maximum altitude and the path of \c WimaArea \a otherArea to the calling object. + * Returns a reference to the calling object. + */ +WimaAreaData &WimaAreaData::operator=(const WimaArea &otherArea) +{ + setMaxAltitude(otherArea.maxAltitude()); + setPath(otherArea.coordinateList()); + + return *this; } /*! @@ -27,11 +62,21 @@ double WimaAreaData::maxAltitude() const * * Returns the path (vertex list defining the \l {Simple Polygon}). */ -const QList &WimaAreaData::path() const +QVariantList WimaAreaData::path() const { return _path; } +/*! + * \fn QString WimaAreaData::type() + * + * Returns the type name of the object. Used to destinguish between derived objects. + */ +QString WimaAreaData::type() const +{ + return typeString; +} + /*! * \fn void WimaAreaData::setMaxAltitude(double maxAltitude) * @@ -47,6 +92,13 @@ void WimaAreaData::setMaxAltitude(double maxAltitude) } } +void WimaAreaData::setPath(const QVariantList &coordinateList) +{ + _path.clear(); + _path.append(coordinateList); +} + + /*! * \fn void WimaAreaData::setPath(const QList &coordinateList) * @@ -59,7 +111,7 @@ void WimaAreaData::setPath(const QList &coordinateList) // copy all coordinates to _path for(int i = 0; i < coordinateList.size(); i++) { - _path.append(coordinateList.value(i)); + _path.append(QVariant::fromValue(coordinateList.value(i))); } emit pathChanged(_path); @@ -69,9 +121,8 @@ void WimaAreaData::setPath(const QList &coordinateList) * \class WimaArea::WimaAreaData * \brief Class to store and exchange data of a \c WimaArea Object. * Class to store and exchange data of a \c WimaArea Object. In contrast to \c WimaArea this class - * does not provied any interface to a grafical user interface, neiter it uses the QGC Fact System. - * It is designed to exchange data between the \c WimaPlaner and the \c WimaController class. And it - * is the base class for any derived data objects + * does not uses the QGC Fact System. It is designed to exchange data between the \c WimaPlaner and + * the \c WimaController class. And it is the base class for any derived data objects * * \sa WimaArea */ diff --git a/src/Wima/WimaAreaData.h b/src/Wima/WimaAreaData.h index 22916740d..ba2f6c8e1 100644 --- a/src/Wima/WimaAreaData.h +++ b/src/Wima/WimaAreaData.h @@ -4,29 +4,42 @@ #include "QGeoCoordinate" +#include "WimaArea.h" + class WimaAreaData : public QObject { Q_OBJECT public: - explicit WimaAreaData(QObject *parent = nullptr); - explicit WimaAreaData(WimaAreaData &other, QObject *parent = nullptr); + Q_PROPERTY(const QVariantList path READ path NOTIFY pathChanged) - double maxAltitude() const; - const QList& path() const; + WimaAreaData(QObject *parent = nullptr); + WimaAreaData(const WimaAreaData &other, QObject *parent = nullptr); + WimaAreaData(const WimaArea &other, QObject *parent = nullptr); + WimaAreaData& operator=(const WimaAreaData& otherData); + WimaAreaData& operator=(const WimaArea& otherArea); -signals: - void maxAltitudeChanged(double maxAltitude); - void pathChanged(const QList& coordinateList); + double maxAltitude() const; + QVariantList path() const; + QString type() const; + static const char *typeString; + +signals: + void maxAltitudeChanged (double maxAltitude); + void pathChanged (const QVariantList& coordinateList); public slots: void setMaxAltitude(double maxAltitude); - void setPath(const QList& coordinateList); + void setPath(const QList &coordinateList); + void setPath(const QVariantList &coordinateList); private: + // Member Functions + + // Member Variables // see WimaArea.h for explanation - double _maxAltitude; - QList _path; + double _maxAltitude; + QVariantList _path; }; diff --git a/src/Wima/WimaController.cc b/src/Wima/WimaController.cc index 9c98377a5..810d698f4 100644 --- a/src/Wima/WimaController.cc +++ b/src/Wima/WimaController.cc @@ -6,12 +6,12 @@ const char* WimaController::missionItemsName = "MissionItems"; WimaController::WimaController(QObject *parent) : QObject (parent) - , _readyForSaveSend (false) , _container (nullptr) , _joinedArea (this) - , _opArea (this) - , _serArea (this) + , _measurementArea (this) + , _serviceArea (this) , _corridor (this) + , _localPlanDataValid (false) { } @@ -38,9 +38,9 @@ QStringList WimaController::saveNameFilters() const return filters; } -QGeoCoordinate WimaController::joinedAreaCenter() const +WimaDataContainer *WimaController::dataContainer() const { - return _joinedArea.center(); + return _container; } void WimaController::setMasterController(PlanMasterController *masterC) @@ -55,21 +55,26 @@ void WimaController::setMissionController(MissionController *missionC) emit missionControllerChanged(); } +/*! + * \fn void WimaController::setDataContainer(WimaDataContainer *container) + * Sets the pointer to the \c WimaDataContainer, which is meant to exchange data between the \c WimaController and the \c WimaPlaner. + * + * \sa WimaPlaner, WimaDataContainer, WimaPlanData + */ void WimaController::setDataContainer(WimaDataContainer *container) { - if (_container == nullptr && container != nullptr) { + if (container != nullptr) { + if (_container != nullptr) { + disconnect(_container, &WimaDataContainer::dataValidChanged, this, &WimaController::containerDataValidChanged); + } + _container = container; - pullFromContainer(); + connect(_container, &WimaDataContainer::dataValidChanged, this, &WimaController::containerDataValidChanged); emit dataContainerChanged(); } } -void WimaController::startWimaController(bool flyView) -{ - -} - void WimaController::startMission() { @@ -118,14 +123,88 @@ bool WimaController::loadFromFile(const QString &filename) QJsonDocument WimaController::saveToJson(FileType fileType) { - + return QJsonDocument(); } -void WimaController::setReadyForSaveSend(bool ready) +/*! + * \fn void WimaController::containerDataValidChanged(bool valid) + * Pulls plan data generated by \c WimaPlaner from the \c _container if the data is valid (\a valid equals true). + * Is connected to the dataValidChanged() signal of the \c WimaDataContainer. + * + * \sa WimaDataContainer, WimaPlaner, WimaPlanData + */ +void WimaController::containerDataValidChanged(bool valid) { - if (ready != _readyForSaveSend) { - _readyForSaveSend = ready; - emit readyForSaveSendChanged(ready); + if ( valid ) { + if (_container == nullptr) { + qWarning("WimaController::containerDataValidChanged(): No container assigned!"); + } + _localPlanDataValid = false; + WimaPlanData planData = _container->pull(); + + // extract list with WimaAreas + QList areaList = planData.areaList(); + + int areaCounter = 0; + int numAreas = 4; // extract only numAreas Areas, if there are more they are invalid and ignored + bool joinedAreaAssigned = false; + for (int i = 0; i < areaList.size(); i++) { + const WimaAreaData *areaData = areaList[i]; + + + if (areaData->type() == WimaServiceAreaData::typeString) { // is it a service area? + _serviceArea = *qobject_cast(areaData); + qWarning("Service area, wuhuuu!"); + areaCounter++; + + continue; + } + + WimaMeasurementAreaData *measurementAreaData = qobject_cast(areaData); + if (measurementAreaData != nullptr) { // is it a measurement area? + _measurementArea = *measurementAreaData; + qWarning("Measurement area, wuhuuu!"); + areaCounter++; + + continue; + } + + WimaCorridorData *corridorAreaData = qobject_cast(areaData); + if (corridorAreaData != nullptr) { // is it a corridor? + _corridor = *corridorAreaData; + qWarning("Corridor, wuhuuu!"); + areaCounter++; + + continue; + } + + if (!joinedAreaAssigned) { // first WimaAreaData object is assumed to be the joined Area + _joinedArea = *areaData; + qWarning("Joined area, wuhuuu!"); + areaCounter++; + joinedAreaAssigned = true; + + continue; + } + + if (areaCounter >= numAreas) + break; + } + + // append areas to _visualItems, don't append _corridor, it's not necessary to display it in flyView + _visualItems.clear(); + //_visualItems.append(&_measurementArea); + //_visualItems.append(&_serviceArea); + _visualItems.append(&_joinedArea); + + emit visualItemsChanged(); + + _localPlanDataValid = true; + } else { + _localPlanDataValid = false; + _visualItems.clear(); + + emit visualItemsChanged(); } } @@ -133,3 +212,5 @@ void WimaController::setReadyForSaveSend(bool ready) + + diff --git a/src/Wima/WimaController.h b/src/Wima/WimaController.h index b4bd60e1e..92f81ae30 100644 --- a/src/Wima/WimaController.h +++ b/src/Wima/WimaController.h @@ -9,6 +9,9 @@ #include "WimaServiceArea.h" #include "WimaCorridor.h" #include "WimaDataContainer.h" +#include "WimaMeasurementAreaData.h" +#include "WimaCorridorData.h" +#include "WimaServiceAreaData.h" #include "PlanMasterController.h" #include "MissionController.h" @@ -36,24 +39,19 @@ public: Q_PROPERTY(QStringList loadNameFilters READ loadNameFilters CONSTANT) Q_PROPERTY(QStringList saveNameFilters READ saveNameFilters CONSTANT) Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT) - Q_PROPERTY(QGeoCoordinate joinedAreaCenter READ joinedAreaCenter CONSTANT) - Q_PROPERTY(QGCMapPolygon joinedArea READ joinedArea NOTIFY joinedAreaChanged) - Q_PROPERTY(WimaDataContainer* dataContainer READ dataContainer WRITE setDataContainer NOTIFY dataContainerChanged) - Q_PROPERTY(bool readyForSaveSend READ readyForSaveSend NOTIFY readyForSaveSendChanged) + Q_PROPERTY(WimaDataContainer* dataContainer READ dataContainer WRITE setDataContainer NOTIFY dataContainerChanged) // Property accessors - PlanMasterController* masterController (void) const { return _masterController; } - MissionController* missionController (void) const { return _missionController; } + PlanMasterController* masterController (void) { return _masterController; } + MissionController* missionController (void) { return _missionController; } QmlObjectListModel* visualItems (void) ; QString currentFile (void) const { return _currentFile; } QStringList loadNameFilters (void) const; QStringList saveNameFilters (void) const; QString fileExtension (void) const { return wimaFileExtension; } - QGeoCoordinate joinedAreaCenter (void) const; QGCMapPolygon joinedArea (void) const; WimaDataContainer* dataContainer (void) const; - bool readyForSaveSend (void) const { return _readyForSaveSend; } @@ -63,7 +61,6 @@ public: void setDataContainer (WimaDataContainer* container); // Member Methodes - Q_INVOKABLE void startWimaController(bool flyView); Q_INVOKABLE void startMission(); Q_INVOKABLE void abortMission(); Q_INVOKABLE void pauseMission(); @@ -83,8 +80,6 @@ public: // Member Methodes QJsonDocument saveToJson(FileType fileType); - void setReadyForSaveSend(bool ready); - signals: void masterControllerChanged (void); @@ -93,21 +88,20 @@ signals: void currentFileChanged (); void dataContainerChanged (); void readyForSaveSendChanged (bool ready); - void joinedAreaChanged (); private slots: - void pullFromContainer (); + void containerDataValidChanged (bool valid); private: - bool _readyForSaveSend; // basically true if updateMission() was sucessful PlanMasterController *_masterController; MissionController *_missionController; QString _currentFile; // file for saveing WimaDataContainer *_container; // container for data exchange with WimaController QmlObjectListModel _visualItems; // contains all visible areas - // The following areas are of type QGCMapPolygon (only path information is required, as they are used for visualisation) - QGCMapPolygon _joinedArea; // joined area fromed by opArea, serArea, _corridor - QGCMapPolygon _opArea; // measurement area - QGCMapPolygon _serArea; // area for supplying - QGCMapPolygon _corridor; // corridor connecting opArea and serArea + WimaAreaData _joinedArea; // joined area fromed by opArea, serArea, _corridor + WimaMeasurementAreaData _measurementArea; // measurement area + WimaServiceAreaData _serviceArea; // area for supplying + WimaCorridorData _corridor; // corridor connecting opArea and serArea + bool _localPlanDataValid; }; + diff --git a/src/Wima/WimaCorridor.cc b/src/Wima/WimaCorridor.cc index fcf15185f..aebf438b9 100644 --- a/src/Wima/WimaCorridor.cc +++ b/src/Wima/WimaCorridor.cc @@ -16,6 +16,18 @@ WimaCorridor::WimaCorridor(const WimaCorridor &other, QObject *parent) init(); } +/*! + * \overload operator=() + * + * Calls the inherited operator WimaArea::operator=(). + */ +WimaCorridor &WimaCorridor::operator=(const WimaCorridor &other) +{ + WimaArea::operator=(other); + + return *this; +} + void WimaCorridor::saveToJson(QJsonObject &json) { this->WimaArea::saveToJson(json); @@ -34,11 +46,6 @@ bool WimaCorridor::loadFromJson(const QJsonObject &json, QString &errorString) } } -void WimaCorridor::update(const WimaCorridor &area) -{ - this->WimaArea::update(area); -} - void WimaCorridor::init() { this->setObjectName(WimaCorridorName); diff --git a/src/Wima/WimaCorridor.h b/src/Wima/WimaCorridor.h index 8f9739f56..b0019d5bf 100644 --- a/src/Wima/WimaCorridor.h +++ b/src/Wima/WimaCorridor.h @@ -12,6 +12,8 @@ public: WimaCorridor(QObject* parent = nullptr); WimaCorridor(const WimaCorridor& other, QObject* parent = nullptr); + WimaCorridor &operator=(const WimaCorridor &other); + // Overrides from WimaPolygon QString mapVisualQML (void) const { return "WimaCorridorMapVisual.qml";} QString editorQML (void) const { return "WimaCorridorEditor.qml";} @@ -30,8 +32,6 @@ public: signals: public slots: - /// Updates this with data from area - void update(const WimaCorridor& area); private: void init(); diff --git a/src/Wima/WimaCorridorData.cpp b/src/Wima/WimaCorridorData.cpp index cf3f8736d..2ebee0ddd 100644 --- a/src/Wima/WimaCorridorData.cpp +++ b/src/Wima/WimaCorridorData.cpp @@ -1,5 +1,6 @@ #include "WimaCorridorData.h" +const char *WimaCorridorData::typeString = "WimaCorridorData"; WimaCorridorData::WimaCorridorData(QObject *parent) :WimaAreaData (parent) @@ -7,10 +8,40 @@ WimaCorridorData::WimaCorridorData(QObject *parent) } -WimaCorridorData::WimaCorridorData(WimaCorridorData &other, QObject *parent) - : WimaAreaData (other, parent) +WimaCorridorData::WimaCorridorData(const WimaCorridorData &other, QObject *parent) + : WimaAreaData (parent) { + *this = other; +} + +WimaCorridorData::WimaCorridorData(const WimaCorridor &other, QObject *parent) + : WimaAreaData (parent) +{ + *this = other; +} + +/*! + * \overload operator=() + * + * Assigns \a other to the invoking object. + */ +WimaCorridorData &WimaCorridorData::operator=(const WimaCorridorData &other) +{ + WimaAreaData::operator=(other); + + return *this; +} + +/*! + * \overload operator=() + * + * Assigns \a other to the invoking object. + */ +WimaCorridorData &WimaCorridorData::operator=(const WimaCorridor &other) +{ + WimaAreaData::operator=(other); + return *this; } /*! diff --git a/src/Wima/WimaCorridorData.h b/src/Wima/WimaCorridorData.h index 758089cb9..b8efc26d4 100644 --- a/src/Wima/WimaCorridorData.h +++ b/src/Wima/WimaCorridorData.h @@ -3,6 +3,8 @@ #include #include "WimaAreaData.h" +#include "WimaCorridor.h" + #include "QGeoCoordinate" class WimaCorridorData : public WimaAreaData @@ -10,8 +12,14 @@ class WimaCorridorData : public WimaAreaData Q_OBJECT public: - explicit WimaCorridorData(QObject *parent = nullptr); - explicit WimaCorridorData(WimaCorridorData &other, QObject *parent = nullptr); + WimaCorridorData(QObject *parent = nullptr); + WimaCorridorData(const WimaCorridorData &other, QObject *parent = nullptr); + WimaCorridorData(const WimaCorridor &other, QObject *parent = nullptr); + WimaCorridorData &operator=(const WimaCorridorData &other); + WimaCorridorData &operator=(const WimaCorridor &other); + + static const char* typeString; + signals: diff --git a/src/Wima/WimaDataContainer.cc b/src/Wima/WimaDataContainer.cc index 017e3f3e0..4d0d1ae52 100644 --- a/src/Wima/WimaDataContainer.cc +++ b/src/Wima/WimaDataContainer.cc @@ -2,55 +2,75 @@ WimaDataContainer::WimaDataContainer(QObject *parent) : QObject (parent) - , _joinedArea (nullptr) - , _opArea (nullptr) - , _serArea (nullptr) - , _corridor (nullptr) + , _planData (this /* parent */) + , _dataValid (false) { } -void WimaDataContainer::setJoinedArea(const WimaArea *joinedArea) +/*! + * \fn bool WimaDataContainer::dataValid() const + * Returns \c true if the data is valid, \c false else. + */ +bool WimaDataContainer::dataValid() const { - if (_joinedArea != joinedArea) { - _joinedArea = joinedArea; - - emit joinedAreaChanged(_joinedArea); - } + return _dataValid; } -void WimaDataContainer::setOpArea(const WimaMeasurementArea *opArea) +/*! + * \fn void WimaDataContainer::push(const WimaPlanData &planData) + * + * Updates the \c WimaPlanData members content with \a planData. + * Emits the planDataChanged() signal. + * + * \sa WimaPlanData + */ +void WimaDataContainer::push(const WimaPlanData &planData) { - if (_opArea != opArea) { - _opArea = opArea; - - emit opAreaChanged(_opArea); - } + setDataValid(false); + _planData = planData; + setDataValid(true); } -void WimaDataContainer::setSerArea(const WimaServiceArea *serArea) +/*! + * \fn const WimaPlanData &WimaDataContainer::pull() const + * + * Returns a constant referenc to the \c WimaPlanData member. + * + * \sa WimaPlanData + */ +const WimaPlanData &WimaDataContainer::pull() const { - if (_serArea != serArea) { - _serArea = serArea; - - emit serAreaChanged(_serArea); - } + return _planData; } -void WimaDataContainer::setCorridor(const WimaCorridor *corridor) +/*! + * \fn void WimaDataContainer::setDataValid(bool valid) + * + * Sets the validity of the data to \a valid. + * Mainly for internal usage. Should be invoked from \c WimaPlaner only. + * + * \sa WimaPlanData + */ +void WimaDataContainer::setDataValid(bool valid) { - if (_corridor != corridor) { - _corridor = corridor; + if ( _dataValid != valid ) { + _dataValid = valid; - emit corridorChanged(_corridor); + emit dataValidChanged(_dataValid); } } -void WimaDataContainer::setVisualItems(const QmlObjectListModel *visualItems) -{ - if (_visualItems != visualItems) { - _visualItems = visualItems; +/*! + * \class WimaDataContainer + * \brief Data container designed for data exchange between \c WimaPlaner and \c WimaController. + * Data container designed for data exchange between \c WimaPlaner and \c WimaController. + * It is meant that only one instance of this class exists. Both \c WimaPlaner and \c WimaController + * have a reference to this instance and can modify its data. + * + * \sa WimaController, WimaPlaner + */ + + + - emit visualItemsChanged(_visualItems); - } -} diff --git a/src/Wima/WimaDataContainer.h b/src/Wima/WimaDataContainer.h index 4f3cdeae4..4ba9cb483 100644 --- a/src/Wima/WimaDataContainer.h +++ b/src/Wima/WimaDataContainer.h @@ -2,46 +2,31 @@ #include -#include "QmlObjectListModel.h" - -#include "WimaArea.h" -#include "WimaMeasurementArea.h" -#include "WimaServiceArea.h" -#include "WimaCorridor.h" +#include "WimaPlanData.h" class WimaDataContainer : public QObject { Q_OBJECT public: - explicit WimaDataContainer(QObject *parent = nullptr); + WimaDataContainer(QObject *parent = nullptr); WimaDataContainer(WimaDataContainer &other, QObject *parent = nullptr) = delete; WimaDataContainer(WimaDataContainer &other) = delete; - const WimaArea * joinedArea (void) { return _joinedArea; } - const WimaMeasurementArea * opArea (void) { return _opArea; } - const WimaServiceArea * serArea (void) { return _serArea; } - const WimaCorridor * corridor (void) { return _corridor; } - const QmlObjectListModel * visualItems (void) { return _visualItems; } + Q_INVOKABLE WimaDataContainer* pointerToThis() {return this;} + + bool dataValid() const; signals: - void joinedAreaChanged (const WimaArea *area); - void opAreaChanged (const WimaMeasurementArea *area); - void serAreaChanged (const WimaServiceArea *area); - void corridorChanged (const WimaCorridor *area); - void visualItemsChanged (const QmlObjectListModel *area); + void dataValidChanged (bool valid); public slots: - void setJoinedArea (const WimaArea *joinedArea); - void setOpArea (const WimaMeasurementArea *opArea); - void setSerArea (const WimaServiceArea *serArea); - void setCorridor (const WimaCorridor *corridor); - void setVisualItems (const QmlObjectListModel *visualItems); - + void push(const WimaPlanData &planData); + const WimaPlanData &pull() const; + void setDataValid(bool valid); private: - const WimaArea *_joinedArea; - const WimaMeasurementArea *_opArea; - const WimaServiceArea *_serArea; - const WimaCorridor *_corridor; - const QmlObjectListModel *_visualItems; + + + WimaPlanData _planData; + bool _dataValid; }; diff --git a/src/Wima/WimaGOperationArea.SettingsGroup.json b/src/Wima/WimaMeasurementArea.SettingsGroup.json similarity index 65% rename from src/Wima/WimaGOperationArea.SettingsGroup.json rename to src/Wima/WimaMeasurementArea.SettingsGroup.json index ae04649a7..b1998a39a 100644 --- a/src/Wima/WimaGOperationArea.SettingsGroup.json +++ b/src/Wima/WimaMeasurementArea.SettingsGroup.json @@ -1,32 +1,34 @@ [ { "name": "BottomLayerAltitude", - "shortDescription": "Altitude of the bottom layer.", + "shortDescription": "The distance between the terrain and the first layer of the measurement path.", "type": "double", "units": "m", "min": 1, "decimalPlaces": 2, - "defaultValue": 10 + "defaultValue": 5 }, { "name": "NumberOfLayers", "shortDescription": "The number of layers.", "type": "uint32", + "units": "m", "min": 1, + "decimalPlaces": 0, "defaultValue": 1 }, { "name": "LayerDistance", - "shortDescription": "The distance between two adjacent layers.", + "shortDescription": "Specify the time between each photo", "type": "double", "units": "m", "min": 0, "decimalPlaces": 2, - "defaultValue": 2 + "defaultValue": 1 }, { "name": "BorderPolygonOffset", - "shortDescription": "The distance between the Operation Area and it's surounding Border Polygon.", + "shortDescription": "The distance between the measurement area and it's enclosing polygon", "type": "double", "units": "m", "min": 0, diff --git a/src/Wima/WimaMeasurementArea.cc b/src/Wima/WimaMeasurementArea.cc index eb40d4884..934bfab91 100644 --- a/src/Wima/WimaMeasurementArea.cc +++ b/src/Wima/WimaMeasurementArea.cc @@ -1,12 +1,12 @@ #include "WimaMeasurementArea.h" -const char* WimaMeasurementArea::settingsGroup = "OperationArea"; +const char* WimaMeasurementArea::settingsGroup = "MeasurementArea"; const char* WimaMeasurementArea::bottomLayerAltitudeName = "BottomLayerAltitude"; const char* WimaMeasurementArea::numberOfLayersName = "NumberOfLayers"; const char* WimaMeasurementArea::layerDistanceName = "LayerDistance"; const char* WimaMeasurementArea::borderPolygonOffsetName = "BorderPolygonOffset"; -const char* WimaMeasurementArea::WimaMeasurementAreaName = "Operation Area"; +const char* WimaMeasurementArea::WimaMeasurementAreaName = "Measurement Area"; WimaMeasurementArea::WimaMeasurementArea(QObject *parent) @@ -21,6 +21,18 @@ WimaMeasurementArea::WimaMeasurementArea(const WimaMeasurementArea &other, QObje init(); } +/*! + * \overload operator=() + * + * Calls the inherited operator WimaArea::operator=(). + */ +WimaMeasurementArea &WimaMeasurementArea::operator=(const WimaMeasurementArea &other) +{ + WimaArea::operator=(other); + + return *this; +} + void WimaMeasurementArea::saveToJson(QJsonObject &json) { this->WimaArea::saveToJson(json); @@ -70,21 +82,40 @@ bool WimaMeasurementArea::loadFromJson(const QJsonObject &json, QString& errorSt } } -void WimaMeasurementArea::update(const WimaMeasurementArea &area) +void WimaMeasurementArea::setBottomLayerAltitude(double altitude) +{ + if ( !qFuzzyCompare(_bottomLayerAltitude.rawValue().toDouble(), altitude) ) { + _bottomLayerAltitude.setRawValue(altitude); + + emit bottomLayerAltitudeChanged(); + } +} + +void WimaMeasurementArea::setNumberOfLayers(double numLayers) { - this->WimaArea::update(area); + if ( !qFuzzyCompare(_numberOfLayers.rawValue().toDouble(), numLayers) ) { + _numberOfLayers.setRawValue(numLayers); - this->setBottomLayerAltitude(area.bottomLayerAltitude()); - this->setNumberOfLayers(area.numberOfLayers()); - this->setLayerDistance(area.layerDistance()); - this->setBorderPolygonOffset(area.borderPolygonOffset()); + emit numberOfLayersChanged(); + } +} + +void WimaMeasurementArea::setLayerDistance(double layerDistance) +{ + if ( !qFuzzyCompare(_layerDistance.rawValue().toDouble(), layerDistance) ) { + _layerDistance.setRawValue(layerDistance); - recalcBorderPolygon(); + emit layerDistanceChanged(); + } } -void WimaMeasurementArea::setBottomLayerAltitude(double altitude) +void WimaMeasurementArea::setBorderPolygonOffset(double offset) { + if ( !qFuzzyCompare(_borderPolygonOffset.rawValue().toDouble(), offset) ) { + _borderPolygonOffset.setRawValue(offset); + emit borderPolygonOffsetChanged(); + } } void print(const WimaMeasurementArea &area) @@ -111,11 +142,8 @@ void print(const WimaMeasurementArea &area, QString outputStr) void WimaMeasurementArea::recalcBorderPolygon() { - //qWarning("WimaMeasurementArea::recalcBorderPolygon() %f", _borderPolygonOffset.rawValue().toDouble()); - QGCMapPolygon polyCopy = this->toQGCPolygon(*this); - polyCopy.offset(_borderPolygonOffset.rawValue().toDouble()); - _borderPolygon.setPath(polyCopy.path()); - polyCopy.deleteLater(); + _borderPolygon = this->toQGCPolygon(*this); + _borderPolygon.offset(_borderPolygonOffset.rawValue().toDouble()); emit borderPolygonChanged(); } @@ -135,4 +163,11 @@ void WimaMeasurementArea::init() connect(&_borderPolygonOffset, &SettingsFact::rawValueChanged, this, &WimaMeasurementArea::recalcBorderPolygon); } +/*! + * \class WimaMeasurementArea + * \brief Class defining the area inside which the actual drone measurements are performed. + * + * \sa WimaArea, WimaController, WimaPlaner + */ + diff --git a/src/Wima/WimaMeasurementArea.h b/src/Wima/WimaMeasurementArea.h index ce1261bc2..02ad10af6 100644 --- a/src/Wima/WimaMeasurementArea.h +++ b/src/Wima/WimaMeasurementArea.h @@ -1,11 +1,13 @@ #pragma once +#include "QScopedPointer" #include + #include "WimaArea.h" +#include "WimaMeasurementAreaData.h" + #include "SettingsFact.h" -#include "WimaTrackerPolyline.h" -#include "QScopedPointer" class WimaMeasurementArea : public WimaArea { @@ -13,12 +15,13 @@ class WimaMeasurementArea : public WimaArea public: WimaMeasurementArea(QObject* parent = nullptr); WimaMeasurementArea(const WimaMeasurementArea &other, QObject *parent = nullptr); + WimaMeasurementArea &operator=(const WimaMeasurementArea &other); - Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitudeFact CONSTANT) - Q_PROPERTY(Fact* numberOfLayers READ numberOfLayersFact CONSTANT) - Q_PROPERTY(Fact* layerDistance READ layerDistanceFact CONSTANT) - Q_PROPERTY(Fact* borderPolygonOffset READ borderPolygonOffsetFact CONSTANT) - Q_PROPERTY(QGCMapPolygon borderPolygon READ borderPolygon NOTIFY borderPolygonChanged) + Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitudeFact CONSTANT) + Q_PROPERTY(Fact* numberOfLayers READ numberOfLayersFact CONSTANT) + Q_PROPERTY(Fact* layerDistance READ layerDistanceFact CONSTANT) + Q_PROPERTY(Fact* borderPolygonOffset READ borderPolygonOffsetFact CONSTANT) + Q_PROPERTY(QGCMapPolygon* borderPolygon READ borderPolygon NOTIFY borderPolygonChanged) // Overrides from WimaPolygon QString mapVisualQML (void) const { return "WimaMeasurementAreaMapVisual.qml";} @@ -33,7 +36,7 @@ public: int numberOfLayers (void) const { return _numberOfLayers.rawValue().toInt();} double layerDistance (void) const { return _layerDistance.rawValue().toDouble();} double borderPolygonOffset (void) const { return _borderPolygonOffset.rawValue().toDouble();} - QGCMapPolygon borderPolygon (void) const { return _borderPolygon;} + QGCMapPolygon* borderPolygon (void) { return &_borderPolygon;} // Member Methodes void saveToJson(QJsonObject& json); @@ -58,10 +61,9 @@ signals: void polylineChanged (void); void vehicleCorridorChanged (WimaVCorridor* corridor); void borderPolygonChanged (void); + void borderPolygonOffsetChanged (void); public slots: - /// Updates this with data from area - void update(const WimaMeasurementArea &area); void setBottomLayerAltitude (double altitude); void setNumberOfLayers (double numLayers); void setLayerDistance (double layerDistance); diff --git a/src/Wima/WimaMeasurementAreaData.cc b/src/Wima/WimaMeasurementAreaData.cc new file mode 100644 index 000000000..f40c2f2ea --- /dev/null +++ b/src/Wima/WimaMeasurementAreaData.cc @@ -0,0 +1,46 @@ +#include "WimaMeasurementAreaData.h" + +const char *WimaMeasurementAreaData::typeString = "WimaMeasurementAreaData"; + +WimaMeasurementAreaData::WimaMeasurementAreaData(QObject *parent) + : WimaAreaData(parent) +{ + +} + +WimaMeasurementAreaData::WimaMeasurementAreaData(const WimaMeasurementAreaData &other, QObject *parent) + : WimaAreaData (parent) +{ + *this = other; +} + +WimaMeasurementAreaData::WimaMeasurementAreaData(const WimaMeasurementArea &other, QObject *parent) + : WimaAreaData (parent) +{ + *this = other; +} + +/*! + * \overload operator=(); + * + * Assigns \a other to the invoking object. + */ +WimaMeasurementAreaData &WimaMeasurementAreaData::operator=(const WimaMeasurementAreaData &other) +{ + WimaAreaData::operator=(other); + + return *this; +} + +/*! + * \overload operator=(); + * + * Assigns \a other to the invoking object. + */ +WimaMeasurementAreaData &WimaMeasurementAreaData::operator=(const WimaMeasurementArea &other) +{ + WimaAreaData::operator=(other); + + return *this; +} + diff --git a/src/Wima/WimaMeasurementAreaData.h b/src/Wima/WimaMeasurementAreaData.h index 23e9d1f76..9b7a1e517 100644 --- a/src/Wima/WimaMeasurementAreaData.h +++ b/src/Wima/WimaMeasurementAreaData.h @@ -1,31 +1,31 @@ #pragma once #include +#include "QGeoCoordinate" + #include "WimaAreaData.h" -#include "QGeoCoordinate" +#include "WimaMeasurementArea.h" + + class WimaMeasurementAreaData : public WimaAreaData { Q_OBJECT public: - explicit WimaMeasurementAreaData(QObject *parent = nullptr); - explicit WimaMeasurementAreaData(WimaMeasurementAreaData &other, QObject *parent = nullptr); - + WimaMeasurementAreaData(QObject *parent = nullptr); + WimaMeasurementAreaData(const WimaMeasurementAreaData &other, QObject *parent = nullptr); + WimaMeasurementAreaData(const WimaMeasurementArea &other, QObject *parent = nullptr); + WimaMeasurementAreaData& operator=(const WimaMeasurementAreaData &other); + WimaMeasurementAreaData& operator=(const WimaMeasurementArea &other); - const QGeoCoordinate &takeOffPosition() const; - const QGeoCoordinate &landOffPosition() const; + static const char* typeString; signals: - void takeOffPositionChanged(const QGeoCoordinate& other); - void landOffPositionChanged(const QGeoCoordinate& other); public slots: - void setTakeOffPosition(const QGeoCoordinate& newCoordinate); - void setLandOffPosition(const QGeoCoordinate& newCoordinate); private: - // see WimaServieArea.h for explanation + // see WimaMeasurementArea.h for explanation }; - diff --git a/src/Wima/WimaMeasurementAreaDataareadata.cc b/src/Wima/WimaMeasurementAreaDataareadata.cc deleted file mode 100644 index eda8c0b6b..000000000 --- a/src/Wima/WimaMeasurementAreaDataareadata.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "WimaMeasurementAreaData.h" - -WimaMeasurementAreaData::WimaMeasurementAreaData(QObject *parent) : QObject(parent) -{ - -} diff --git a/src/Wima/WimaPlanData.cc b/src/Wima/WimaPlanData.cc new file mode 100644 index 000000000..3aba84c11 --- /dev/null +++ b/src/Wima/WimaPlanData.cc @@ -0,0 +1,122 @@ +#include "WimaPlanData.h" + +WimaPlanData::WimaPlanData(QObject *parent) + : QObject (parent) +{ + +} + +WimaPlanData::WimaPlanData(const WimaPlanData &other, QObject *parent) + : QObject (parent) +{ + *this = other; +} + +/*! + * \fn WimaPlanData &WimaPlanData::operator=(const WimaPlanData &other) + * + * Copies the data area list of \a other to the calling \c WimaPlanData object. + * Returns a reference to the calling \c WimaPlanData object. + */ +WimaPlanData &WimaPlanData::operator=(const WimaPlanData &other) +{ + QList areaList = other.areaList(); + _areaList.clear(); + for (const WimaAreaData* areaData: areaList) { + if (areaData->type() == WimaAreaData::typeString) { + this->append(*areaData); + }else if (areaData->type() == WimaServiceAreaData::typeString) { + this->append(*qobject_cast(areaData)); + }else if (areaData->type() == WimaMeasurementAreaData::typeString) { + this->append(*qobject_cast(areaData)); + }else if (areaData->type() == WimaCorridorData::typeString) { + this->append(*qobject_cast(areaData)); + } + } + + return *this; +} + + +/*! + * \fn void WimaPlanData::append(const WimaAreaData &areaData) + * + * Adds a WimaAreaData item. + */ +void WimaPlanData::append(const WimaAreaData &areaData) +{ + _joinedArea = areaData; + + if( !_areaList.contains(&_joinedArea) ) { + _areaList.append(&_joinedArea); + } +} + +/*! + * \fn void WimaPlanData::append(const WimaServiceAreaData &areaData) + * + * Adds a WimaServiceAreaData item. + */ +void WimaPlanData::append(const WimaServiceAreaData &areaData) +{ + _serviceArea = areaData; + + if( !_areaList.contains(&_serviceArea) ) { + _areaList.append(&_serviceArea); + } +} + +/*! + * \fn void WimaPlanData::append(const WimaServiceAreaData &areaData) + * + * Adds a WimaCorridorData item. + */ +void WimaPlanData::append(const WimaCorridorData &areaData) +{ + _corridor = areaData; + + if( !_areaList.contains(&_corridor) ) { + _areaList.append(&_corridor); + } +} + +/*! + * \fn void WimaPlanData::append(const WimaServiceAreaData &areaData) + * + * Adds a WimaMeasurementAreaData item. + */ +void WimaPlanData::append(const WimaMeasurementAreaData &areaData) +{ + _measurementArea = areaData; + + if( !_areaList.contains(&_measurementArea) ) { + _areaList.append(&_measurementArea); + } +} + +/*! + * \fn void WimaPlanData::append(const WimaServiceAreaData &areaData) + * + * Clears all stored objects + */ +void WimaPlanData::clear() +{ + _areaList.clear(); +} + +QList WimaPlanData::areaList() const +{ + return _areaList; +} + +/*! + * \class WimaPlanData + * \brief Class storing data generated by the \c WimaPlaner class. + * + * This class is designed to store data generated by the \c WimaPlaner class and + * meant for data exchange between the \c WimaController and the \c WimaPlanner. + * It stores a QList of \c WimaAreaData objects, called area data list, containing the data of serveral \c WimaAreas + * generated by the \c WimaPlaner. + * + * \sa QList + */ diff --git a/src/Wima/WimaPlanData.h b/src/Wima/WimaPlanData.h new file mode 100644 index 000000000..5fb0a3335 --- /dev/null +++ b/src/Wima/WimaPlanData.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "WimaAreaData.h" +#include "WimaServiceAreaData.h" +#include "WimaCorridorData.h" +#include "WimaMeasurementAreaData.h" + +class WimaPlanData : QObject +{ + Q_OBJECT +public: + WimaPlanData(QObject *parent = nullptr); + WimaPlanData(const WimaPlanData &other, QObject *parent = nullptr); + WimaPlanData& operator=(const WimaPlanData &other); + + // Member Methodes + void append(const WimaAreaData &areaData); + void append(const WimaServiceAreaData &areaData); + void append(const WimaCorridorData &areaData); + void append(const WimaMeasurementAreaData &areaData); + void clear(); + + QList areaList() const; + + + +signals: + void areaListChanged(); + +private: + WimaAreaData _joinedArea; + WimaServiceAreaData _serviceArea; + WimaCorridorData _corridor; + WimaMeasurementAreaData _measurementArea; + QList _areaList; +}; diff --git a/src/Wima/WimaPlaner.cc b/src/Wima/WimaPlaner.cc index d37962636..e78c5a3bc 100644 --- a/src/Wima/WimaPlaner.cc +++ b/src/Wima/WimaPlaner.cc @@ -6,12 +6,12 @@ const char* WimaPlaner::missionItemsName = "MissionItems"; WimaPlaner::WimaPlaner(QObject *parent) : QObject (parent) - , _readyForSaveSend (false) + , _missionReady (false) , _currentAreaIndex (-1) , _container (nullptr) , _joinedArea (this) - , _opArea (this) - , _serArea (this) + , _measurementArea (this) + , _serviceArea (this) , _corridor (this) { connect(this, &WimaPlaner::currentPolygonIndexChanged, this, &WimaPlaner::recalcPolygonInteractivity); @@ -67,18 +67,18 @@ void WimaPlaner::setCurrentPolygonIndex(int index) void WimaPlaner::setDataContainer(WimaDataContainer *container) { - if (_container == nullptr && container != nullptr) { + if (container != nullptr) { + if (_container != nullptr) { + disconnect(this, &WimaPlaner::missionReadyChanged, _container, &WimaDataContainer::setDataValid); + } + _container = container; + connect(this, &WimaPlaner::missionReadyChanged, _container, &WimaDataContainer::setDataValid); emit dataContainerChanged(); } } -void WimaPlaner::startWimaPlaner(bool flyView) -{ - -} - void WimaPlaner::removeArea(int index) { if(index >= 0 && index < _visualItems.count()){ @@ -110,10 +110,10 @@ void WimaPlaner::removeArea(int index) } -bool WimaPlaner::addGOperationArea() +bool WimaPlaner::addMeasurementArea() { - if (!_visualItems.contains(&_opArea)) { - _visualItems.append(&_opArea); + if (!_visualItems.contains(&_measurementArea)) { + _visualItems.append(&_measurementArea); int newIndex = _visualItems.count()-1; setCurrentPolygonIndex(newIndex); @@ -127,8 +127,8 @@ bool WimaPlaner::addGOperationArea() bool WimaPlaner::addServiceArea() { - if (!_visualItems.contains(&_serArea)) { - _visualItems.append(&_serArea); + if (!_visualItems.contains(&_serviceArea)) { + _visualItems.append(&_serviceArea); int newIndex = _visualItems.count()-1; setCurrentPolygonIndex(newIndex); @@ -140,7 +140,7 @@ bool WimaPlaner::addServiceArea() } } -bool WimaPlaner::addVehicleCorridor() +bool WimaPlaner::addCorridor() { if (!_visualItems.contains(&_corridor)) { _visualItems.append(&_corridor); @@ -194,12 +194,12 @@ void WimaPlaner::resumeMission() bool WimaPlaner::updateMission() { - - setReadyForSaveSend(false); + QString errorString; + setMissionReady(false); #define debug 0 - if ( !recalcJoinedArea()) { - qgcApp()->showMessage(tr("Not able to join areas. Areas must be overlapping")); + if ( !recalcJoinedArea(errorString)) { + qgcApp()->showMessage(tr(errorString.toLocal8Bit().data())); return false; } @@ -218,43 +218,45 @@ bool WimaPlaner::updateMission() } // set altitudes, temporary measure to solve bugs - QGeoCoordinate center = _serArea.center(); + QGeoCoordinate center = _serviceArea.center(); center.setAltitude(0); - _serArea.setCenter(center); - center = _opArea.center(); + _serviceArea.setCenter(center); + center = _measurementArea.center(); center.setAltitude(0); - _opArea.setCenter(center); + _measurementArea.setCenter(center); center = _corridor.center(); center.setAltitude(0); _corridor.setCenter(center); // set HomePos. to serArea center - settingsItem->setCoordinate(_serArea.center()); + settingsItem->setCoordinate(_serviceArea.center()); // create take off position item - int sequenceNumber = _missionController->insertSimpleMissionItem(_serArea.center(), missionItems->count()); + int sequenceNumber = _missionController->insertSimpleMissionItem(_serviceArea.center(), missionItems->count()); _missionController->setCurrentPlanViewIndex(sequenceNumber, true); // create survey item, will be extened with more()-> mission types in the future - _missionController->insertComplexMissionItem(_missionController->surveyComplexItemName(), _opArea.center(), missionItems->count()); + _missionController->insertComplexMissionItem(_missionController->surveyComplexItemName(), _measurementArea.center(), missionItems->count()); SurveyComplexItem* survey = qobject_cast(missionItems->get(missionItems->count()-1)); if (survey == nullptr){ qWarning("WimaPlaner::updateMission(): survey == nullptr"); return false; } else { survey->surveyAreaPolygon()->clear(); - survey->surveyAreaPolygon()->appendVertices(_opArea.coordinateList()); + survey->surveyAreaPolygon()->appendVertices(_measurementArea.coordinateList()); //survey-> } // calculate path from take off to opArea - QGeoCoordinate start = _serArea.center(); + QGeoCoordinate start = _serviceArea.center(); QGeoCoordinate end = survey->visualTransectPoints().first().value(); QList path; - if ( !WimaArea::dijkstraPath(start, end, _joinedArea, path)) { - qgcApp()->showMessage(tr("Not able to calculate the path from takeoff position to measurement area.")); + if ( !WimaArea::dijkstraPath(start, end, _joinedArea, path, errorString)) { + qgcApp()->showMessage(QString( QString(tr("Not able to calculate the path from takeoff position to measurement area.")) + + errorString + ).toLocal8Bit().data()); return false; } for (int i = 1; i < path.count()-1; i++) { @@ -264,10 +266,12 @@ bool WimaPlaner::updateMission() // calculate return path start = survey->visualTransectPoints().last().value(); - end = _serArea.center(); + end = _serviceArea.center(); path.clear(); - if ( ! WimaArea::dijkstraPath(start, end, _joinedArea, path)) { - qgcApp()->showMessage(tr("Not able to calculate the path from measurement area to landing position.")); + if ( ! WimaArea::dijkstraPath(start, end, _joinedArea, path, errorString)) { + qgcApp()->showMessage(QString( QString(tr("Not able to calculate the path from measurement area to landing position.")) + + errorString + ).toLocal8Bit().data()); return false; } for (int i = 1; i < path.count()-1; i++) { @@ -276,7 +280,7 @@ bool WimaPlaner::updateMission() } // create land position item - sequenceNumber = _missionController->insertSimpleMissionItem(_serArea.center(), missionItems->count()); + sequenceNumber = _missionController->insertSimpleMissionItem(_serviceArea.center(), missionItems->count()); _missionController->setCurrentPlanViewIndex(sequenceNumber, true); SimpleMissionItem* landItem = qobject_cast(missionItems->get(missionItems->count()-1)); if (landItem == nullptr){ @@ -290,8 +294,8 @@ bool WimaPlaner::updateMission() } } - pushToContainer(); - setReadyForSaveSend(true); + pushToContainer(); // exchange plan data with the WimaController via the _container + setMissionReady(true); return true; } @@ -384,9 +388,9 @@ bool WimaPlaner::loadFromFile(const QString &filename) if (jsonArea.contains(WimaArea::areaTypeName) && jsonArea[WimaArea::areaTypeName].isString()) { if ( jsonArea[WimaArea::areaTypeName] == WimaMeasurementArea::WimaMeasurementAreaName) { - print(_opArea); - bool success = _opArea.loadFromJson(jsonArea, errorString); - print(_opArea); + print(_measurementArea); + bool success = _measurementArea.loadFromJson(jsonArea, errorString); + print(_measurementArea); if ( !success ) { qgcApp()->showMessage(errorMessage.arg(errorString)); @@ -394,10 +398,10 @@ bool WimaPlaner::loadFromFile(const QString &filename) } validAreaCounter++; - _visualItems.append(&_opArea); + _visualItems.append(&_measurementArea); emit visualItemsChanged(); } else if ( jsonArea[WimaArea::areaTypeName] == WimaServiceArea::wimaServiceAreaName) { - bool success = _serArea.loadFromJson(jsonArea, errorString); + bool success = _serviceArea.loadFromJson(jsonArea, errorString); if ( !success ) { qgcApp()->showMessage(errorMessage.arg(errorString)); @@ -405,7 +409,7 @@ bool WimaPlaner::loadFromFile(const QString &filename) } validAreaCounter++; - _visualItems.append(&_serArea); + _visualItems.append(&_serviceArea); emit visualItemsChanged(); } else if ( jsonArea[WimaArea::areaTypeName] == WimaCorridor::WimaCorridorName) { bool success = _corridor.loadFromJson(jsonArea, errorString); @@ -432,7 +436,7 @@ bool WimaPlaner::loadFromFile(const QString &filename) _currentFile.sprintf("%s/%s.%s", fileInfo.path().toLocal8Bit().data(), fileInfo.completeBaseName().toLocal8Bit().data(), wimaFileExtension); emit currentFileChanged(); - recalcJoinedArea(); + //recalcJoinedArea(); // MissionItems // extrac MissionItems part @@ -493,14 +497,32 @@ void WimaPlaner::recalcPolygonInteractivity(int index) } } -bool WimaPlaner::recalcJoinedArea() +bool WimaPlaner::recalcJoinedArea(QString &errorString) { + // check if area paths form simple polygons + if ( WimaArea::isSelfIntersecting(_serviceArea) ) { + errorString.append(tr("Service area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n")); + return false; + } + + if ( WimaArea::isSelfIntersecting(_corridor) ) { + errorString.append(tr("Corridor is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n")); + return false; + } + + if ( WimaArea::isSelfIntersecting(_measurementArea) ) { + errorString.append(tr("Measurement area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n")); + return false; + } + // join service area, op area and corridor - _joinedArea = _serArea; + _joinedArea = _serviceArea; _joinedArea.join(_corridor); - - if ( !_joinedArea.join(_opArea) ) + if ( !_joinedArea.join(_measurementArea) ) { + errorString.append(tr("Not able to join areas. Service area and measurement are" + " must have a overlapping section, or be connected through a corridor.")); return false; // this happens if all areas are pairwise disjoint + } else { return true; } @@ -508,16 +530,18 @@ bool WimaPlaner::recalcJoinedArea() } +/*! + * \fn void WimaPlaner::pushToContainer() + * Pushes the \c WimaPlanData object generated by \c toPlanData() to the \c WimaDataContainer. + * Should be called only after \c updateMission() was successful. + * + * \sa WimaDataContainer, WimaPlanData + */ void WimaPlaner::pushToContainer() { - // Sets the pointers (inside _container) to the areas (of this). - // Should be called only (once) after a _container has been assigned. if (_container != nullptr) { - _container->setOpArea(&_opArea); - _container->setSerArea(&_serArea); - _container->setCorridor(&_corridor); - _container->setJoinedArea(&_joinedArea); - _container->setVisualItems(&_visualItems); + WimaPlanData planData = toPlanData(); + _container->push(planData); } else { qWarning("WimaPlaner::uploadToContainer(): no container assigned."); } @@ -540,6 +564,40 @@ void WimaPlaner::setInteractive() recalcPolygonInteractivity(_currentAreaIndex); } +/*! + * \fn WimaPlanData WimaPlaner::toPlanData() + * + * Returns a \c WimaPlanData object containing information about the current mission. + * The \c WimaPlanData object holds only the data which is relevant for the \c WimaController class. + * Should only be called if updateMission() was successful. + * + * \sa WimaController, WimaPlanData + */ +WimaPlanData WimaPlaner::toPlanData() +{ + WimaPlanData planData; + /* Note: constructor call: WimaMeasuretr(mentAreaData::WimaMeasurementAreaData(const WimaMeasurementArea &other, QObject *parent) + * converts WimaMeasurementArea to WimaMeasurementAreaData, this makes: planData.appendWimaAreaData(_measurementArea); possible. + * Same for the following statements + */ + planData.append(WimaMeasurementAreaData(_measurementArea)); + planData.append(WimaServiceAreaData(_serviceArea)); + planData.append(WimaCorridorData(_corridor)); + planData.append(WimaAreaData(_joinedArea)); + + return WimaPlanData(planData); +} + +void WimaPlaner::setMissionReady(bool ready) +{ + if(_missionReady != ready) + { + _missionReady = ready; + + emit missionReadyChanged(_missionReady); + } +} + QJsonDocument WimaPlaner::saveToJson(FileType fileType) { /// This function save all areas (of WimaPlaner) and all mission items (of MissionController) to a QJsonDocument @@ -597,13 +655,5 @@ QJsonDocument WimaPlaner::saveToJson(FileType fileType) return QJsonDocument(json); } -void WimaPlaner::setReadyForSaveSend(bool ready) -{ - if (ready != _readyForSaveSend) { - _readyForSaveSend = ready; - emit readyForSaveSendChanged(ready); - } -} - diff --git a/src/Wima/WimaPlaner.h b/src/Wima/WimaPlaner.h index c2f0f9521..4b3fdbe6d 100644 --- a/src/Wima/WimaPlaner.h +++ b/src/Wima/WimaPlaner.h @@ -9,6 +9,11 @@ #include "WimaServiceArea.h" #include "WimaCorridor.h" #include "WimaDataContainer.h" +#include "WimaPlanData.h" +#include "WimaAreaData.h" +#include "WimaServiceAreaData.h" +#include "WimaMeasurementAreaData.h" +#include "WimaCorridorData.h" #include "PlanMasterController.h" #include "MissionController.h" @@ -41,13 +46,13 @@ public: Q_PROPERTY(QStringList saveNameFilters READ saveNameFilters CONSTANT) Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT) Q_PROPERTY(QGeoCoordinate joinedAreaCenter READ joinedAreaCenter CONSTANT) - Q_PROPERTY(WimaDataContainer* dataContainer WRITE setDataContainer NOTIFY dataContainerChanged) - Q_PROPERTY(bool readyForSaveSend READ readyForSaveSend NOTIFY readyForSaveSendChanged) + Q_PROPERTY(WimaDataContainer* dataContainer READ dataContainer WRITE setDataContainer NOTIFY dataContainerChanged) + Q_PROPERTY(bool missionReady READ missionReady NOTIFY missionReadyChanged) // Property accessors - PlanMasterController* masterController (void) const { return _masterController; } - MissionController* missionController (void) const { return _missionController; } + PlanMasterController* masterController (void) { return _masterController; } + MissionController* missionController (void) { return _missionController; } QmlObjectListModel* visualItems (void) ; int currentPolygonIndex (void) const { return _currentAreaIndex; } QString currentFile (void) const { return _currentFile; } @@ -55,9 +60,8 @@ public: QStringList saveNameFilters (void) const; QString fileExtension (void) const { return wimaFileExtension; } QGeoCoordinate joinedAreaCenter (void) const; - bool readyForSaveSend (void) const { return _readyForSaveSend; } - - + bool missionReady (void) const { return _missionReady; } + WimaDataContainer* dataContainer (void) { return _container;} // Property setters void setMasterController (PlanMasterController* masterController); @@ -67,13 +71,12 @@ public: void setDataContainer (WimaDataContainer* container); // Member Methodes - Q_INVOKABLE void startWimaPlaner(bool flyView); - Q_INVOKABLE bool addGOperationArea(); + Q_INVOKABLE bool addMeasurementArea(); /// Removes an area from _visualItems /// @param index Index of the area to be removed Q_INVOKABLE void removeArea(int index); Q_INVOKABLE bool addServiceArea(); - Q_INVOKABLE bool addVehicleCorridor(); + Q_INVOKABLE bool addCorridor(); /// Remove all areas from WimaPlaner and all mission items from MissionController Q_INVOKABLE void removeAll(); @@ -92,16 +95,13 @@ public: Q_INVOKABLE void resetAllInteractive(void); Q_INVOKABLE void setInteractive(void); + QJsonDocument saveToJson(FileType fileType); // static Members static const char* wimaFileExtension; static const char* areaItemsName; static const char* missionItemsName; - // Member Methodes - QJsonDocument saveToJson(FileType fileType); - void setReadyForSaveSend(bool ready); - signals: void masterControllerChanged (void); void missionControllerChanged (void); @@ -109,23 +109,28 @@ signals: void currentPolygonIndexChanged (int index); void currentFileChanged (); void dataContainerChanged (); - void readyForSaveSendChanged (bool ready); + void missionReadyChanged (bool ready); private slots: void recalcPolygonInteractivity (int index); - bool recalcJoinedArea (); + bool recalcJoinedArea (QString &errorString); void pushToContainer (); private: - bool _readyForSaveSend; // basically true if updateMission() was sucessful + // Member Functions + WimaPlanData toPlanData(); + void setMissionReady(bool ready); + + // Member Variables + bool _missionReady; // basically true if updateMission() was sucessful PlanMasterController *_masterController; MissionController *_missionController; int _currentAreaIndex; QString _currentFile; // file for saveing WimaDataContainer *_container; // container for data exchange with WimaController QmlObjectListModel _visualItems; // contains all visible areas - WimaArea _joinedArea; // joined area fromed by opArea, serArea, _corridor - WimaMeasurementArea _opArea; // measurement area - WimaServiceArea _serArea; // area for supplying - WimaCorridor _corridor; // corridor connecting opArea and serArea + WimaArea _joinedArea; // joined area fromed by _measurementArea, _serviceArea, _corridor + WimaMeasurementArea _measurementArea; // measurement area + WimaServiceArea _serviceArea; // area for supplying + WimaCorridor _corridor; // corridor connecting _measurementArea and _serviceArea }; diff --git a/src/Wima/WimaServiceArea.cc b/src/Wima/WimaServiceArea.cc index daf6f1b61..7e19299c4 100644 --- a/src/Wima/WimaServiceArea.cc +++ b/src/Wima/WimaServiceArea.cc @@ -16,6 +16,18 @@ WimaServiceArea::WimaServiceArea(const WimaServiceArea &other, QObject *parent) init(); } +/*! + * \overload operator=() + * + * Calls the inherited operator WimaArea::operator=(). + */ +WimaServiceArea &WimaServiceArea::operator=(const WimaServiceArea &other) +{ + WimaArea::operator=(other); + + return *this; +} + void WimaServiceArea::setTakeOffPosition(const QGeoCoordinate &coordinate) { if(_takeOffPosition != coordinate){ @@ -50,13 +62,6 @@ bool WimaServiceArea::loadFromJson(const QJsonObject &json, QString &errorString } } -void WimaServiceArea::update(const WimaServiceArea &area) -{ - this->WimaArea::update(area); - this->setTakeOffPosition(area.takeOffPosition()); - this->setLandPosition(area.landPosition()); -} - void print(const WimaServiceArea &area) { QString message; diff --git a/src/Wima/WimaServiceArea.h b/src/Wima/WimaServiceArea.h index e53445d9a..a0dbed557 100644 --- a/src/Wima/WimaServiceArea.h +++ b/src/Wima/WimaServiceArea.h @@ -10,6 +10,7 @@ class WimaServiceArea : public WimaArea public: WimaServiceArea(QObject* parent = nullptr); WimaServiceArea(const WimaServiceArea& other, QObject* parent); + WimaServiceArea& operator=(const WimaServiceArea &other); Q_PROPERTY(const QGeoCoordinate& takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged) Q_PROPERTY(const QGeoCoordinate& landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged) @@ -42,8 +43,6 @@ signals: public slots: void setTakeOffPosition (const QGeoCoordinate& coordinate); void setLandPosition (const QGeoCoordinate& coordinate); - /// Updates this with data from area - void update(const WimaServiceArea &area); private: // Member Methodes diff --git a/src/Wima/WimaServiceAreaData.cc b/src/Wima/WimaServiceAreaData.cc index 39730971c..a07056be3 100644 --- a/src/Wima/WimaServiceAreaData.cc +++ b/src/Wima/WimaServiceAreaData.cc @@ -1,5 +1,7 @@ #include "WimaServiceAreaData.h" +const char *WimaServiceAreaData::typeString = "WimaServiceAreaData"; + WimaServiceAreaData::WimaServiceAreaData(QObject *parent) : WimaAreaData(parent) @@ -7,12 +9,34 @@ WimaServiceAreaData::WimaServiceAreaData(QObject *parent) } -WimaServiceAreaData::WimaServiceAreaData(WimaServiceAreaData &other, QObject *parent) - : WimaAreaData (other, parent) - , _takeOffPosition(other.takeOffPosition()) - , _landPosition(other.landOffPosition()) +WimaServiceAreaData::WimaServiceAreaData(const WimaServiceAreaData &other, QObject *parent) + : WimaAreaData (parent) +{ + *this = other; +} + +WimaServiceAreaData::WimaServiceAreaData(const WimaServiceArea &other, QObject *parent) + : WimaAreaData (parent) +{ + *this = other; +} + +WimaServiceAreaData &WimaServiceAreaData::operator=(const WimaServiceAreaData &otherData) +{ + WimaAreaData::operator=(otherData); + setLandPosition(otherData.landPosition()); + setTakeOffPosition(otherData.takeOffPosition()); + + return *this; +} + +WimaServiceAreaData &WimaServiceAreaData::operator=(const WimaServiceArea &otherArea) { + WimaAreaData::operator=(otherArea); + setLandPosition(otherArea.landPosition()); + setTakeOffPosition(otherArea.takeOffPosition()); + return *this; } /*! @@ -30,7 +54,7 @@ const QGeoCoordinate &WimaServiceAreaData::takeOffPosition() const * Returns a constant reference to the landOffPosition. * */ -const QGeoCoordinate &WimaServiceAreaData::landOffPosition() const +const QGeoCoordinate &WimaServiceAreaData::landPosition() const { return _landPosition; } @@ -56,12 +80,12 @@ void WimaServiceAreaData::setTakeOffPosition(const QGeoCoordinate &newCoordinate * if newCoordinate differs from the member value. * */ -void WimaServiceAreaData::setLandOffPosition(const QGeoCoordinate &newCoordinate) +void WimaServiceAreaData::setLandPosition(const QGeoCoordinate &newCoordinate) { if (_landPosition != newCoordinate) { _landPosition = newCoordinate; - emit landOffPositionChanged(_landPosition); + emit landPositionChanged(_landPosition); } } diff --git a/src/Wima/WimaServiceAreaData.h b/src/Wima/WimaServiceAreaData.h index 7154c49ab..ece5574cc 100644 --- a/src/Wima/WimaServiceAreaData.h +++ b/src/Wima/WimaServiceAreaData.h @@ -1,29 +1,36 @@ #pragma once #include +#include "QGeoCoordinate" #include "WimaAreaData.h" -#include "QGeoCoordinate" +#include "WimaServiceArea.h" + + class WimaServiceAreaData : public WimaAreaData { Q_OBJECT public: - explicit WimaServiceAreaData(QObject *parent = nullptr); - explicit WimaServiceAreaData(WimaServiceAreaData &other, QObject *parent = nullptr); - + WimaServiceAreaData(QObject *parent = nullptr); + WimaServiceAreaData(const WimaServiceAreaData &other, QObject *parent = nullptr); + WimaServiceAreaData(const WimaServiceArea &other, QObject *parent = nullptr); + WimaServiceAreaData& operator=(const WimaServiceAreaData &otherData); + WimaServiceAreaData& operator=(const WimaServiceArea &otherArea); const QGeoCoordinate &takeOffPosition() const; - const QGeoCoordinate &landOffPosition() const; + const QGeoCoordinate &landPosition() const; + + static const char* typeString; signals: void takeOffPositionChanged(const QGeoCoordinate& other); - void landOffPositionChanged(const QGeoCoordinate& other); + void landPositionChanged(const QGeoCoordinate& other); public slots: void setTakeOffPosition(const QGeoCoordinate& newCoordinate); - void setLandOffPosition(const QGeoCoordinate& newCoordinate); + void setLandPosition(const QGeoCoordinate& newCoordinate); private: // see WimaServieArea.h for explanation diff --git a/src/Wima/doc/wima.qdocconf b/src/Wima/doc/wima.qdocconf index 9e8341083..fd40910d9 100644 --- a/src/Wima/doc/wima.qdocconf +++ b/src/Wima/doc/wima.qdocconf @@ -1,15 +1,3 @@ -project = Wima - -headerdirs = ../ -sourcedirs = ../ - -sources.fileextensions = "*.cpp *.cc *.qdoc *.mm *.qml" -headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" -examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml" -examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng" - -outputdir = ./doc/QDoc/html -outputformats = HTML diff --git a/src/WimaView/WimaVCorridorMapVisual.qml b/src/WimaView/WimaCorridorMapVisual.qml similarity index 100% rename from src/WimaView/WimaVCorridorMapVisual.qml rename to src/WimaView/WimaCorridorMapVisual.qml diff --git a/src/WimaView/WimaItemEditor.qml b/src/WimaView/WimaItemEditor.qml index 5a48c9f00..598f1c049 100644 --- a/src/WimaView/WimaItemEditor.qml +++ b/src/WimaView/WimaItemEditor.qml @@ -20,7 +20,7 @@ Rectangle { radius: _radius property var map ///< Map control - property var wimaController + property var wimaPlaner property var masterController property bool readOnly ///< true: read only view, false: full editing view property var rootQgcView @@ -94,13 +94,18 @@ Rectangle { id: hamburgerMenu MenuItem { - text: qsTr("Add Operation Area") - onTriggered: wimaController.addGOperationArea() + text: qsTr("Add Measurement Area") + onTriggered: wimaPlaner.addMeasurementArea() } MenuItem { text: qsTr("Add Service Area") - onTriggered: wimaController.addServiceArea() + onTriggered: wimaPlaner.addServiceArea() + } + + MenuItem { + text: qsTr("Add Corridor") + onTriggered: wimaPlaner.addCorridor() } MenuItem { @@ -108,10 +113,10 @@ Rectangle { onTriggered: remove() } - MenuItem { + /*MenuItem { text: qsTr("Change Area Type ...") onTriggered: commandPicker.clicked() - } + }*/ } diff --git a/src/WimaView/WimaItemEditor_old.qml b/src/WimaView/WimaItemEditor_old.qml deleted file mode 100644 index 796dcf874..000000000 --- a/src/WimaView/WimaItemEditor_old.qml +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 2.3 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 -import QtQuick.Dialogs 1.2 -import QtQml 2.2 - -import QGroundControl 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Vehicle 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.FactControls 1.0 -import QGroundControl.Palette 1.0 - - -/// Fly Area Item edit control -Rectangle { - id: _root - height: editorLoader.visible ? (editorLoader.y + editorLoader.height + (_margin * 2)) : (descriptionLabel.y + descriptionLabel.height + _margin / 2) - color: _currentItem ? qgcPal.missionItemEditor : qgcPal.windowShade - radius: _radius - - property var map ///< Map control - property var flyArea - property var masterController - property var polygon ///< MissionItem associated with this editor - property bool readOnly ///< true: read only view, false: full editing view - property var rootQgcView - property int _index - - signal clicked - signal remove - - property var _masterController: masterController - property var _missionController: _masterController.missionController - property bool _currentItem: polygon.interactive - property color _outerTextColor: _currentItem ? qgcPal.primaryButtonText : qgcPal.text - property bool _noMissionItemsAdded: ListView.view.model.count === 1 - property real _sectionSpacer: ScreenTools.defaultFontPixelWidth / 2 // spacing between section headings - - readonly property real _editFieldWidth: Math.min(width - _margin * 2, ScreenTools.defaultFontPixelWidth * 12) - readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2 - readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2 - readonly property real _hamburgerSize: descriptionLabel.height * 0.75 - readonly property bool _waypointsOnlyMode: QGroundControl.corePlugin.options.missionWaypointsOnly - - QGCPalette { - id: qgcPal - colorGroupEnabled: enabled - } - - FocusScope { - id: currentItemScope - anchors.fill: parent - - MouseArea { - anchors.fill: parent - onClicked: { - currentItemScope.focus = true - _root.clicked() - } - } - } - - - QGCLabel { - id: label - anchors.verticalCenter: descriptionLabel.verticalCenter - anchors.leftMargin: _margin - anchors.left: parent.left - text: index - color: _outerTextColor - } - - QGCColoredImage { - id: hamburger - anchors.rightMargin: ScreenTools.defaultFontPixelWidth - anchors.right: parent.right - anchors.verticalCenter: descriptionLabel.verticalCenter - width: _hamburgerSize - height: _hamburgerSize - sourceSize.height: _hamburgerSize - source: "qrc:/qmlimages/Hamburger.svg" - visible: _currentItem - color: qgcPal.text - } - - QGCMouseArea { - fillItem: hamburger - visible: hamburger.visible - onClicked: { - currentItemScope.focus = true - hamburgerMenu.popup() - } - - Menu { - id: hamburgerMenu - - MenuItem { - text: qsTr("Insert Fly Area") - onTriggered: flyArea.appendFlyAreaPolygon() - } - - MenuItem { - text: qsTr("Delete") - onTriggered: remove() - } - MenuItem { - text: qsTr("Copy Fly Area") - //onTriggered: //To Do - } - - - } - } - - QGCLabel { - id: descriptionLabel - anchors.topMargin: _margin / 2 - anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2 - anchors.rightMargin: ScreenTools.defaultFontPixelWidth - anchors.left: label.right - anchors.top: parent.top - text: "Fly Area" - verticalAlignment: Text.AlignVCenter - color: _outerTextColor - } - - - Loader { - id: editorLoader - anchors.leftMargin: _margin - anchors.topMargin: _margin - anchors.left: parent.left - anchors.top: descriptionLabel.bottom - source: "FlyAreaEditor.qml" - visible: _currentItem - - property var masterController: _masterController - property real availableWidth: _root.width - (_margin * 2) ///< How wide the editor should be - property var editorRoot: _root - } -} // Rectangle diff --git a/src/WimaView/WimaGOperationAreaEditor.qml b/src/WimaView/WimaMeasurementAreaEditor.qml similarity index 100% rename from src/WimaView/WimaGOperationAreaEditor.qml rename to src/WimaView/WimaMeasurementAreaEditor.qml diff --git a/src/WimaView/WimaGOperationAreaMapVisual.qml b/src/WimaView/WimaMeasurementAreaMapVisual.qml similarity index 97% rename from src/WimaView/WimaGOperationAreaMapVisual.qml rename to src/WimaView/WimaMeasurementAreaMapVisual.qml index 1b1ba73df..7f99715b0 100644 --- a/src/WimaView/WimaGOperationAreaMapVisual.qml +++ b/src/WimaView/WimaMeasurementAreaMapVisual.qml @@ -27,7 +27,6 @@ Item { property var areaItem: object property var _polygon: areaItem - property var _borderPolygon: areaItem.borderPolygon signal clicked(int sequenceNumber) @@ -92,7 +91,7 @@ Item { WimaMapPolygonVisuals { qgcView: _root.qgcView mapControl: map - mapPolygon: _borderPolygon + mapPolygon: areaItem.borderPolygon borderWidth: 1 borderColor: "white" interiorColor: "transparent" diff --git a/src/WimaView/WimaServicePolygonMapVisual.qml b/src/WimaView/WimaServicePolygonMapVisual.qml deleted file mode 100644 index 8fec7f55a..000000000 --- a/src/WimaView/WimaServicePolygonMapVisual.qml +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2016 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - -import QtQuick 2.3 -import QtQuick.Controls 1.2 -import QtLocation 5.3 -import QtPositioning 5.3 - -import QGroundControl 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.FlightMap 1.0 - -/// Wima Global Measurement Area visuals -Item { - id: _root - - property var map ///< Map control to place item in - property var qgcView ///< QGCView to use for popping dialogs - - property var _missionItem: object - property var _polygon: object.polygon - - signal clicked(int sequenceNumber) - - /// Add an initial 4 sided polygon if there is none - function _addInitialPolygon() { - if (_polygon.count < 3) { - // Initial polygon is inset to take 2/3rds space - var rect = Qt.rect(map.centerViewport.x, map.centerViewport.y, map.centerViewport.width, map.centerViewport.height) - rect.x += (rect.width * 0.25) / 2 - rect.y += (rect.height * 0.25) / 2 - rect.width *= 0.25 - rect.height *= 0.25 - - var centerCoord = map.toCoordinate(Qt.point(rect.x + (rect.width / 2), rect.y + (rect.height / 2)), false /* clipToViewPort */) - var topLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y), false /* clipToViewPort */) - var topRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y), false /* clipToViewPort */) - var bottomLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y + rect.height), false /* clipToViewPort */) - var bottomRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y + rect.height), false /* clipToViewPort */) - - // Adjust polygon to max size - var maxSize = 100 - var halfWidthMeters = Math.min(topLeftCoord.distanceTo(topRightCoord), maxSize) / 2 - var halfHeightMeters = Math.min(topLeftCoord.distanceTo(bottomLeftCoord), maxSize) / 2 - topLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 0) - topRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 0) - bottomLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 180) - bottomRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 180) - - _polygon.appendVertex(topLeftCoord) - _polygon.appendVertex(topRightCoord) - _polygon.appendVertex(bottomRightCoord) - _polygon.appendVertex(bottomLeftCoord) - } - } - - Component.onCompleted: { - _addInitialPolygon() - } - - Component.onDestruction: { - } - - QGCMapPolygonVisuals { - qgcView: _root.qgcView - mapControl: map - mapPolygon: _polygon - interactive: _missionItem.isCurrentPolygon - borderWidth: 1 - borderColor: "black" - interiorColor: "yellow" - interiorOpacity: 0.25 - } - - - - -} diff --git a/src/WimaView/WimaView.qml b/src/WimaView/WimaView.qml index 274168abb..419343dd3 100644 --- a/src/WimaView/WimaView.qml +++ b/src/WimaView/WimaView.qml @@ -53,11 +53,11 @@ QGCView { readonly property bool _waypointsOnlyMode: QGroundControl.corePlugin.options.missionWaypointsOnly property bool _airspaceEnabled: QGroundControl.airmapSupported ? (QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue && QGroundControl.airspaceManager.connected): false - property var _wimaController: wimaController + property var _wimaPlaner: wimaPlaner property var _planMasterController: masterController property var _missionController: _planMasterController.missionController property var _visualItems: _missionController.visualItems - property var _wimaVisualItems: _wimaController.visualItems + property var _wimaVisualItems: _wimaPlaner.visualItems property bool _lightWidgetBorders: editorMap.isSatelliteMap property bool _addWaypointOnClick: false property bool _addROIOnClick: false @@ -72,11 +72,8 @@ QGCView { readonly property string _armedVehicleUploadPrompt: qsTr("Vehicle is currently armed. Do you want to upload the mission to the vehicle?") Component.onCompleted: { - toolbar.planMasterController = Qt.binding(function () { return _planMasterController }) - toolbar.currentMissionItem = Qt.binding(function () { return _missionController.currentPlanViewItem }) - _wimaController.masterController = _planMasterController - _wimaController.missionController = _planMasterController.missionController - _wimaController.dataContainer = dataContainer; + toolbar.planMasterController = Qt.binding(function () { return _planMasterController }) + toolbar.currentMissionItem = Qt.binding(function () { return _missionController.currentPlanViewItem }) } function addComplexItem(complexItemName) { @@ -189,13 +186,13 @@ QGCView { message: qsTr("You need at least one item to create a KML.") } } - WimaController { - id:wimaController + WimaPlaner { + id:wimaPlaner Component.onCompleted: { - wimaController.masterController = Qt.binding(function () { return masterController}) - wimaController.missionController = Qt.binding(function () { return masterController.missionController}) - startWimaController(false /* flyView */) + wimaPlaner.masterController = Qt.binding(function () { return masterController}) + wimaPlaner.missionController = Qt.binding(function () { return masterController.missionController}) + wimaPlaner.dataContainer = Qt.binding(function () { return dataContainerPointer}) } function addComplexItem(complexItemName) { var coordinate = editorMap.center @@ -227,8 +224,8 @@ QGCView { function loadFromSelectedFile() { wimaFileDialog.title = qsTr("Select Wima File") wimaFileDialog.selectExisting = true - wimaFileDialog.nameFilters = wimaController.loadNameFilters - wimaFileDialog.fileExtension = wimaController.fileExtension + wimaFileDialog.nameFilters = wimaPlaner.loadNameFilters + wimaFileDialog.fileExtension = wimaPlaner.fileExtension wimaFileDialog.fileExtension2 = _appSettings.planFileExtension wimaFileDialog.openForLoad() } @@ -236,8 +233,8 @@ QGCView { function saveToSelectedFile() { wimaFileDialog.title = qsTr("Save to Wima File") wimaFileDialog.selectExisting = false - wimaFileDialog.nameFilters = wimaController.saveNameFilters - wimaFileDialog.fileExtension = wimaController.fileExtension + wimaFileDialog.nameFilters = wimaPlaner.saveNameFilters + wimaFileDialog.fileExtension = wimaPlaner.fileExtension wimaFileDialog.fileExtension2 = _appSettings.planFileExtension wimaFileDialog.openForSave() } @@ -380,9 +377,9 @@ QGCView { _missionController.setCurrentPlanViewIndex(0, true) } else { var retList = ShapeFileHelper.determineShapeType(file) - if (retList[0] == ShapeFileHelper.Error) { + if (retList[0] === ShapeFileHelper.Error) { _qgcView.showMessage("Error", retList[1], StandardButton.Ok) - } else if (retList[0] == ShapeFileHelper.Polygon) { + } else if (retList[0] === ShapeFileHelper.Polygon) { var editVehicle = _activeVehicle ? _activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle if (editVehicle.fixedWing) { insertComplexMissionItemFromKMLOrSHP(_missionController.surveyComplexItemName, file, -1) @@ -390,7 +387,7 @@ QGCView { polygonSelectPatternFile = file _qgcView.showDialog(patternPolygonSelectDialog, fileDialog.title, _qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel) } - } else if (retList[0] == ShapeFileHelper.Polyline) { + } else if (retList[0] === ShapeFileHelper.Polyline) { insertComplexMissionItemFromKMLOrSHP(_missionController.corridorScanComplexItemName, file, -1) } } @@ -404,13 +401,13 @@ QGCView { folder: _appSettings.missionSavePath onAcceptedForSave: { - wimaController.saveToFile(file) + wimaPlaner.saveToFile(file) close() } onAcceptedForLoad: { - wimaController.loadFromFile(file) - editorMap.center = wimaController.joinedAreaCenter; + wimaPlaner.loadFromFile(file) + editorMap.center = wimaPlaner.joinedAreaCenter; close() } } @@ -584,7 +581,7 @@ QGCView { //Add Wima Visuals Repeater { - model: wimaController.visualItems + model: wimaPlaner.visualItems delegate: WimaMapVisual { map: editorMap ///< Map control to place item in qgcView: _qgcView ///< QGCView to use for popping dialogs @@ -674,7 +671,7 @@ QGCView { dropPanelComponent: syncDropPanel }, { - name: qsTr("Global"), + name: qsTr("Measure"), iconSource: "/qmlimages/Target.svg" }, { @@ -707,16 +704,16 @@ QGCView { onClicked: { switch (index) { case 1: - wimaController.addGOperationArea(); + wimaPlaner.addMeasurementArea(); break case 2: - wimaController.addServiceArea(); + wimaPlaner.addServiceArea(); break case 3: - wimaController.addVehicleCorridor(); + wimaPlaner.addCorridor(); break case 4: - wimaController.updateMission(); + wimaPlaner.updateMission(); break case 6: editorMap.zoomLevel += 0.5 @@ -929,11 +926,11 @@ QGCView { switch (current) { case planElementMission: _editingLayer = _layerMission - _wimaController.resetAllInteractive(); + _wimaPlaner.resetAllInteractive(); break case planElementWima: _editingLayer = _layerWima - _wimaController.setInteractive(); + _wimaPlaner.setInteractive(); break } } @@ -974,26 +971,26 @@ QGCView { anchors.fill: parent spacing: ScreenTools.defaultFontPixelHeight / 4 orientation: ListView.Vertical - model: wimaController.visualItems + model: wimaPlaner.visualItems cacheBuffer: Math.max(height * 2, 0) clip: true - currentIndex: wimaController.currentPolygonIndex + currentIndex: wimaPlaner.currentPolygonIndex highlightMoveDuration: 250 visible: _editingLayer == _layerWima && !planControlColapsed //-- List Elements delegate: WimaItemEditor { map: editorMap masterController: _planMasterController - wimaController: _wimaController + wimaPlaner: _wimaPlaner _index: index areaItem: object width: parent.width readOnly: false rootQgcView: _qgcView - onClicked: _wimaController.currentPolygonIndex = index + onClicked: _wimaPlaner.currentPolygonIndex = index onRemove: { var removeIndex = index - _wimaController.removeArea(removeIndex) + _wimaPlaner.removeArea(removeIndex) } } @@ -1099,7 +1096,7 @@ QGCView { QGCViewMessage { message: qsTr("Are you sure you want to remove all items and create a Wima mission? ") function accept() { - wimaController.removeAll(); + wimaPlaner.removeAll(); hideDialog() } } @@ -1214,18 +1211,18 @@ QGCView { enabled: true//!masterController.syncInProgress onClicked: { dropPanel.hide() - wimaController.loadFromSelectedFile() + wimaPlaner.loadFromSelectedFile() } } QGCButton { text: qsTr("Save ") Layout.fillWidth: true - enabled: wimaController.currentFile !== "" + enabled: wimaPlaner.currentFile !== "" onClicked: { dropPanel.hide() - wimaController.saveToCurrent() - console.log("saveing to: ", wimaController.currentFile) + wimaPlaner.saveToCurrent() + console.log("saveing to: ", wimaPlaner.currentFile) } } @@ -1235,7 +1232,7 @@ QGCView { enabled: _wimaVisualItems.count >= 1 onClicked: { dropPanel.hide() - wimaController.saveToSelectedFile() + wimaPlaner.saveToSelectedFile() } } @@ -1328,7 +1325,7 @@ QGCView { QGCListView { anchors.fill: parent - model: wimaController.visualItems + model: wimaPlaner.visualItems delegate: Rectangle{ height: 15 color: "lightsteelblue" diff --git a/src/ui/MainWindowInner.qml b/src/ui/MainWindowInner.qml index da34a418e..39e9a22e1 100644 --- a/src/ui/MainWindowInner.qml +++ b/src/ui/MainWindowInner.qml @@ -401,7 +401,7 @@ Item { visible: false property var toolbar: wimaToolBar - property var dataContainer: wimaDataContainer + property var dataContainerPointer: wimaDataContainer.pointerToThis() } @@ -410,7 +410,7 @@ Item { anchors.fill: parent visible: true - property var dataContainer: wimaDataContainer + property var dataContainerPointer: wimaDataContainer.pointerToThis() //------------------------------------------------------------------------- //-- Loader helper for any child, no matter how deep can display an element // on top of the video window. -- 2.22.0