diff --git a/src/MissionManager/QGCMapPolygon.cc b/src/MissionManager/QGCMapPolygon.cc index d3111ac123ba9e758a532a5267865319b10cca15..4de88a90efb2a4e8175f90daa4fa0d6591e96804 100644 --- a/src/MissionManager/QGCMapPolygon.cc +++ b/src/MissionManager/QGCMapPolygon.cc @@ -367,6 +367,43 @@ void QGCMapPolygon::setInteractive(bool interactive) } } +void print(const QGCMapPolygon &poly) +{ + QString message; + print(poly, message); + + qWarning() << message; +} + +void print(const QGCMapPolygon &poly, QString &outputString) +{ + outputString.append(QString("Coordinates:\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("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())); +} + +void swap(QGCMapPolygon &poly1, QGCMapPolygon &poly2) +{ + using std::swap; + + poly1._polygonPath.swap(poly2._polygonPath); + swap(poly1._polygonModel, poly2._polygonModel); + swap(poly1._dirty, poly2._dirty); + swap(poly1._center, poly2._center); + swap(poly1._centerDrag, poly2._centerDrag); + swap(poly1._ignoreCenterUpdates, poly2._ignoreCenterUpdates); + swap(poly1._interactive, poly2._interactive); +} + QGeoCoordinate QGCMapPolygon::vertexCoordinate(int vertex) const { if (vertex >= 0 && vertex < _polygonPath.count()) { diff --git a/src/MissionManager/QGCMapPolygon.h b/src/MissionManager/QGCMapPolygon.h index d112a58d2ef0f86c35ae55783a33a0d1d7a54023..4e8cbec6c43ba6d14531971e8490efe0c8741f3c 100644 --- a/src/MissionManager/QGCMapPolygon.h +++ b/src/MissionManager/QGCMapPolygon.h @@ -105,6 +105,12 @@ public: void setCenterDrag (bool centerDrag); void setInteractive (bool interactive); + // Friends + friend void swap(QGCMapPolygon& poly1, QGCMapPolygon& poly2); + friend void print(const QGCMapPolygon& poly, QString& outputString); + friend void print(const QGCMapPolygon& poly); + + // static Variables static const char* jsonPolygonKey; signals: diff --git a/src/QmlControls/QmlObjectListModel.cc b/src/QmlControls/QmlObjectListModel.cc index 64764a3651c9bf379a5ff71645f6d748246250b6..e05e0f7e95a3e139441ba9f84984676b2e02c7d7 100644 --- a/src/QmlControls/QmlObjectListModel.cc +++ b/src/QmlControls/QmlObjectListModel.cc @@ -268,3 +268,12 @@ void QmlObjectListModel::clearAndDeleteContents() clear(); endResetModel(); } + +void swap(QmlObjectListModel &list1, QmlObjectListModel &list2) +{ + using std::swap; + + swap(list1._objectList, list2._objectList); + swap(list1._dirty, list2._dirty); + swap(list1._skipDirtyFirstItem, list2._skipDirtyFirstItem); +} diff --git a/src/QmlControls/QmlObjectListModel.h b/src/QmlControls/QmlObjectListModel.h index d7db98d753d8caa2624066f4425ff4b85669b5c3..110fa2c8d9d1b12b7d8b65c2b7bf29f69fd7ead7 100644 --- a/src/QmlControls/QmlObjectListModel.h +++ b/src/QmlControls/QmlObjectListModel.h @@ -59,6 +59,9 @@ public: void beginReset () { beginResetModel(); } void endReset () { endResetModel(); } + // Friends + friend void swap(QmlObjectListModel& list1, QmlObjectListModel& list2); + signals: void countChanged (int count); void dirtyChanged (bool dirtyChanged); diff --git a/src/Wima/WimaArea.cc b/src/Wima/WimaArea.cc index 4aa348c23ede2795fe6f5de3d43d4c48413fe5d8..7f7e7bfcc77dcd1d17a23964365650b9c4355ae7 100644 --- a/src/Wima/WimaArea.cc +++ b/src/Wima/WimaArea.cc @@ -6,42 +6,32 @@ const char* WimaArea::wimaAreaName = "WimaArea"; const char* WimaArea::areaTypeName = "AreaType"; -WimaArea::WimaArea() - : QGCMapPolygon (nullptr) -{ - this->setObjectName(wimaAreaName); - _maxAltitude = 30; - _wimaVehicle = new WimaVehicle(this); -} -WimaArea::WimaArea(QObject *parent) - : QGCMapPolygon (parent) -{ - this->setObjectName(wimaAreaName); - _maxAltitude = 30; - _wimaVehicle = new WimaVehicle(this); -} -WimaArea::WimaArea(const QGCMapPolygon &other, QObject *parent) - : QGCMapPolygon (other, parent) +WimaArea::WimaArea(QObject *parent) + : QGCMapPolygon (parent) { - this->setObjectName(wimaAreaName); + init(); _maxAltitude = 30; - _wimaVehicle = new WimaVehicle(this); } WimaArea::WimaArea(const WimaArea &other, QObject *parent) - : WimaArea (parent) + : QGCMapPolygon (other, parent) { - this->setObjectName(wimaAreaName); + init(); this->setPath(other.path()); this->setCenter(other.center()); this->setCenterDrag(other.centerDrag()); this->setInteractive(other.interactive()); _maxAltitude = other.maxAltitude(); - _wimaVehicle = other.vehicle(); } +WimaArea &WimaArea::operator=(WimaArea other) +{ + swap(*this, other); // copy-swap-idiom + + return *this; +} void WimaArea::setMaxAltitude(double alt) { @@ -51,14 +41,7 @@ void WimaArea::setMaxAltitude(double alt) } } -void WimaArea::setVehicle(WimaVehicle *vehicle) -{ - if(_wimaVehicle != vehicle){ - _wimaVehicle->deleteLater(); - _wimaVehicle = vehicle; - emit vehicleChanged(); - } -} + /*QList* WimaArea::splitArea(WimaArea *polygonToSplitt, int numberOfFractions) { @@ -127,7 +110,7 @@ void WimaArea::join(QList* polyList, WimaArea* joinedPoly) return; } -void WimaArea::join(WimaArea &poly1, WimaArea &poly2, WimaArea &joinedPoly) +bool WimaArea::join(WimaArea &poly1, WimaArea &poly2, WimaArea &joinedPoly) { if (poly1.count() >= 3 && poly2.count() >= 3) { @@ -156,7 +139,7 @@ void WimaArea::join(WimaArea &poly1, WimaArea &poly2, WimaArea &joinedPoly) if ( crossContainsWalker == true) { joinedPoly.appendVertices(crossPoly->coordinateList()); - return; + return true; } @@ -222,22 +205,28 @@ void WimaArea::join(WimaArea &poly1, WimaArea &poly2, WimaArea &joinedPoly) } if (currentVertex == startVertex) { - return; + if (poly1.count() == joinedPoly.count()) { // is the case if poly1 and poly2 don't intersect + return false; + } else { + return true; + } } } } else { - qWarning("WimaArea::joinPolygons(poly1, poly2): poly->count() < 3"); - return; + return false; } } -void WimaArea::join(WimaArea &poly) +bool WimaArea::join(WimaArea &poly) { WimaArea joinedArea; - join(*this, poly, joinedArea); - this->setPath(joinedArea.path()); - return; + if ( join(*this, poly, joinedArea) ) { + this->setPath(joinedArea.path()); + return true; + } else { + return false; + } } bool WimaArea::isDisjunct(QList* polyList) @@ -378,20 +367,18 @@ bool WimaArea::intersects(const QGCMapPolyline& line, const WimaArea& poly, QLis } } -double WimaArea::distInsidePoly(const QGeoCoordinate &c1, const QGeoCoordinate &c2, const WimaArea &poly) +double WimaArea::distInsidePoly(const QGeoCoordinate &c1, const QGeoCoordinate &c2, WimaArea poly) { - WimaArea bigPoly(poly); - bigPoly.offset(0.1); // hack to compensate for numerical issues, migh be replaced in the future... - if ( bigPoly.containsCoordinate(c1) && bigPoly.containsCoordinate(c2)) { + poly.offset(0.1); // hack to compensate for numerical issues, migh be replaced in the future... + if ( poly.containsCoordinate(c1) && poly.containsCoordinate(c2)) { QList intersectionList; QList> neighbourlist; QGCMapPolyline line; line.appendVertex(c1); line.appendVertex(c2); - intersects(line, bigPoly, intersectionList, neighbourlist); + intersects(line, poly, intersectionList, neighbourlist); - //if ( intersectionList.size() == (c1InPolyRim || c2InPolyRim ? 2:0) ){ if ( intersectionList.size() == 0 ){ return c1.distanceTo(c2); } else { @@ -403,8 +390,12 @@ double WimaArea::distInsidePoly(const QGeoCoordinate &c1, const QGeoCoordinate & } } -void WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &end, const WimaArea &poly, QList &dijkstraPath) +bool WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &end, const WimaArea &poly, QList &dijkstraPath) { + if ( isSelfIntersecting(poly) ) { + return false; + } + struct Node{ QGeoCoordinate coordinate; double distance = std::numeric_limits::infinity(); @@ -477,7 +468,7 @@ void WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &e Node* Node = &nodeList.last(); if (Node->predecessorNode == nullptr) { qWarning("WimaArea::dijkstraPath(): Error, no path found!"); - return; + return false; } while (1) { @@ -489,6 +480,40 @@ void WimaArea::dijkstraPath(const QGeoCoordinate &start, const QGeoCoordinate &e break; } } + + return true; +} + +bool WimaArea::isSelfIntersecting(const WimaArea &poly) +{ + int i = 0; + if (poly.count() > 3) { + while(i < poly.count()-1) { + QGCMapPolyline refLine; + refLine.appendVertex(poly.vertexCoordinate(i)); + refLine.appendVertex(poly.vertexCoordinate(poly.nextVertexIndex(i))); + int j = poly.nextVertexIndex(i); + while(j < poly.count()) { + QGeoCoordinate dummy; + QGCMapPolyline iteratorLine; + iteratorLine.appendVertex(poly.vertexCoordinate(j)); + iteratorLine.appendVertex(poly.vertexCoordinate(poly.nextVertexIndex(j))); + + if ( intersects(refLine, iteratorLine, dummy) ) + return true; + + j++; + } + i++; + } + } + + return false; +} + +bool WimaArea::isSelfIntersecting() +{ + return isSelfIntersecting(*this); } void WimaArea::saveToJson(QJsonObject &json) @@ -515,3 +540,30 @@ bool WimaArea::loadFromJson(const QJsonObject &json, QString& errorString) } } +void WimaArea::init() +{ + this->setObjectName(wimaAreaName); +} + +void print(const WimaArea &area) +{ + QString message; + print(area, message); + qWarning() << message; +} + +void print(const WimaArea &area, QString &outputString) +{ + outputString.append(QString("Type: %s").arg(area.objectName())); + print(static_cast(area), outputString); + outputString.append(QString("Maximum Altitude: %.3f").arg(area._maxAltitude)); +} + + +void swap(WimaArea &area1, WimaArea &area2) +{ + using std::swap; + swap(static_cast(area1), static_cast(area2)); + swap(area1._maxAltitude, area2._maxAltitude); +} + diff --git a/src/Wima/WimaArea.h b/src/Wima/WimaArea.h index 8a316bd544546842faaa620bc3b6d37824f972bd..e959503098884dfb93050707004bee5864ce8ad9 100644 --- a/src/Wima/WimaArea.h +++ b/src/Wima/WimaArea.h @@ -15,21 +15,17 @@ class WimaArea : public QGCMapPolygon //abstract base class for all WimaAreas { Q_OBJECT public: - WimaArea(); - WimaArea(QObject* parent); - WimaArea(const QGCMapPolygon& other, QObject* parent); - WimaArea(const WimaArea& other, QObject* parent); - + WimaArea(QObject* parent = nullptr); + WimaArea(const WimaArea& other, QObject* parent = nullptr); + WimaArea& operator=(WimaArea other); Q_PROPERTY(double maxAltitude READ maxAltitude WRITE setMaxAltitude NOTIFY maxAltitudeChanged) Q_PROPERTY(QString mapVisualQML READ mapVisualQML CONSTANT) Q_PROPERTY(QString editorQML READ editorQML CONSTANT) - Q_PROPERTY(WimaVehicle* vehicle READ vehicle WRITE setVehicle NOTIFY vehicleChanged) //Property accessors double maxAltitude (void) const { return _maxAltitude;} - WimaVehicle* vehicle (void) const { return _wimaVehicle;} virtual QString mapVisualQML (void) const { return "WimaAreaMapVisual.qml";} virtual QString editorQML (void) const { return "WimaAreaEditor.qml";} @@ -39,10 +35,6 @@ public: void setVehicle (WimaVehicle* vehicle); // Member Methodes - /*template - QList* splitArea (WimaArea *polygonToSplitt, int numberOfFractions); // use QScopedPointer to store return value - template - QList* splitArea (int numberOfFractions); // use QScopedPointer to store return value*/ //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 @@ -52,9 +44,9 @@ public: static void join (QList* polyList, WimaArea* joinedPoly);// change to & notation /// 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 the joined polygon of poly1 and poly2 if possible, poly1 else - static void join (WimaArea &poly1, WimaArea &poly2, WimaArea& joinedPoly); - void join (WimaArea &poly); + /// @return true if polygons have been joined, false else + static bool join (WimaArea &poly1, WimaArea &poly2, WimaArea& joinedPoly); + bool join (WimaArea &poly); 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 @@ -77,13 +69,25 @@ public: static bool intersects(const QGCMapPolyline& line, const WimaArea& poly, 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, const WimaArea& poly); + static double distInsidePoly(const QGeoCoordinate& c1, const QGeoCoordinate& c2, WimaArea poly); /// calculates the shortes path between two geo coordinates inside a polygon using the Dijkstra Algorithm - static void dijkstraPath(const QGeoCoordinate& c1, const QGeoCoordinate& c2, const WimaArea& poly, QList& dijkstraPath); + /// @return true if path was found, false else + static bool dijkstraPath(const QGeoCoordinate& c1, const QGeoCoordinate& c2, const WimaArea& poly, QList& dijkstraPath); + /// @return true if the polygon is self intersecting + static bool isSelfIntersecting(const WimaArea& poly); + bool isSelfIntersecting(); + void saveToJson(QJsonObject& jsonObject); bool loadFromJson(const QJsonObject &jsonObject, QString& errorString); + // Friends + friend void swap(WimaArea& area1, WimaArea& area2); + /// 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; @@ -98,7 +102,9 @@ signals: protected: double _maxAltitude; - WimaVehicle* _wimaVehicle; + +private: + void init(); }; diff --git a/src/Wima/WimaController.cc b/src/Wima/WimaController.cc index 82c186073d8ef85adc64dc12a1e7ff31cf1a08d8..5568bae1a15898346548a9e24312515926a7ec4e 100644 --- a/src/Wima/WimaController.cc +++ b/src/Wima/WimaController.cc @@ -4,22 +4,23 @@ const char* WimaController::wimaFileExtension = "wima"; const char* WimaController::areaItemsName = "AreaItems"; const char* WimaController::missionItemsName = "MissionItems"; -WimaController::WimaController(QObject *parent) : - QObject (parent) - ,_flyView (true) - ,_currentPolygonIndex (-1) - ,_container(nullptr) +WimaController::WimaController(QObject *parent) + : QObject (parent) + , _flyView (true) + , _readyForSaveSend (false) + , _currentPolygonIndex (-1) + , _container (nullptr) + , _joinedArea (this) + , _opArea (this) + , _serArea (this) + , _corridor (this) { connect(this, &WimaController::currentPolygonIndexChanged, this, &WimaController::recalcPolygonInteractivity); } -QmlObjectListModel *WimaController::visualItems() const +const QmlObjectListModel* WimaController::visualItems() const { - if (_container != nullptr) { - return _container->visualItems(); - } else { - return nullptr; - } + return &_visualItems; } QStringList WimaController::loadNameFilters() const @@ -41,21 +42,12 @@ QStringList WimaController::saveNameFilters() const QGeoCoordinate WimaController::joinedAreaCenter() const { - if (_container != nullptr) { - return _container->joinedArea()->center(); - } else { - return QGeoCoordinate(); - } + return _joinedArea.center(); } -WimaArea *WimaController::joinedArea() const +WimaArea WimaController::joinedArea() const { - if (_container != nullptr) { - return _container->joinedArea(); void uploadToContainer(); - void downloadFromContainer(); - } else { - return nullptr; - } + return _joinedArea; } void WimaController::setMasterController(PlanMasterController *masterC) @@ -72,7 +64,7 @@ void WimaController::setMissionController(MissionController *missionC) void WimaController::setCurrentPolygonIndex(int index) { - if(_container != nullptr && index >= 0 && index < _container->visualItems()->count() && index != _currentPolygonIndex){ + if(index >= 0 && index < _visualItems.count() && index != _currentPolygonIndex){ _currentPolygonIndex = index; emit currentPolygonIndexChanged(index); @@ -81,9 +73,21 @@ void WimaController::setCurrentPolygonIndex(int index) void WimaController::setDataContainer(WimaDataContainer *container) { - if (container != nullptr && _container != container) { + if (_container == nullptr && container != nullptr) { _container = container; + if (_flyView) { + downloadFromContainer(); + _visualItems.append(&_opArea); + _visualItems.append(&_serArea); + _visualItems.append(&_joinedArea); + + connect(_container, &WimaDataContainer::opAreaChanged, this, &WimaController::setOpArea); + connect(_container, &WimaDataContainer::serAreaChanged, this, &WimaController::setSerArea); + connect(_container, &WimaDataContainer::corridorChanged, this, &WimaController::setCorridor); + connect(_container, &WimaDataContainer::joinedAreaChanged, this, &WimaController::setJoinedArea); + } + emit dataContainerChanged(); } } @@ -95,25 +99,29 @@ void WimaController::startWimaController(bool flyView) void WimaController::removeArea(int index) { - if(_container != nullptr && index >= 0 && index < _container->visualItems()->count()){ - WimaArea* area = qobject_cast(_container->visualItems()->removeAt(index)); + if(index >= 0 && index < _visualItems.count()){ + if (_flyView) { //not editing allowed in flyView + return; + } + WimaArea* area = qobject_cast(_visualItems.removeAt(index)); if ( area == nullptr) { qWarning("WimaController::removeArea(): nullptr catched, internal error."); return; } + area->clear(); emit visualItemsChanged(); - if (_container->visualItems()->count() == 0) { + if (_visualItems.count() == 0) { // this branch is reached if all items are removed // to guarentee proper behavior, _currentPolygonIndex must be set to a invalid value, as on constructor init. _currentPolygonIndex = -1; return; } - if(_currentPolygonIndex >= _container->visualItems()->count()){ - setCurrentPolygonIndex(_container->visualItems()->count() - 1); + if(_currentPolygonIndex >= _visualItems.count()){ + setCurrentPolygonIndex(_visualItems.count() - 1); }else{ recalcPolygonInteractivity(_currentPolygonIndex); } @@ -125,96 +133,57 @@ void WimaController::removeArea(int index) bool WimaController::addGOperationArea() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return false; - } + if (!_flyView && !_visualItems.contains(&_opArea)) { + _visualItems.append(&_opArea); - // check if opArea exists already - WimaGOperationArea* opArea = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaGOperationArea* currentArea = qobject_cast(_container->visualItems()->get(i)); - if ( currentArea != nullptr ) { - opArea = currentArea; - return false; - } - } + int newIndex = _visualItems.count()-1; + setCurrentPolygonIndex(newIndex); - // create one if no opArea available - opArea = new WimaGOperationArea(this); - _container->visualItems()->append(opArea); - int newIndex = _container->visualItems()->count()-1; - setCurrentPolygonIndex(newIndex); - - emit visualItemsChanged(); - return true; + emit visualItemsChanged(); + return true; + } else { + return false; + } } bool WimaController::addServiceArea() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return false; - } - - // check if serArea exists already - WimaServiceArea* serArea = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaServiceArea* currentArea = qobject_cast(_container->visualItems()->get(i)); - if ( currentArea != nullptr ) { - serArea = currentArea; - return false; - } - } + if (!_flyView && !_visualItems.contains(&_serArea)) { + _visualItems.append(&_serArea); - // create one if no serArea available - serArea = new WimaServiceArea(this); + int newIndex = _visualItems.count()-1; + setCurrentPolygonIndex(newIndex); - _container->visualItems()->append(serArea); - int newIndex = _container->visualItems()->count()-1; - setCurrentPolygonIndex(newIndex); - - emit visualItemsChanged(); - return true; + emit visualItemsChanged(); + return true; + } else { + return false; + } } bool WimaController::addVehicleCorridor() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return false; - } - - // check if corridor exists already - WimaVCorridor* corridor = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaVCorridor* currentArea = qobject_cast(_container->visualItems()->get(i)); - if ( currentArea != nullptr ) { - corridor = currentArea; - return false; - } - } - - // create one if no corridor available - corridor = new WimaVCorridor(this); + if (!_flyView && !_visualItems.contains(&_corridor)) { + _visualItems.append(&_corridor); - _container->visualItems()->append(corridor); - int newIndex = _container->visualItems()->count()-1; - setCurrentPolygonIndex(newIndex); + int newIndex = _visualItems.count()-1; + setCurrentPolygonIndex(newIndex); - emit visualItemsChanged(); - return true; + emit visualItemsChanged(); + return true; + } else { + return false; + } } void WimaController::removeAll() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); + if (_flyView) { return; } bool changesApplied = false; - while (_container->visualItems()->count() > 0) { + while (_visualItems.count() > 0) { removeArea(0); changesApplied = true; } @@ -250,131 +219,111 @@ void WimaController::resumeMission() bool WimaController::updateMission() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return false; - } + if (!_flyView) { + setReadyForSaveSend(false); + #define debug 0 - #define debug 0 - // pick first WimaGOperationArea - WimaGOperationArea* opArea = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaGOperationArea* currentArea = qobject_cast(_container->visualItems()->get(i)); - if (currentArea != nullptr){ - opArea = currentArea; - break; + if ( !updateJoinedArea()) { + qgcApp()->showMessage(tr("Not able to join areas. Areas must be overlapping")); + return false; } - } - if (opArea == nullptr) - return false; - // pick first WimaServiceArea - WimaServiceArea* serArea = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaServiceArea* currentArea = qobject_cast(_container->visualItems()->get(i)); - if (currentArea != nullptr){ - serArea = currentArea; - break; - } - } - if ( serArea == nullptr ) - return false; - // pick first WimaVCorridor - WimaVCorridor* corridor = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaVCorridor* currentArea = qobject_cast(_container->visualItems()->get(i)); - if (currentArea != nullptr){ - corridor = currentArea; - break; - } - } + #if debug + _visualItems.append(&_joinedArea); + #endif - updateJoinedArea(); + // reset visual items + _missionController->removeAll(); + QmlObjectListModel* missionItems = _missionController->visualItems(); + // set home position to serArea center + MissionSettingsItem* settingsItem= qobject_cast(missionItems->get(0)); + if (settingsItem == nullptr){ + qWarning("WimaController::updateMission(): settingsItem == nullptr"); + return false; + } - #if debug - _container->visualItems()->append(&_joinedArea); - #endif + // set altitudes, temporary measure to solve bugs + QGeoCoordinate center = _serArea.center(); + center.setAltitude(0); + _serArea.setCenter(center); + center = _opArea.center(); + center.setAltitude(0); + _opArea.setCenter(center); + center = _corridor.center(); + center.setAltitude(0); + _corridor.setCenter(center); - // reset visual items - _missionController->removeAll(); - QmlObjectListModel* missionItems = _missionController->visualItems(); - // set home position to serArea center - MissionSettingsItem* settingsItem= qobject_cast(missionItems->get(0)); - if (settingsItem == nullptr){ - qWarning("WimaController::updateMission(): settingsItem == nullptr"); - return false; - } - // set altitudes, temporary measure to solve bugs - QGeoCoordinate center = serArea->center(); - center.setAltitude(0); - serArea->setCenter(center); - center = opArea->center(); - center.setAltitude(0); - opArea->setCenter(center); - center = corridor->center(); - center.setAltitude(0); - corridor->setCenter(center); - - - // set HomePos. to serArea center - settingsItem->setCoordinate(serArea->center()); - - // create take off position item - int sequenceNumber = _missionController->insertSimpleMissionItem(serArea->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()); - SurveyComplexItem* survey = qobject_cast(missionItems->get(missionItems->count()-1)); - if (survey == nullptr){ - qWarning("WimaController::updateMission(): survey == nullptr"); - return false; - } else { - survey->surveyAreaPolygon()->clear(); - survey->surveyAreaPolygon()->appendVertices(opArea->coordinateList()); - //survey-> - } + // set HomePos. to serArea center + settingsItem->setCoordinate(_serArea.center()); - // calculate path from take off to opArea - QGeoCoordinate start = serArea->center(); - QGeoCoordinate end = survey->visualTransectPoints().first().value(); - QList path; - WimaArea::dijkstraPath(start, end, *_container->joinedArea(), path); - for (int i = 1; i < path.count()-1; i++) { - sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count()-1); + // create take off position item + int sequenceNumber = _missionController->insertSimpleMissionItem(_serArea.center(), missionItems->count()); _missionController->setCurrentPlanViewIndex(sequenceNumber, true); - } - // calculate return path - start = survey->visualTransectPoints().last().value(); - end = serArea->center(); - path.clear(); - WimaArea::dijkstraPath(start, end, *_container->joinedArea(), path); - for (int i = 1; i < path.count()-1; i++) { - sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count()); + + // create survey item, will be extened with more()-> mission types in the future + _missionController->insertComplexMissionItem(_missionController->surveyComplexItemName(), _opArea.center(), missionItems->count()); + SurveyComplexItem* survey = qobject_cast(missionItems->get(missionItems->count()-1)); + if (survey == nullptr){ + qWarning("WimaController::updateMission(): survey == nullptr"); + return false; + } else { + survey->surveyAreaPolygon()->clear(); + survey->surveyAreaPolygon()->appendVertices(_opArea.coordinateList()); + //survey-> + } + + // calculate path from take off to opArea + QGeoCoordinate start = _serArea.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.")); + return false; + } + for (int i = 1; i < path.count()-1; i++) { + sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count()-1); + _missionController->setCurrentPlanViewIndex(sequenceNumber, true); + } + + // calculate return path + start = survey->visualTransectPoints().last().value(); + end = _serArea.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.")); + return false; + } + for (int i = 1; i < path.count()-1; i++) { + sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count()); + _missionController->setCurrentPlanViewIndex(sequenceNumber, true); + } + + // create land position item + sequenceNumber = _missionController->insertSimpleMissionItem(_serArea.center(), missionItems->count()); _missionController->setCurrentPlanViewIndex(sequenceNumber, true); - } + SimpleMissionItem* landItem = qobject_cast(missionItems->get(missionItems->count()-1)); + if (landItem == nullptr){ + qWarning("WimaController::updateMission(): landItem == nullptr"); + return false; + } else { + Vehicle* controllerVehicle = _masterController->controllerVehicle(); + MAV_CMD landCmd = controllerVehicle->vtol() ? MAV_CMD_NAV_VTOL_LAND : MAV_CMD_NAV_LAND; + if (controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(landCmd)) { + landItem->setCommand(landCmd); + } + } - // create land position item - sequenceNumber = _missionController->insertSimpleMissionItem(serArea->center(), missionItems->count()); - _missionController->setCurrentPlanViewIndex(sequenceNumber, true); - SimpleMissionItem* landItem = qobject_cast(missionItems->get(missionItems->count()-1)); - if (landItem == nullptr){ - qWarning("WimaController::updateMission(): landItem == nullptr"); - return false; + updateContainer(); + setReadyForSaveSend(true); + return true; } else { - Vehicle* controllerVehicle = _masterController->controllerVehicle(); - MAV_CMD landCmd = controllerVehicle->vtol() ? MAV_CMD_NAV_VTOL_LAND : MAV_CMD_NAV_LAND; - if (controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(landCmd)) { - landItem->setCommand(landCmd); - } + return true; } - return true; } void WimaController::saveToCurrent() @@ -429,11 +378,6 @@ bool WimaController::loadFromCurrent() bool WimaController::loadFromFile(const QString &filename) { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return false; - } - #define debug 0 QString errorString; QString errorMessage = tr("Error loading Plan file (%1). %2").arg(filename).arg("%1"); @@ -464,55 +408,41 @@ bool WimaController::loadFromFile(const QString &filename) // AreaItems QJsonArray areaArray = json[areaItemsName].toArray(); - _container->visualItems()->clear(); + _visualItems.clear(); for( int i = 0; i < areaArray.size(); i++) { QJsonObject jsonArea = areaArray[i].toObject(); if (jsonArea.contains(WimaArea::areaTypeName) && jsonArea[WimaArea::areaTypeName].isString()) { - if ( jsonArea[WimaArea::areaTypeName] == WimaArea::wimaAreaName ) { - WimaArea* area = new WimaArea(this); - bool success = area->loadFromJson(jsonArea, errorString); - - if ( !success ) { - qgcApp()->showMessage(errorMessage.arg(errorString)); - return false; - } - - _container->visualItems()->append(area); - emit visualItemsChanged(); - } else if ( jsonArea[WimaArea::areaTypeName] == WimaGOperationArea::wimaGOperationAreaName) { - WimaGOperationArea* opArea = new WimaGOperationArea(this); - bool success = opArea->loadFromJson(jsonArea, errorString); + if ( jsonArea[WimaArea::areaTypeName] == WimaGOperationArea::wimaGOperationAreaName) { + bool success = _opArea.loadFromJson(jsonArea, errorString); if ( !success ) { qgcApp()->showMessage(errorMessage.arg(errorString)); return false; } - _container->visualItems()->append(opArea); + _visualItems.append(&_opArea); emit visualItemsChanged(); } else if ( jsonArea[WimaArea::areaTypeName] == WimaServiceArea::wimaServiceAreaName) { - WimaServiceArea* serArea = new WimaServiceArea(this); - bool success = serArea->loadFromJson(jsonArea, errorString); + bool success = _serArea.loadFromJson(jsonArea, errorString); if ( !success ) { qgcApp()->showMessage(errorMessage.arg(errorString)); return false; } - _container->visualItems()->append(serArea); + _visualItems.append(&_serArea); emit visualItemsChanged(); } else if ( jsonArea[WimaArea::areaTypeName] == WimaVCorridor::wimaVCorridorName) { - WimaVCorridor* corridor = new WimaVCorridor(this); - bool success = corridor->loadFromJson(jsonArea, errorString); + bool success = _corridor.loadFromJson(jsonArea, errorString); if ( !success ) { qgcApp()->showMessage(errorMessage.arg(errorString)); return false; } - _container->visualItems()->append(corridor); + _visualItems.append(&_corridor); emit visualItemsChanged(); } else { errorString += QString(tr("%s not supported.\n").arg(WimaArea::areaTypeName)); @@ -580,100 +510,86 @@ bool WimaController::loadFromFile(const QString &filename) } } -void WimaController::recalcVehicleCorridor() +void WimaController::recalcPolygonInteractivity(int index) { - + if (index >= 0 && index < _visualItems.count()) { + resetAllInteractive(); + WimaArea* interactivePoly = qobject_cast(_visualItems.get(index)); + interactivePoly->setInteractive(true); + } } -void WimaController::recalcVehicleMeasurementAreas() +bool WimaController::updateJoinedArea() { + // join service area, op area and corridor + _joinedArea = _serArea; + _joinedArea.join(_corridor); + if ( !_joinedArea.join(_opArea) ) + return false; + else { + emit joinedAreaChanged() ; + return true; + } -} - -void WimaController::recalcAll() -{ } -void WimaController::recalcPolygonInteractivity(int index) +void WimaController::updateContainer() { - if (_container != nullptr && index >= 0 && index < _container->visualItems()->count()) { - resetAllInteractive(); - WimaArea* interactivePoly = qobject_cast(_container->visualItems()->get(index)); - interactivePoly->setInteractive(true); + if (_container != nullptr) { + _container->setOpArea(_opArea); + _container->setSerArea(_serArea); + _container->setCorridor(_corridor); + _container->setJoinedArea(_joinedArea); + } else { + qWarning("WimaController::uploadToContainer(): no container assigned."); } } -void WimaController::updateJoinedArea() +void WimaController::downloadFromContainer() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return; + if (_flyView) { + _opArea = _container->opArea(); + _serArea = _container->serArea(); + _corridor = _container->corridor(); + _joinedArea = _container->joinedArea(); } +} - // pick first WimaGOperationArea - WimaGOperationArea* opArea = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaGOperationArea* currentArea = qobject_cast(_container->visualItems()->get(i)); - if (currentArea != nullptr){ - opArea = currentArea; - break; - } - } - if (opArea == nullptr) - return; - - // pick first WimaServiceArea - WimaServiceArea* serArea = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaServiceArea* currentArea = qobject_cast(_container->visualItems()->get(i)); - if (currentArea != nullptr){ - serArea = currentArea; - break; - } +void WimaController::setOpArea(const WimaGOperationArea &area) +{ + if (_flyView) { + _opArea = area; } - if ( serArea == nullptr ) - return; +} - // pick first WimaVCorridor - WimaVCorridor* corridor = nullptr; - for (int i = 0; i < _container->visualItems()->count(); i++) { - WimaVCorridor* currentArea = qobject_cast(_container->visualItems()->get(i)); - if (currentArea != nullptr){ - corridor = currentArea; - break; - } +void WimaController::setSerArea(const WimaServiceArea &area) +{ + if (_flyView) { + _serArea = area; } +} - // join service area, op area and corridor - if (corridor != nullptr) { - WimaArea::join(*serArea, *corridor, *_container->joinedArea()); - _container->joinedArea()->join(*opArea); - } else { - WimaArea::join(*serArea, *opArea, *_container->joinedArea()); +void WimaController::setCorridor(const WimaVCorridor &area) +{ + if (_flyView) { + _corridor = area; } - - emit joinedAreaChanged() ; } -void WimaController::uploadToContainer() +void WimaController::setJoinedArea(const WimaArea &area) { - if (_container != nullptr) { - + if (_flyView) { + _joinedArea = area; } } void WimaController::resetAllInteractive() { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return ; - } - - int itemCount = _container->visualItems()->count(); + int itemCount = _visualItems.count(); if (itemCount > 0){ for (int i = 0; i < itemCount; i++) { - WimaArea* iteratorPoly = qobject_cast(_container->visualItems()->get(i)); + WimaArea* iteratorPoly = qobject_cast(_visualItems.get(i)); iteratorPoly->setInteractive(false); } } @@ -686,20 +602,15 @@ void WimaController::setInteractive() QJsonDocument WimaController::saveToJson(FileType fileType) { - if (_container == nullptr) { - qWarning("WimaController::addGOperationArea(): container not initialized!"); - return QJsonDocument(); - } - QJsonObject json; if ( fileType == FileType::WimaFile ) { QJsonArray jsonArray; - for (int i = 0; i < _container->visualItems()->count(); i++) { + for (int i = 0; i < _visualItems.count(); i++) { QJsonObject json; - WimaArea* area = qobject_cast(_container->visualItems()->get(i)); + WimaArea* area = qobject_cast(_visualItems.get(i)); if (area == nullptr) { qWarning("WimaController::saveToJson(): Internal error, area == nullptr!"); @@ -743,5 +654,13 @@ QJsonDocument WimaController::saveToJson(FileType fileType) return QJsonDocument(json); } +void WimaController::setReadyForSaveSend(bool ready) +{ + if (ready != _readyForSaveSend) { + _readyForSaveSend = ready; + emit readyForSaveSendChanged(ready); + } +} + diff --git a/src/Wima/WimaController.h b/src/Wima/WimaController.h index d2fe036a806d7fd42b29bde38b989a15f6637ee8..9718a107bdb127e8b818e8abd9d66d783ab02c5e 100644 --- a/src/Wima/WimaController.h +++ b/src/Wima/WimaController.h @@ -31,32 +31,33 @@ public: Q_PROPERTY(PlanMasterController* masterController READ masterController WRITE setMasterController NOTIFY masterControllerChanged) Q_PROPERTY(MissionController* missionController READ missionController WRITE setMissionController NOTIFY missionControllerChanged) - Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged) + Q_PROPERTY(const QmlObjectListModel*visualItems READ visualItems NOTIFY visualItemsChanged) Q_PROPERTY(int currentPolygonIndex READ currentPolygonIndex WRITE setCurrentPolygonIndex NOTIFY currentPolygonIndexChanged) Q_PROPERTY(QString currentFile READ currentFile NOTIFY currentFileChanged) 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(WimaArea* joinedArea READ joinedArea NOTIFY joinedAreaChanged) + Q_PROPERTY(WimaArea joinedArea READ joinedArea NOTIFY joinedAreaChanged) Q_PROPERTY(bool flyView READ flyView CONSTANT) Q_PROPERTY(WimaDataContainer* dataContainer READ dataContainer WRITE setDataContainer NOTIFY dataContainerChanged) - + Q_PROPERTY(bool readyForSaveSend READ readyForSaveSend NOTIFY readyForSaveSendChanged) // Property accessors PlanMasterController* masterController (void) const { return _masterController; } MissionController* missionController (void) const { return _missionController; } - QmlObjectListModel* visualItems (void) const; + const QmlObjectListModel* visualItems (void) const; int currentPolygonIndex (void) const { return _currentPolygonIndex; } QString currentFile (void) const { return _currentFile; } QStringList loadNameFilters (void) const; QStringList saveNameFilters (void) const; QString fileExtension (void) const { return wimaFileExtension; } QGeoCoordinate joinedAreaCenter (void) const; - WimaArea* joinedArea (void) const; + WimaArea joinedArea (void) const; WimaDataContainer* dataContainer (void) const { return _container; } bool flyView (void) const { return _flyView; } + bool readyForSaveSend (void) const { return _readyForSaveSend; } @@ -100,6 +101,7 @@ public: // Member Methodes QJsonDocument saveToJson(FileType fileType); + void setReadyForSaveSend(bool ready); signals: void masterControllerChanged (void); @@ -109,26 +111,30 @@ signals: void currentFileChanged (); void joinedAreaChanged (); void dataContainerChanged (); + void readyForSaveSendChanged (bool ready); private slots: - void recalcVehicleCorridor(); - void recalcVehicleMeasurementAreas(); - void recalcAll(); - void recalcPolygonInteractivity(int index); - void updateJoinedArea(); - void uploadToContainer(); - void downloadFromContainer(); + void recalcPolygonInteractivity (int index); + bool updateJoinedArea (); + void updateContainer (); + void downloadFromContainer (); + void setOpArea (const WimaGOperationArea& area); + void setSerArea (const WimaServiceArea& area); + void setCorridor (const WimaVCorridor& area); + void setJoinedArea (const WimaArea& area); private: bool _flyView; + bool _readyForSaveSend; PlanMasterController* _masterController; MissionController* _missionController; int _currentPolygonIndex; QString _currentFile; WimaDataContainer* _container; - QmlObjectListModel* _visualItems; - WimaArea* _joinedArea; - - + QmlObjectListModel _visualItems; + WimaArea _joinedArea; + WimaGOperationArea _opArea; + WimaServiceArea _serArea; + WimaVCorridor _corridor; }; diff --git a/src/Wima/WimaDataContainer.cc b/src/Wima/WimaDataContainer.cc index 1571cdec96b1dcf5d816c540771f557be3bacb9d..fed86faf5ffa42ca485776316a77d12df0a11e37 100644 --- a/src/Wima/WimaDataContainer.cc +++ b/src/Wima/WimaDataContainer.cc @@ -1,9 +1,47 @@ #include "WimaDataContainer.h" WimaDataContainer::WimaDataContainer(QObject *parent) - : QObject(parent) - , _visualItems(this) - , _joinedArea(this) + : QObject (parent) + , _joinedArea (this) + , _opArea (this) + , _serArea (this) + , _corridor (this) { } + +void WimaDataContainer::setJoinedArea(const WimaArea &joinedArea) +{ + if (_joinedArea.path() != joinedArea.path()) { + _joinedArea = joinedArea; + + emit joinedAreaChanged(_joinedArea); + } +} + +void WimaDataContainer::setOpArea(const WimaGOperationArea &opArea) +{ + if (_opArea.path() != opArea.path()) { + _opArea = opArea; + + emit opAreaChanged(_opArea); + } +} + +void WimaDataContainer::setSerArea(const WimaServiceArea &serArea) +{ + if (_serArea.path() != serArea.path()) { + _serArea = serArea; + + emit serAreaChanged(_serArea); + } +} + +void WimaDataContainer::setCorridor(const WimaVCorridor &corridor) +{ + if (_corridor.path() != corridor.path()) { + _corridor = corridor; + + emit corridorChanged(_corridor); + } +} diff --git a/src/Wima/WimaDataContainer.h b/src/Wima/WimaDataContainer.h index 8da2ec94426f4c7d7e57ef5a5d2dc51566562096..79dd1c87d546e6224eae01f95af682c97abe1002 100644 --- a/src/Wima/WimaDataContainer.h +++ b/src/Wima/WimaDataContainer.h @@ -6,6 +6,9 @@ #include "QmlObjectListModel.h" #include "WimaArea.h" +#include "WimaGOperationArea.h" +#include "WimaServiceArea.h" +#include "WimaVCorridor.h" class WimaDataContainer : public QObject { @@ -13,21 +16,29 @@ class WimaDataContainer : public QObject public: explicit WimaDataContainer(QObject *parent = nullptr); - QmlObjectListModel* visualItems (void) { return &_visualItems; } //use setVisualItems to modify list WimaArea joinedArea (void) { return _joinedArea; } + WimaGOperationArea opArea (void) { return _opArea; } + WimaServiceArea serArea (void) { return _serArea; } + WimaVCorridor corridor (void) { return _corridor; } - void setJoinedArea(const WimaArea& joinedArea); - void setVisualItems(const QmlObjectListModel& list); + void setJoinedArea (const WimaArea& joinedArea); + void setOpArea (const WimaGOperationArea& opArea); + void setSerArea (const WimaServiceArea& serArea); + void setCorridor (const WimaVCorridor& corridor); signals: - void joinedAreaChanged(); - void visualItemsChanged(); + void joinedAreaChanged (const WimaArea& area); + void opAreaChanged (const WimaGOperationArea& area); + void serAreaChanged (const WimaServiceArea& area); + void corridorChanged (const WimaVCorridor& area); public slots: private: - QmlObjectListModel _visualItems; WimaArea _joinedArea; + WimaGOperationArea _opArea; + WimaServiceArea _serArea; + WimaVCorridor _corridor; }; #endif // WIMADATACONTAINER_H diff --git a/src/Wima/WimaGOperationArea.cc b/src/Wima/WimaGOperationArea.cc index 0351e8fa74dd366b820b4fca24cafe525106887e..4824d6719beac6ed55358af0c2fd87c9732dee2d 100644 --- a/src/Wima/WimaGOperationArea.cc +++ b/src/Wima/WimaGOperationArea.cc @@ -8,69 +8,24 @@ const char* WimaGOperationArea::layerDistanceName = "LayerDistance const char* WimaGOperationArea::borderPolygonOffsetName = "BorderPolygonOffset"; const char* WimaGOperationArea::wimaGOperationAreaName = "Operation Area"; -WimaGOperationArea::WimaGOperationArea() - : WimaGOperationArea(nullptr) -{ - -} WimaGOperationArea::WimaGOperationArea(QObject *parent) : WimaArea (parent) - , _metaDataMap (FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/WimaGOperationArea.SettingsGroup.json"), this /* QObject parent */)) - , _bottomLayerAltitude (settingsGroup, _metaDataMap[bottomLayerAltitudeName]) - , _numberOfLayers (settingsGroup, _metaDataMap[numberOfLayersName]) - , _layerDistance (settingsGroup, _metaDataMap[layerDistanceName]) - , _borderPolygonOffset (settingsGroup, _metaDataMap[borderPolygonOffsetName]) - , _borderPolygon (new QGCMapPolygon(this)) { - this->setObjectName(wimaGOperationAreaName); - connect(this, &WimaGOperationArea::pathChanged, this, &WimaGOperationArea::recalcBorderPolygon); - connect(&_borderPolygonOffset, &SettingsFact::rawValueChanged, this, &WimaGOperationArea::recalcBorderPolygon); + init(); } -WimaGOperationArea::WimaGOperationArea(const WimaArea &other, QObject *parent) +WimaGOperationArea::WimaGOperationArea(const WimaGOperationArea &other, QObject *parent) : WimaArea(other, parent) - , _metaDataMap (FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/WimaGOperationArea.SettingsGroup.json"), this /* QObject parent */)) - , _bottomLayerAltitude (settingsGroup, _metaDataMap[bottomLayerAltitudeName]) - , _numberOfLayers (settingsGroup, _metaDataMap[numberOfLayersName]) - , _layerDistance (settingsGroup, _metaDataMap[layerDistanceName]) - , _borderPolygonOffset (settingsGroup, _metaDataMap[borderPolygonOffsetName]) - , _borderPolygon (new QGCMapPolygon(this)) { - this->setObjectName(wimaGOperationAreaName); - connect(this, &WimaGOperationArea::pathChanged, this, &WimaGOperationArea::recalcBorderPolygon); - connect(&_borderPolygonOffset, &SettingsFact::rawValueChanged, this, &WimaGOperationArea::recalcBorderPolygon); - } - -void WimaGOperationArea::addVehicle(WimaVehicle *vehicle) -{ - if(vehicle != nullptr){ - _wimaVehicle = vehicle; - emit vehicleChanged(); - } + init(); } -void WimaGOperationArea::removeVehicle(int vehicleIndex) +WimaGOperationArea &WimaGOperationArea::operator=(WimaGOperationArea other) { - if(vehicleIndex >= 0){ - _wimaVehicle = nullptr; - emit vehicleChanged(); - } -} + swap(*this, other); -void WimaGOperationArea::setVehicleCorridor(WimaVCorridor *corridor) -{ - if(corridor != nullptr){ - if (corridor != _vehicleCorridor){ - _vehicleCorridor = corridor; - emit vehicleCorridorChanged(_vehicleCorridor); - } - else { - qWarning("WimaGOperationArea::setVehicleCorridor(): new corridor equals old _vehicleCorridor!"); - } - }else{ - qWarning("WimaGOperationArea::setVehicleCorridor(): corridor == nullptr!"); - } + return *this; } void WimaGOperationArea::saveToJson(QJsonObject &json) @@ -122,77 +77,64 @@ bool WimaGOperationArea::loadFromJson(const QJsonObject &json, QString& errorStr } } -void WimaGOperationArea::recalcBorderPolygon() +void print(const WimaGOperationArea &area) { - //qWarning("WimaGOperationArea::recalcBorderPolygon() %f", _borderPolygonOffset.rawValue().toDouble()); - QGCMapPolygon polyCopy = this->toQGCPolygon(*this); - polyCopy.offset(_borderPolygonOffset.rawValue().toDouble()); - _borderPolygon.setPath(polyCopy.path()); - polyCopy.deleteLater(); - - emit borderPolygonChanged(); + QString message; + print(area, message); + qWarning() << message; } -/*void WimaGOperationArea::recalculatesubPolygons() +void print(const WimaGOperationArea &area, QString outputStr) { - int vehicleCount = _vehicleList->count(); - QScopedPointer> listQGCPoly(this->splitPolygonArea(vehicleCount)); - - int polyCount = listQGCPoly->size(); - _vehiclePolygons->clear(); - for(int i = 0; i < polyCount; i++){ - WimaVehicleMeasurementPolygon* subPoly = new WimaVehicleMeasurementPolygon(listQGCPoly->takeAt(i), this); - _vehiclePolygons->append(subPoly); + print(static_cast(area), outputStr); + outputStr.append(QString("Bottom Layer Altitude: %.3f\n").arg(area._bottomLayerAltitude.rawValue().toDouble())); + outputStr.append(QString("Number of Layers: %i\n").arg(area._numberOfLayers.rawValue().toInt())); + outputStr.append(QString("Layer Distance: %.3f\n").arg(area._layerDistance.rawValue().toDouble())); + outputStr.append(QString("Border Polygon Offset: %.3f\n").arg(area._borderPolygonOffset.rawValue().toDouble())); + + outputStr.append(QString("Border Polygon Coordinates\n").arg(area._borderPolygonOffset.rawValue().toDouble())); + for (int i = 0; i < area._borderPolygon.count(); i++) { + QGeoCoordinate coordinate = area._borderPolygon.vertexCoordinate(i); + outputStr.append(QString("%s\n").arg(coordinate.toString(QGeoCoordinate::Degrees))); } } -void WimaGOperationArea::removeAllVehicles() +void swap(WimaGOperationArea &area1, WimaGOperationArea &area2) { - int count = _vehicleList->count(); - - if(count > 0){ - do{ - _vehicleList->removeAt(0); - count--; - }while(count > 0); - - emit vehicleListChanged(); - } - + using std::swap; + + swap(area1._metaDataMap, area2._metaDataMap); + swap(area1._bottomLayerAltitude, area2._bottomLayerAltitude); + swap(area1._numberOfLayers, area2._numberOfLayers); + swap(area1._layerDistance, area2._layerDistance); + swap(area1._borderPolygonOffset, area2._borderPolygonOffset); + swap(area1._borderPolygon, area2._borderPolygon); } - -void WimaGOperationArea::addVehiclePolygon() +void WimaGOperationArea::recalcBorderPolygon() { - _vehiclePolygons->append(new WimaVehicleMeasurementPolygon(this)); + //qWarning("WimaGOperationArea::recalcBorderPolygon() %f", _borderPolygonOffset.rawValue().toDouble()); + QGCMapPolygon polyCopy = this->toQGCPolygon(*this); + polyCopy.offset(_borderPolygonOffset.rawValue().toDouble()); + _borderPolygon.setPath(polyCopy.path()); + polyCopy.deleteLater(); - emit vehiclePolygonsChanged(); + emit borderPolygonChanged(); } -void WimaGOperationArea::removeVehiclePolygon(int polygonIndex) +void WimaGOperationArea::init() { - if(polygonIndex >= 0 && polygonIndex < _vehiclePolygons->count()){ - _vehiclePolygons->removeAt(polygonIndex); - - emit vehiclePolygonsChanged(); - }else { - qWarning("Index out of bounds!"); - } -} -void WimaGOperationArea::removeVehiclePolygon(WimaVehicleMeasurementPolygon *wimaPolygon) -{ - if(wimaPolygon != nullptr){ - QObject* removedPolygon = _vehiclePolygons->removeOne(wimaPolygon); - if(removedPolygon){ - emit vehiclePolygonsChanged(); - }else { - qWarning("Polygon not inside polygon list."); - } - }else { - qWarning("Not a valid Polygon."); - } -}*/ + _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/WimaGOperationArea.SettingsGroup.json"), this /* QObject parent */); + _bottomLayerAltitude = SettingsFact(settingsGroup, _metaDataMap[bottomLayerAltitudeName], this /* QObject parent */); + _numberOfLayers = SettingsFact(settingsGroup, _metaDataMap[numberOfLayersName], this /* QObject parent */); + _layerDistance = SettingsFact(settingsGroup, _metaDataMap[layerDistanceName], this /* QObject parent */); + _borderPolygonOffset = SettingsFact(settingsGroup, _metaDataMap[borderPolygonOffsetName], this /* QObject parent */); + _borderPolygon = new QGCMapPolygon(this); + this->setObjectName(wimaGOperationAreaName); + connect(this, &WimaGOperationArea::pathChanged, this, &WimaGOperationArea::recalcBorderPolygon); + connect(&_borderPolygonOffset, &SettingsFact::rawValueChanged, this, &WimaGOperationArea::recalcBorderPolygon); +} diff --git a/src/Wima/WimaGOperationArea.h b/src/Wima/WimaGOperationArea.h index 91a7cbe2eaf534335754f29a6766f6adb2f24f7c..8fa301672f9f9486369b8e844cc029c2c5d72161 100644 --- a/src/Wima/WimaGOperationArea.h +++ b/src/Wima/WimaGOperationArea.h @@ -12,28 +12,18 @@ class WimaGOperationArea : public WimaArea { Q_OBJECT public: - WimaGOperationArea(); - WimaGOperationArea(QObject* parent); - WimaGOperationArea(const WimaArea& other, QObject* parent = nullptr); + WimaGOperationArea(QObject* parent = nullptr); + WimaGOperationArea(const WimaGOperationArea& other, QObject* parent = nullptr); + WimaGOperationArea& operator=(WimaGOperationArea other); Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitude CONSTANT) Q_PROPERTY(Fact* numberOfLayers READ numberOfLayers CONSTANT) Q_PROPERTY(Fact* layerDistance READ layerDistance CONSTANT) Q_PROPERTY(Fact* borderPolygonOffset READ borderPolygonOffset CONSTANT) - /*Q_PROPERTY(QmlObjectListModel* vehicleList READ vehicleList NOTIFY vehicleListChanged) - Q_PROPERTY(QmlObjectListModel* vehiclePolygons READ vehiclePolygons NOTIFY vehiclePolygonsChanged)*/ Q_PROPERTY(QGCMapPolygon* borderPolygon READ borderPolygon NOTIFY borderPolygonChanged) - Q_INVOKABLE void addVehicle (WimaVehicle *vehicle); - Q_INVOKABLE void removeVehicle (int vehicleIndex); - void setVehicleCorridor (WimaVCorridor* corridor); - /*Q_INVOKABLE void recalculatesubPolygons (); - Q_INVOKABLE void removeAllVehicles (); - Q_INVOKABLE void addVehiclePolygon (); - Q_INVOKABLE void removeVehiclePolygon (int polygonIndex); - Q_INVOKABLE void removeVehiclePolygon (WimaVehicleMeasurementPolygon *wimaPolygon);*/ - + void setVehicleCorridor (WimaVCorridor* corridor); // Overrides from WimaPolygon QString mapVisualQML (void) const { return "WimaGOperationAreaMapVisual.qml";} @@ -44,16 +34,18 @@ public: Fact* numberOfLayers (void) { return &_numberOfLayers;} Fact* layerDistance (void) { return &_layerDistance;} Fact* borderPolygonOffset (void) { return &_borderPolygonOffset;} - /*QmlObjectListModel* vehicleList (void) const { return _vehicleList;} - QmlObjectListModel* vehiclePolygons (void) const { return _vehiclePolygons;}*/ - WimaVCorridor* vehicleCorridor (void) { return _vehicleCorridor;} QGCMapPolygon* borderPolygon (void) { return &_borderPolygon;} // Member Methodes void saveToJson(QJsonObject& json); bool loadFromJson(const QJsonObject& json, QString &errorString); + // Friends + friend void swap(WimaGOperationArea& area1, WimaGOperationArea& area2); + friend void print(const WimaGOperationArea& area, QString outputStr); + friend void print(const WimaGOperationArea& area); + // Static Variables static const char* settingsGroup; static const char* bottomLayerAltitudeName; static const char* numberOfLayersName; @@ -77,6 +69,10 @@ private slots: private: + // Member Methodes + void init(); + + // Members QMap _metaDataMap; SettingsFact _bottomLayerAltitude; @@ -84,10 +80,6 @@ private: SettingsFact _layerDistance; SettingsFact _borderPolygonOffset; - - /*QmlObjectListModel* _vehicleList; - QmlObjectListModel* _vehiclePolygons;*/ - WimaVCorridor* _vehicleCorridor; QGCMapPolygon _borderPolygon; }; diff --git a/src/Wima/WimaServiceArea.cc b/src/Wima/WimaServiceArea.cc index e85860229fd4dcbd33a9ac84c57cdf53e577a8aa..7c5e216db2bf396d4a1188b7c80c119398e75089 100644 --- a/src/Wima/WimaServiceArea.cc +++ b/src/Wima/WimaServiceArea.cc @@ -2,22 +2,25 @@ const char* WimaServiceArea::wimaServiceAreaName = "Service Area"; -WimaServiceArea::WimaServiceArea() - : WimaServiceArea(nullptr) -{ -} WimaServiceArea::WimaServiceArea(QObject *parent) : WimaArea (parent) { - this->setObjectName(wimaServiceAreaName); + init(); } -WimaServiceArea::WimaServiceArea(const WimaArea &other, QObject *parent) +WimaServiceArea::WimaServiceArea(const WimaServiceArea &other, QObject *parent) : WimaArea (other, parent) { - this->setObjectName(wimaServiceAreaName); + init(); +} + +WimaServiceArea &WimaServiceArea::operator=(WimaServiceArea other) +{ + swap(*this, other); + + return *this; } void WimaServiceArea::setTakeOffPosition(const QGeoCoordinate &coordinate) @@ -36,18 +39,6 @@ void WimaServiceArea::setLandPosition(const QGeoCoordinate &coordinate) } } -void WimaServiceArea::setVehicleCorridor(WimaVCorridor &corridor) -{ - - if (&corridor != _vehicleCorridor){ - _vehicleCorridor = &corridor; - emit vehicleCorridorChanged(*_vehicleCorridor); - } - else { - qWarning("WimaServiceArea::setVehicleCorridor(): new corridor equals old _vehicleCorridor!"); - } -} - void WimaServiceArea::saveToJson(QJsonObject &json) { this->WimaArea::saveToJson(json); @@ -66,3 +57,30 @@ bool WimaServiceArea::loadFromJson(const QJsonObject &json, QString &errorString } } +void print(const WimaServiceArea &area) +{ + QString message; + print(area, message); + qWarning() << message; +} + +void print(const WimaServiceArea &area, QString &outputStr) +{ + print(static_cast(area), outputStr); + outputStr.append(QString("Takeoff Position: %s\n").arg(area._takeOffPosition.toString(QGeoCoordinate::Degrees))); + outputStr.append(QString("Land Position: %s\n").arg(area._landPosition.toString(QGeoCoordinate::Degrees))); +} + +void swap(WimaServiceArea &area1, WimaServiceArea &area2) +{ + using std::swap; + + swap(area1._takeOffPosition, area2._takeOffPosition); + swap(area1._landPosition, area2._landPosition); +} + +void WimaServiceArea::init() +{ + this->setObjectName(wimaServiceAreaName); +} + diff --git a/src/Wima/WimaServiceArea.h b/src/Wima/WimaServiceArea.h index 669bdfc02045dcae962fa78c2f027fe3502bdfa8..8512fe0a4265ffc715031422f9a0b463c8edfdc9 100644 --- a/src/Wima/WimaServiceArea.h +++ b/src/Wima/WimaServiceArea.h @@ -8,9 +8,9 @@ class WimaServiceArea : public WimaArea { Q_OBJECT public: - WimaServiceArea(); - WimaServiceArea(QObject* parent); - WimaServiceArea(const WimaArea& other, QObject* parent); + WimaServiceArea(QObject* parent = nullptr); + WimaServiceArea(const WimaServiceArea& other, QObject* parent); + WimaServiceArea& operator=(WimaServiceArea other); Q_PROPERTY(const QGeoCoordinate& takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged) Q_PROPERTY(const QGeoCoordinate& landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged) @@ -23,13 +23,11 @@ public: // Property acessors const QGeoCoordinate& takeOffPosition (void) const { return _takeOffPosition;} const QGeoCoordinate& landPosition (void) const { return _landPosition;} - WimaVCorridor *vehicleCorridor (void) const { return _vehicleCorridor;} // Property setters void setTakeOffPosition (const QGeoCoordinate& coordinate); void setLandPosition (const QGeoCoordinate& coordinate); - void setVehicleCorridor (WimaVCorridor& corridor); // Member Methodes void saveToJson(QJsonObject& json); @@ -38,13 +36,21 @@ public: // static Members static const char* wimaServiceAreaName; + // Friends + friend void swap(WimaServiceArea& area1, WimaServiceArea& area2); + friend void print(const WimaServiceArea& area, QString& outputStr); + friend void print(const WimaServiceArea& area); + signals: void takeOffPositionChanged (void); void landPositionChanged (void); void vehicleCorridorChanged (WimaVCorridor& corridor); private: + // Member Methodes + void init(); + + // Members QGeoCoordinate _takeOffPosition; QGeoCoordinate _landPosition; - WimaVCorridor* _vehicleCorridor; }; diff --git a/src/Wima/WimaVCorridor.cc b/src/Wima/WimaVCorridor.cc index f08b2fe5723f32ec23d7d239f8501b2b436e5234..45ed7c01020d090d1a21ae617983e83e1ef768ce 100644 --- a/src/Wima/WimaVCorridor.cc +++ b/src/Wima/WimaVCorridor.cc @@ -2,46 +2,25 @@ const char* WimaVCorridor::wimaVCorridorName = "Corridor"; -WimaVCorridor::WimaVCorridor() - : WimaVCorridor(nullptr) -{ -} WimaVCorridor::WimaVCorridor(QObject *parent) - : WimaArea (parent) - , _serviceArea (nullptr) - , _opArea (nullptr) + : WimaArea (parent) { - this->setObjectName(wimaVCorridorName); + init(); } -WimaVCorridor::WimaVCorridor(const WimaArea &other, QObject *parent) - : WimaArea (other, parent) - , _serviceArea (nullptr) - , _opArea (nullptr) +WimaVCorridor::WimaVCorridor(const WimaVCorridor &other, QObject *parent) + : WimaArea (other, parent) { - this->setObjectName(wimaVCorridorName); + init(); } -void WimaVCorridor::setServiceArea(WimaServiceArea &serviceArea) +WimaVCorridor &WimaVCorridor::operator=(WimaVCorridor other) { - if(&serviceArea != _serviceArea){ - _serviceArea = &serviceArea; - emit serviceAreaChanged(_serviceArea); - }else { - qWarning("WimaVCorridor::setServiceArea(): new serviceArea does not differ from old _serviceArea!"); - } -} + swap(*this, other); -void WimaVCorridor::setOpArea(WimaGOperationArea &opArea) -{ - if(&opArea != _opArea){ - _opArea = &opArea; - emit opAreaChanged(_opArea); - }else { - qWarning("WimaVCorridor::setOpArea(): new opArea does not differ from old _opArea!"); - } + return *this; } void WimaVCorridor::saveToJson(QJsonObject &json) @@ -61,3 +40,27 @@ bool WimaVCorridor::loadFromJson(const QJsonObject &json, QString &errorString) return false; } } + +void WimaVCorridor::init() +{ + this->setObjectName(wimaVCorridorName); +} + +void print(const WimaVCorridor &area) +{ + QString message; + print(area, message); + qWarning() << message; +} + +void print(const WimaVCorridor &area, QString &outputString) +{ + print(static_cast(area), outputString); +} + +void swap(WimaVCorridor &area1, WimaVCorridor &area2) +{ + using std::swap; + + swap(static_cast(area1), static_cast(area2)); +} diff --git a/src/Wima/WimaVCorridor.h b/src/Wima/WimaVCorridor.h index 8dfbea9272c979a839df012c630e17abda8dd16e..2239385e65e5ac4b7d4d717477209d38ca9833c2 100644 --- a/src/Wima/WimaVCorridor.h +++ b/src/Wima/WimaVCorridor.h @@ -9,32 +9,33 @@ class WimaVCorridor : public WimaArea { Q_OBJECT public: - WimaVCorridor(); - WimaVCorridor(QObject* parent); - WimaVCorridor(const WimaArea& other, QObject* parent); + WimaVCorridor(QObject* parent = nullptr); + WimaVCorridor(const WimaVCorridor& other, QObject* parent = nullptr); + WimaVCorridor& operator=(WimaVCorridor other); // Overrides from WimaPolygon QString mapVisualQML (void) const { return "WimaVCorridorMapVisual.qml";} QString editorQML (void) const { return "WimaVCorridorEditor.qml";} // Methodes - void setServiceArea (WimaServiceArea& serviceArea); - void setOpArea (WimaGOperationArea& opArea); - WimaServiceArea* serviceArea (void) const {return _serviceArea;} - WimaGOperationArea* opArea (void) const {return _opArea;} void saveToJson (QJsonObject& json); bool loadFromJson (const QJsonObject& json, QString& errorString); // static Members static const char* wimaVCorridorName; + // Friends + friend void swap(WimaVCorridor& area1, WimaVCorridor& area2); + friend void print(const WimaVCorridor& area, QString& outputString); + friend void print(const WimaVCorridor& area); + signals: void serviceAreaChanged (WimaServiceArea* serviceArea); void opAreaChanged (WimaGOperationArea* opArea); private: - WimaServiceArea* _serviceArea; - WimaGOperationArea* _opArea; + void init(); }; +