diff --git a/WimaGlobalMeasurementPolygonEditor.qml b/WimaGlobalMeasurementPolygonEditor.qml deleted file mode 100644 index 9c36e13c5bfc938decd97e1b1eba471841e202c1..0000000000000000000000000000000000000000 --- a/WimaGlobalMeasurementPolygonEditor.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Item { - -} diff --git a/android.pri b/android.pri index f655709bc50e8b137bf808938fba18a5bc075f6c..9b80ceb8ff7840c69cff5940c04162bf6e197388 100644 --- a/android.pri +++ b/android.pri @@ -25,3 +25,7 @@ DISTFILES += \ $$PWD/android/build.gradle \ $$PWD/android/gradle/wrapper/gradle-wrapper.properties \ $$PWD/android/gradlew.bat + +HEADERS += \ + +SOURCES += \ diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index c3978a241e37e04e41888be8ae7916180db067a1..b0040dae27dc38021a605234542088e545c7eac8 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -407,29 +407,26 @@ HEADERS += \ src/api/QmlComponentInfo.h \ src/comm/MavlinkMessagesTimer.h \ src/GPS/Drivers/src/base_station.h \ - src/MissionManager/WimaController.h \ - src/MissionManager/WimaPolygon.h \ - src/MissionManager/WimaServicePolygon.h \ - src/MissionManager/WimaVehicleCorridor.h \ - src/MissionManager/WimaVehicleMeasurementPolygon.h \ - src/MissionManager/WimaGlobalMeasurementPolygon.h \ - src/MissionManager/WimaVehicle.h \ - src/MissionManager/WimaPolyline.h - + src/Wima/WimaArea.h \ + src/Wima/WimaGOperationArea.h \ + src/Wima/WimaServiceArea.h \ + src/Wima/WimaVCorridor.h \ + src/Wima/WimaTrackerPolyline.h \ + src/Wima/WimaController.h \ + src/Wima/WimaVehicle.h SOURCES += \ src/api/QGCCorePlugin.cc \ src/api/QGCOptions.cc \ src/api/QGCSettings.cc \ src/api/QmlComponentInfo.cc \ src/comm/MavlinkMessagesTimer.cc \ - src/MissionManager/WimaController.cc \ - src/MissionManager/WimaPolygon.cc \ - src/MissionManager/WimaServicePolygon.cc \ - src/MissionManager/WimaVehicleCorridor.cc \ - src/MissionManager/WimaVehicleMeasurementPolygon.cc \ - src/MissionManager/WimaGlobalMeasurementPolygon.cc \ - src/MissionManager/WimaVehicle.cc \ - src/MissionManager/WimaPolyline.cc + src/Wima/WimaArea.cc \ + src/Wima/WimaGOperationArea.cc \ + src/Wima/WimaServiceArea.cc \ + src/Wima/WimaVCorridor.cc \ + src/Wima/WimaTrackerPolyline.cc \ + src/Wima/WimaController.cc \ + src/Wima/WimaVehicle.cc # # Unit Test specific configuration goes here (requires full debug build with all plugins) @@ -1311,4 +1308,4 @@ contains (CONFIG, QGC_DISABLE_INSTALLER_SETUP) { } DISTFILES += \ - src/MissionManager/WimaGlobalMeasurementPolygon.SettingsGroup.json + src/Wima/WimaGOperationArea.SettingsGroup.json diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 40a4efee8677e8323abda2234b7e30d1b8e123f3..fc85d1a6eef961ffefdf9bf730ba02ad9f2bb944 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -211,10 +211,13 @@ src/WimaView/WimaToolBar.qml src/WimaView/WimaView.qml src/WimaView/WimaMapVisual.qml - src/WimaView/WimaGlobalMeasurementPolygonMapVisual.qml src/WimaView/WimaServicePolygonMapVisual.qml src/WimaView/WimaItemEditor.qml - WimaGlobalMeasurementPolygonEditor.qml + src/WimaView/WimaMapPolylineVisuals.qml + src/WimaView/WimaMapPolygonVisuals.qml + src/WimaView/WimaGOperationAreaMapVisual.qml + src/WimaView/WimaServiceAreaMapVisual.qml + src/WimaView/WimaGOperationAreaEditor.qml src/Settings/APMMavlinkStreamRate.SettingsGroup.json @@ -259,7 +262,7 @@ src/Vehicle/VibrationFact.json src/Vehicle/WindFact.json src/Settings/Video.SettingsGroup.json - src/MissionManager/WimaGlobalMeasurementPolygon.SettingsGroup.json + src/Wima/WimaGOperationArea.SettingsGroup.json src/comm/APMArduCopterMockLink.params diff --git a/src/MissionManager/WimaController.h b/src/MissionManager/WimaController.h deleted file mode 100644 index 6f2bb0d2855762d83c660d75bbba5c3c130ba4d4..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaController.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include -#include "QGCMapPolygon.h" -#include "QmlObjectListModel.h" - -#include "WimaPolygon.h" -#include "WimaGlobalMeasurementPolygon.h" -#include "WimaServicePolygon.h" - -#include "PlanMasterController.h" -#include "MissionController.h" - - -class WimaController : public QObject -{ - Q_OBJECT -public: - WimaController(QObject *parent = nullptr); - - - 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(int currentPolygonIndex READ currentPolygonIndex WRITE setCurrentPolygonIndex NOTIFY currentPolygonIndexChanged) - - - // Property accessors - PlanMasterController* masterController (void) const { return _masterController;} - MissionController* missionController (void) const { return _missionController;} - QmlObjectListModel* visualItems (void) { return _visualItems; } - int currentPolygonIndex (void) const { return _currentPolygonIndex; } - - - - - // Property setters - void setMasterController (PlanMasterController* masterController); - void setMissionController (MissionController* missionController); - void setCurrentPolygonIndex (int index); - - Q_INVOKABLE void addGlobalMeasurementArea(); - Q_INVOKABLE void removeArea(int index); - Q_INVOKABLE void addServiceArea(); - - Q_INVOKABLE void startMission(); - Q_INVOKABLE void abortMission(); - Q_INVOKABLE void pauseMission(); - Q_INVOKABLE void resumeMission(); - - Q_INVOKABLE void saveMission(); - Q_INVOKABLE void loadMission(); - - Q_INVOKABLE void resetAllIsCurrentPolygon(void); - - - -signals: - void masterControllerChanged (void); - void missionControllerChanged (void); - void visualItemsChanged (void); - void currentPolygonIndexChanged (int index); - -private slots: - void recalcVehicleCorridor(); - void recalcVehicleMeasurementAreas(); - void recalcAll(); - void recalcPolygonInteractivity(int index); - - -private: - bool _planView; - QmlObjectListModel* _visualItems; - PlanMasterController* _masterController; - MissionController* _missionController; - int _currentPolygonIndex; - -}; diff --git a/src/MissionManager/WimaGlobalMeasurementPolygon.SettingsGroup.json b/src/MissionManager/WimaGlobalMeasurementPolygon.SettingsGroup.json deleted file mode 100644 index b6f5d25f3ee58e94c47a93c79d1c1ed03af2ab08..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaGlobalMeasurementPolygon.SettingsGroup.json +++ /dev/null @@ -1,27 +0,0 @@ -[ -{ - "name": "BottomLayerAltitude", - "shortDescription": "Altitude of the bottom layer.", - "type": "double", - "units": "m", - "min": 1, - "decimalPlaces": 2, - "defaultValue": 5 -}, -{ - "name": "NumberOfLayers", - "shortDescription": "The number of layers", - "type": "uint32", - "min": 1, - "defaultValue": 1 -}, -{ - "name": "LayerDistance", - "shortDescription": "The distance between to adjacent layers.", - "type": "double", - "units": "m", - "min": 0, - "decimalPlaces": 2, - "defaultValue": 1 -} -] diff --git a/src/MissionManager/WimaGlobalMeasurementPolygon.h b/src/MissionManager/WimaGlobalMeasurementPolygon.h deleted file mode 100644 index dcf372362d9b1c9d79c4962ef0f7ea5575a3aa6b..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaGlobalMeasurementPolygon.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include -#include "WimaPolygon.h" -#include "QGCMapPolyline.h" -#include "QGCMapPolygon.h" -#include "WimaVehicleMeasurementPolygon.h" -#include "SettingsFact.h" - -#include "QScopedPointer" - -class WimaGlobalMeasurementPolygon : public WimaPolygon -{ - Q_OBJECT -public: - WimaGlobalMeasurementPolygon(QObject* parent); - WimaGlobalMeasurementPolygon(QGCMapPolygon* other, QObject* parent); - - Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitude CONSTANT) - Q_PROPERTY(Fact* numberOfLayers READ numberOfLayers CONSTANT) - Q_PROPERTY(Fact* layerDistance READ layerDistance CONSTANT) - Q_PROPERTY(QmlObjectListModel* vehicleList READ vehicleList NOTIFY vehicleListChanged) - Q_PROPERTY(QmlObjectListModel* vehiclePolygons READ vehiclePolygons NOTIFY vehiclePolygonsChanged) - Q_PROPERTY(WimaPolyline* polyline READ polyline NOTIFY polylineChanged) - - - Q_INVOKABLE void addVehicle (Vehicle *vehicle); - Q_INVOKABLE void removeVehicle (int vehicleIndex); - Q_INVOKABLE void recalculatesubPolygons (); - Q_INVOKABLE void removeAllVehicles (); - Q_INVOKABLE void addVehiclePolygon (); - Q_INVOKABLE void removeVehiclePolygon (int polygonIndex); - Q_INVOKABLE void removeVehiclePolygon (WimaVehicleMeasurementPolygon *wimaPolygon); - - - // Overrides from WimaPolygon - QString mapVisualQML (void) const { return "WimaGlobalMeasurementPolygonMapVisual.qml";} - QString editorQML (void) const { return "WimaGlobalMeasurementPolygonEditor.qml";} - - // Property accessors - Fact* bottomLayerAltitude (void) { return &_bottomLayerAltitude;} - Fact* numberOfLayers (void) { return &_numberOfLayers;} - Fact* layerDistance (void) { return &_layerDistance;} - QmlObjectListModel* vehicleList (void) const { return _vehicleList;} - QmlObjectListModel* vehiclePolygons (void) const { return _vehiclePolygons;} - WimaPolyline* polyline (void) { return &_polyline;} - - - static const char* settingsGroup; - static const char* bottomLayerAltitudeName; - static const char* numberOfLayersName; - static const char* layerDistanceName; - - -signals: - void bottomLayerAltitudeChanged (void); - void numberOfLayersChanged (void); - void layerDistanceChanged (void); - void vehicleListChanged (void); - void gatewayPolylinesChanged (void); - void vehiclePolygonsChanged (void); - - -private: - QMap _metaDataMap; - - SettingsFact _bottomLayerAltitude; - SettingsFact _numberOfLayers; - SettingsFact _layerDistance; - - - QmlObjectListModel* _vehicleList; - QmlObjectListModel* _vehiclePolygons; - WimaPolyline _polyline; - - - -}; - - diff --git a/src/MissionManager/WimaPolygon.cc b/src/MissionManager/WimaPolygon.cc deleted file mode 100644 index de3ebb22ce0433e9085524fae68d0d6e872d9b82..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaPolygon.cc +++ /dev/null @@ -1,67 +0,0 @@ -#include "WimaPolygon.h" - -WimaPolygon::WimaPolygon(QObject *parent) : - QObject (parent) - ,_maxAltitude (30) - ,_vehicle (parent) - ,_polygon (new QGCMapPolygon(this)) -{ - connect(_polygon, &QGCMapPolygon::interactiveChanged, this, &WimaPolygon::interactiveChanged); - connect(_polygon, &QGCMapPolygon::countChanged, this, &WimaPolygon::countChanged); -} - -WimaPolygon::WimaPolygon(QGCMapPolygon *other, QObject *parent): - WimaPolygon(parent) -{ - *_polygon = *other; - connect(_polygon, &QGCMapPolygon::interactiveChanged, this, &WimaPolygon::interactiveChanged); - connect(_polygon, &QGCMapPolygon::countChanged, this, &WimaPolygon::countChanged); -} - -WimaPolygon::~WimaPolygon() -{ - -} - - -void WimaPolygon::setMaxAltitude(double alt) -{ - if(alt > 0 && alt != _maxAltitude){ - _maxAltitude = alt; - emit maxAltitudeChanged(); - } -} - - -void WimaPolygon::setVehicle(Vehicle *vehicle) -{ - if(_vehicle.vehicle() != vehicle){ - _vehicle.setVehicle(vehicle); - emit vehicleChanged(); - } -} - - -void WimaPolygon::setInteractive(bool interactive) -{ - _polygon->setInteractive(interactive); -} - -QList *WimaPolygon::splitPolygonArea(QGCMapPolygon *polygonToSplitt, int numberOfFractions) -{ - if(numberOfFractions > 0 && polygonToSplitt != nullptr){ - QGCMapPolygon* poly = new QGCMapPolygon(polygonToSplitt, this); - QList* list = new QList(); - list->append(poly); - return list; - } - return nullptr; -} - - -QList* WimaPolygon::splitPolygonArea(int numberOfFractions) -{ - return splitPolygonArea(_polygon, numberOfFractions); -} - - diff --git a/src/MissionManager/WimaPolygon.h b/src/MissionManager/WimaPolygon.h deleted file mode 100644 index a898122ae9a54b0b5e57e33dbc9bd67f4451efa8..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaPolygon.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - - -#include "QGCMapPolygon.h" -#include "QGCMapPolyline.h" -#include "Vehicle.h" -#include "qobject.h" -#include "WimaVehicle.h" -#include "WimaPolyline.h" - - - - - -class WimaPolygon : public QObject //abstract base class for all WimaPolygons -{ - Q_OBJECT -public: - WimaPolygon(QObject* parent = nullptr); - WimaPolygon(QGCMapPolygon* other, QObject* parent = nullptr); - ~WimaPolygon(); - - - - 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(Vehicle* vehicle READ vehicle WRITE setVehicle NOTIFY vehicleChanged) - Q_PROPERTY(QGCMapPolygon* polygon READ polygon NOTIFY polygonChanged) - Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged) - Q_PROPERTY(int count READ count NOTIFY countChanged) - - //Property accessors - double maxAltitude (void) const { return _maxAltitude;} - Vehicle* vehicle (void) const { return _vehicle.vehicle();} - QGCMapPolygon* polygon (void) const { return _polygon;} - bool interactive (void) const { return _polygon->interactive();} - int count (void) const { return _polygon->count();} - - virtual QString mapVisualQML (void) const = 0; - virtual QString editorQML (void) const = 0; - - - //Property setters - void setMaxAltitude (double alt); - void setVehicle (Vehicle* vehicle); - void setInteractive (bool interactive); - - - // Member Methodes - QList* splitPolygonArea(QGCMapPolygon *polygonToSplitt, int numberOfFractions); // use QScopedPointer to store return value - QList* splitPolygonArea(int numberOfFractions); // use QScopedPointer to store return value - - - - -signals: - void maxAltitudeChanged (void); - void vehicleChanged (void); - void polygonChanged (void); - void interactiveChanged (void); - void polylineChanged (void); - void countChanged (void); - - -protected: - double _maxAltitude; - WimaVehicle _vehicle; - QGCMapPolygon* _polygon; -}; - - diff --git a/src/MissionManager/WimaPolygonContainer.cc b/src/MissionManager/WimaPolygonContainer.cc deleted file mode 100644 index 689efa1809fb3667d60326e2d5826ef42ce52cd8..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaPolygonContainer.cc +++ /dev/null @@ -1,75 +0,0 @@ -#include "WimaPolygonContainer.h" - -WimaPolygonContainer::WimaPolygonContainer(QObject *parent) : - QObject (parent) - ,_flatListDirty (true) -{ - connect(this, &WimaPolygonContainer::itemListChanged, this, &WimaPolygonContainer::setFlatListDirty); -} - -QList &WimaPolygonContainer::returnItems() -{ - return _itemList; -} - -void WimaPolygonContainer::addItem(WimaPolygon *polygon) -{ - if(polygon != nullptr){ - _itemList.append(polygon); - - emit itemListChanged(); - } - else { - qWarning("Not a valid WimaPolygon!"); - } -} - -void WimaPolygonContainer::removeItem(int itemIndex) -{ - if(itemIndex >= 0 && itemIndex < _itemList.count()){ - _itemList.removeAt(itemIndex); - - emit itemListChanged(); - }else { - qWarning("Invalid item Index. Index must be in 0..%i.", _itemList.count()-1); - } -} - -void WimaPolygonContainer::removeItem(WimaPolygon *polygon) -{ - if(polygon != nullptr){ - _itemList.removeOne(polygon); - - emit itemListChanged(); - } - else { - qWarning("Not a valid WimaPolygon!"); - } -} - -QList& WimaPolygonContainer::returnFlatList() -{ - if(_flatListDirty){ - _flatList.clear(); - - int count = _itemList.count(); - for(int i = 0; i < count; i++){ - WimaPolygon* poly = _itemList.takeAt(i); - _flatList.append(poly); - _flatList.append(poly->subPolygons()); // returns an emptey list, if no sub polygons exist - } - _flatListDirty = false; - } - - return _flatList; -} - -int WimaPolygonContainer::count() -{ - return _itemList.size(); -} - -void WimaPolygonContainer::setFlatListDirty(void) -{ - _flatListDirty = true; -} diff --git a/src/MissionManager/WimaPolygonContainer.h b/src/MissionManager/WimaPolygonContainer.h deleted file mode 100644 index 781957e86feff5846f1d0486dd7175bcbd7e9372..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaPolygonContainer.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef WIMAPOLYGONCONTAINER_H -#define WIMAPOLYGONCONTAINER_H - -#include -#include "WimaPolygon.h" - -class WimaPolygonContainer : public QObject -{ - Q_OBJECT -public: - WimaPolygonContainer(QObject *parent = nullptr); - - - QList& returnItems(); - - void addItem(WimaPolygon* polygon); - void removeItem(int itemIndex); - void removeItem(WimaPolygon* polygon); - QList& returnFlatList(); - int count(void); - -signals: - void itemListChanged(void); - -private slots: - void setFlatListDirty(void); - -private: - QList _itemList; - QList _flatList; - bool _flatListDirty; -}; - -#endif // WIMAPOLYGONCONTAINER_H diff --git a/src/MissionManager/WimaPolyline.cc b/src/MissionManager/WimaPolyline.cc deleted file mode 100644 index 8c09f8a80e2bd2d3311f56172dd358cfa29e7f2a..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaPolyline.cc +++ /dev/null @@ -1,97 +0,0 @@ -#include "WimaPolyline.h" - -WimaPolyline::WimaPolyline(QObject *parent) - : QObject (parent) - , _boundPolygon (nullptr) - , _startVertexIndex(0) - , _endVertexIndex(1) -{ - connect(&_polyline, &QGCMapPolyline::interactiveChanged, this, &WimaPolyline::interactiveChanged); -} - -WimaPolyline::WimaPolyline(QGCMapPolyline *polyline, QObject *parent) - :WimaPolyline(parent) -{ - _polyline = *polyline; -} - -void WimaPolyline::bindPolygon(QGCMapPolygon *polygon) -{ - if(polygon != nullptr){ - _boundPolygon = polygon; - connect(polygon, &QGCMapPolygon::pathChanged, this, &WimaPolyline::recalcPolyline); - }else{ - qWarning("Invalid Object!"); - } -} - -void WimaPolyline::unbindPolygon() -{ - if(_boundPolygon != nullptr){ - disconnect(_boundPolygon, &QGCMapPolygon::pathChanged, this, &WimaPolyline::recalcPolyline); - _boundPolygon = nullptr; - }else{ - qWarning("No Object bound!"); - } -} - -void WimaPolyline::swapLimits() -{ - int storage = _startVertexIndex; - _startVertexIndex = _endVertexIndex; - _endVertexIndex = storage; -} - -void WimaPolyline::setInteractive(bool interactive) -{ - _polyline.setInteractive(interactive); -} -void WimaPolyline::setStartVertexIndex(int PolygonVertexIndex) -{ - if(PolygonVertexIndex >= 0 && PolygonVertexIndex < _boundPolygon->count()){ - _startVertexIndex = PolygonVertexIndex; - recalcPolyline(); - }else{ - qWarning("Index out of bounds!"); - } -} - -void WimaPolyline::setEndVertexIndex(int PolygonVertexIndex) -{ - if(PolygonVertexIndex >= 0 && PolygonVertexIndex < _boundPolygon->count()){ - _endVertexIndex = PolygonVertexIndex; - recalcPolyline(); - }else{ - qWarning("Index out of bounds!"); - } -} - -void WimaPolyline::recalcPolyline() -{ - if (_boundPolygon != nullptr && _boundPolygon->count() > 0){ - if (_startVertexIndex >= _boundPolygon->count()){ - _startVertexIndex = 0; - } - if (_endVertexIndex >= _boundPolygon->count()){ - _startVertexIndex = _boundPolygon->count()-1; - } - - _polyline.clear(); - int i = _startVertexIndex; - while(1){ - _polyline.appendVertex(_boundPolygon->vertexCoordinate(i)); - if (i == _boundPolygon->count()-1){ - i = 0; - }else if (i == _endVertexIndex) { - break; - } - i++; - } - - emit polylineChanged(); - }else{ - qWarning("No object bound!"); - } -} - - diff --git a/src/MissionManager/WimaPolyline.h b/src/MissionManager/WimaPolyline.h deleted file mode 100644 index 819a99d20371277c210cb125f8f76dbc24563407..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaPolyline.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef WIMAPOLYLINE_H -#define WIMAPOLYLINE_H - -#include -#include "QGCMapPolyline.h" -#include "QGCMapPolygon.h" - -class WimaPolyline : public QObject -{ - Q_OBJECT -public: - WimaPolyline(QObject *parent = nullptr); - WimaPolyline(QGCMapPolyline *polyline, QObject *parent = nullptr); - - Q_PROPERTY(QGCMapPolyline const* polyline READ polyline NOTIFY polylineChanged) - Q_PROPERTY(int startVertexIndex READ startVertexIndex WRITE setStartVertexIndex NOTIFY startVertexIndexChanged) - Q_PROPERTY(int endVertexIndex READ endVertexIndex WRITE setEndVertexIndex NOTIFY endVertexIndexChanged) - Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged) - - // Property accessors - QGCMapPolyline const* polyline (void) const { return &_polyline;} - int startVertexIndex (void) const { return _startVertexIndex;} - int endVertexIndex (void) const { return _endVertexIndex;} - bool interactive (void) const { return _polyline.interactive();} - - - //Property setters - Q_INVOKABLE void bindPolygon (QGCMapPolygon* polygon); - Q_INVOKABLE void unbindPolygon (); - Q_INVOKABLE void swapLimits (); - Q_INVOKABLE void setInteractive (bool interactive); - void setStartVertexIndex (int PolygonVertexIndex); - void setEndVertexIndex (int PolygonVertexIndex); - - - - - -signals: - void polylineChanged (void); - void startVertexIndexChanged (void); - void endVertexIndexChanged (void); - void interactiveChanged (void); - -public slots: - void recalcPolyline(void); - -private: - QGCMapPolyline _polyline; - QGCMapPolygon* _boundPolygon; - int _startVertexIndex; - int _endVertexIndex; - -}; - -#endif // WIMAPOLYLINE_H diff --git a/src/MissionManager/WimaServicePolygon.cc b/src/MissionManager/WimaServicePolygon.cc deleted file mode 100644 index 213a128e97a1b14d2d1a7c8da36b4cb666abbb3a..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaServicePolygon.cc +++ /dev/null @@ -1,30 +0,0 @@ -#include "WimaServicePolygon.h" - -WimaServicePolygon::WimaServicePolygon(QObject *parent): - WimaPolygon (parent) -{ - this->setObjectName("Service Area"); -} - -WimaServicePolygon::WimaServicePolygon(QGCMapPolygon *other, QObject *parent): - WimaPolygon (other, parent) -{ - -} - -void WimaServicePolygon::setTakeOffPosition(QGeoCoordinate* coordinate) -{ - if(_takeOffPosition != *coordinate){ - _takeOffPosition = *coordinate; - emit takeOffPositionChanged(); - } -} - -void WimaServicePolygon::setLandPosition(QGeoCoordinate* coordinate) -{ - if(_landPosition != *coordinate){ - _landPosition = *coordinate; - emit landPositionChanged(); - } -} - diff --git a/src/MissionManager/WimaServicePolygon.h b/src/MissionManager/WimaServicePolygon.h deleted file mode 100644 index f4dc3713492e50b202b38c5ac9ec24085afa5789..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaServicePolygon.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include "WimaPolygon.h" - -class WimaServicePolygon : public WimaPolygon -{ - Q_OBJECT -public: - WimaServicePolygon(QObject* parent = nullptr); - WimaServicePolygon(QGCMapPolygon* other, QObject* parent = nullptr); - - Q_PROPERTY(QGeoCoordinate* takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged) - Q_PROPERTY(QGeoCoordinate* landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged) - - // Overrides from WimaPolygon - QString mapVisualQML (void) const { return "WimaServicePolygonMapVisual.qml";} - QString editorQML (void) const { return "WimaServicePolygonEditor.qml";} - - // Property acessors - QGeoCoordinate* takeOffPosition (void) { return &_takeOffPosition;} - QGeoCoordinate* landPosition (void) { return &_landPosition;} - - // Property setters - void setTakeOffPosition (QGeoCoordinate* coordinate); - void setLandPosition (QGeoCoordinate* coordinate); - -signals: - void takeOffPositionChanged (void); - void landPositionChanged (void); -private: - QGeoCoordinate _takeOffPosition; - QGeoCoordinate _landPosition; -}; - diff --git a/src/MissionManager/WimaVehicle.cc b/src/MissionManager/WimaVehicle.cc deleted file mode 100644 index 06f0eaddd16cfec4a7685fec852ddb3041c16706..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaVehicle.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include "WimaVehicle.h" - - - -WimaVehicle::WimaVehicle(QObject *parent): - QObject (parent) - ,_vehicle (nullptr) - ,_servicePolygon (nullptr) - ,_vehicleCorridor (nullptr) - ,_measurementPolygon (nullptr) -{ - -} - -void WimaVehicle::setVehicle(Vehicle *vehicle) -{ - if(vehicle != nullptr){ - _vehicle = vehicle; - }else { - qWarning("Not a valid vehicle!"); - } -} - -void WimaVehicle::setServicePolygon(WimaServicePolygon *servicePolygon) -{ - if(servicePolygon != nullptr){ - _servicePolygon = servicePolygon; - }else{ - qWarning("Not a valid service Polygon!"); - } -} - -void WimaVehicle::setVehicleCorridor(WimaVehicleCorridor *vehicleCorridor) -{ - if(vehicleCorridor != nullptr){ - _vehicleCorridor = vehicleCorridor; - }else{ - qWarning("Not a valid vehicle Corridor!"); - } -} - -void WimaVehicle::setMeasurementPolygon(WimaVehicleMeasurementPolygon *measurementPolygon) -{ - if(measurementPolygon != nullptr){ - _measurementPolygon = measurementPolygon; - }else{ - qWarning("Not a valid measurementPolygon!"); - } -} diff --git a/src/MissionManager/WimaVehicleCorridor.cc b/src/MissionManager/WimaVehicleCorridor.cc deleted file mode 100644 index d91cdf3071a318ac701ac681cd6c9608c48d9c16..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaVehicleCorridor.cc +++ /dev/null @@ -1,13 +0,0 @@ -#include "WimaVehicleCorridor.h" - -WimaVehicleCorridor::WimaVehicleCorridor(QObject *parent): - WimaPolygon(parent) -{ - this->setObjectName("Corridor"); -} - -WimaVehicleCorridor::WimaVehicleCorridor(QGCMapPolygon *other, QObject *parent): - WimaPolygon (other, parent) -{ - -} diff --git a/src/MissionManager/WimaVehicleCorridor.h b/src/MissionManager/WimaVehicleCorridor.h deleted file mode 100644 index 2dc06b7649f9897206cf57be6328b839ee0e54b7..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaVehicleCorridor.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include "WimaPolygon.h" - -class WimaVehicleCorridor : public WimaPolygon -{ - Q_OBJECT -public: - WimaVehicleCorridor(QObject* parent); - WimaVehicleCorridor(QGCMapPolygon* other, QObject* parent); - - // Overrides from WimaPolygon - QString mapVisualQML (void) const { return "WimaVehicleCorridorMapVisual.qml";} - QString editorQML (void) const { return "WimaVehicleCorridorEditor.qml";} -}; - diff --git a/src/MissionManager/WimaVehicleMeasurementPolygon.cc b/src/MissionManager/WimaVehicleMeasurementPolygon.cc deleted file mode 100644 index fa6b6ca694bc731ba424b8bfe92f6b47b40a8b9c..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaVehicleMeasurementPolygon.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include "WimaVehicleMeasurementPolygon.h" - - -WimaVehicleMeasurementPolygon::WimaVehicleMeasurementPolygon(QObject *parent): - WimaPolygon (parent) -{ - this->setObjectName("Vehicle Area"); -} - -WimaVehicleMeasurementPolygon::WimaVehicleMeasurementPolygon(QGCMapPolygon *other, QObject *parent): - WimaPolygon (other, parent) -{ - -} diff --git a/src/MissionManager/WimaVehicleMeasurementPolygon.h b/src/MissionManager/WimaVehicleMeasurementPolygon.h deleted file mode 100644 index 8aa63d6d10f4b35c2f4e2b83b301b1344508bcd9..0000000000000000000000000000000000000000 --- a/src/MissionManager/WimaVehicleMeasurementPolygon.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include "WimaPolygon.h" - -class WimaVehicleMeasurementPolygon : public WimaPolygon -{ - Q_OBJECT -public: - WimaVehicleMeasurementPolygon(QObject* parent); - WimaVehicleMeasurementPolygon(QGCMapPolygon* other, QObject* parent); - - // Overrides from WimaPolygon - QString mapVisualQML (void) const { return "WimaVehicleMeasurementPolygonMapVisual.qml";} - QString editorQML (void) const { return "WimaVehicleMeasurementPolygonEditor.qml";} -}; - - diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 088426583514be0255801fd718dc1a48dbd18e82..fce8b868b329011c9b594597840ccb2e5f45d23e 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -67,7 +67,7 @@ #include "FlightMapSettings.h" #include "CoordinateVector.h" #include "PlanMasterController.h" -#include "WimaController.h" //custom +#include "Wima/WimaController.h" //custom #include "VideoManager.h" #include "VideoSurface.h" #include "VideoReceiver.h" diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index a24a43a873a4aa62b0717bf29ddebf34db97f7d2..f4e1323cde04607fd5181c4b95610174be881fd4 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -85,7 +85,10 @@ VehicleSummaryRow 1.0 VehicleSummaryRow.qml ViewWidget 1.0 ViewWidget.qml FlyAreaItemEditor 1.0 FlyAreaItemEditor.qml -WimaMapVisual 1.0 WimaMapVisual.qml -WimaGlobalMeasurementPolygonMapVisual 1.0 WimaGlobalMeasurementPolygonMapVisual.qml -WimaServicePolygonMapVisual 1.0 WimaServicePolygonMapVisual.qml -WimaItemEditor 1.0 WimaItemEditor.qml +WimaMapVisual 1.0 WimaMapVisual.qml +WimaGOperationAreaMapVisual 1.0 WimaGOperationAreaMapVisual.qml +WimaGOperationAreaEditor 1.0 WimaGOperationAreaEditor.qml +WimaServiceAreaMapVisual 1.0 WimaServiceAreaMapVisual.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 e0a0f97e39aa4552574a4e6f7e003bfe5aeea570..3632a4eaaad9822435a7a61a46639cfba1c6e179 100644 --- a/src/Wima/WimaArea.cc +++ b/src/Wima/WimaArea.cc @@ -1,6 +1,95 @@ #include "WimaArea.h" -WimaArea::WimaArea() +WimaArea::WimaArea(QObject *parent) : + WimaArea (nullptr, parent) { + //qWarning() << "WimaPolygon:: polygon count" << _polygon->count(); +} + +WimaArea::WimaArea(WimaArea *other, QObject *parent): + QGCMapPolygon (parent) + ,_maxAltitude (30) + ,_wimaVehicle (new WimaVehicle(this)) +{ + if (other != nullptr) { + _maxAltitude = other->maxAltitude(); + _wimaVehicle = other->vehicle(); + setPath (other->path()); + setCenter (other->center()); + setCenterDrag (other->centerDrag()); + setInteractive (other->interactive()); + } + +} + +WimaArea::~WimaArea() +{ + +} + + +void WimaArea::setMaxAltitude(double alt) +{ + if(alt > 0 && alt != _maxAltitude){ + _maxAltitude = alt; + emit maxAltitudeChanged(); + } +} + + +void WimaArea::setVehicle(WimaVehicle *vehicle) +{ + if(_wimaVehicle != vehicle){ + _wimaVehicle->deleteLater(); + _wimaVehicle = vehicle; + emit vehicleChanged(); + } +} +/*QList* WimaArea::splitArea(WimaArea *polygonToSplitt, int numberOfFractions) +{ + if(numberOfFractions > 0 && polygonToSplitt != nullptr){ + WimaArea* poly; + if(p) + = new WimaArea(polygonToSplitt, this); + QList* list = new QList(); + list->append(poly); + return list; + } + return nullptr; } + + +QList* WimaArea::splitArea(int numberOfFractions) +{ + return splitPolygonArea(this, numberOfFractions); +}*/ + +int WimaArea::getClosestVertexIndex(QGeoCoordinate coordinate) +{ + if (this->count() == 0) { + qWarning("Polygon count == 0!"); + return -1; + }else if (this->count() == 1) { + return 0; + }else { + int index = 0; + double min_dist = coordinate.distanceTo(this->vertexCoordinate(index)); + for(int i = 1; i < this->count(); i++){ + double dist = coordinate.distanceTo(this->vertexCoordinate(i)); + if (dist < min_dist){ + min_dist = dist; + index = i; + } + } + + return index; + } +} + +QGeoCoordinate WimaArea::getClosestVertex(QGeoCoordinate coordinate) +{ + return this->vertexCoordinate(getClosestVertexIndex(coordinate)); +} + + diff --git a/src/Wima/WimaArea.h b/src/Wima/WimaArea.h index 784672dd6c3f4328e4896de42c5f1819f68de61f..cd61b7ca992b2281755976c429b37e9bee029184 100644 --- a/src/Wima/WimaArea.h +++ b/src/Wima/WimaArea.h @@ -1,11 +1,54 @@ -#ifndef WIMAAREA_H -#define WIMAAREA_H +#pragma once +#include "QGCMapPolygon.h" +#include "Vehicle.h" +#include "qobject.h" +#include "WimaVehicle.h" -class WimaArea +class WimaArea : public QGCMapPolygon //abstract base class for all WimaAreas { + Q_OBJECT public: - WimaArea(); + WimaArea(QObject* parent = nullptr); + WimaArea(WimaArea* other, QObject* parent = nullptr); + ~WimaArea(); + + + + 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 = 0; + virtual QString editorQML (void) const = 0; + + //Property setters + void setMaxAltitude (double alt); + 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 (QGeoCoordinate coordinate); + //iterates over all vertices in _polygon and returns that one closest to coordinate + QGeoCoordinate getClosestVertex (QGeoCoordinate coordinate); + +signals: + void maxAltitudeChanged (void); + void vehicleChanged (void); + + +protected: + double _maxAltitude; + WimaVehicle* _wimaVehicle; }; -#endif // WIMAAREA_H \ No newline at end of file + diff --git a/src/Wima/WimaController.cc b/src/Wima/WimaController.cc index 0a54782d9aab876bb73f62a50c637e6cc4fc99b1..100a0597b36f68e64e6796a3428100f36f3c85d5 100644 --- a/src/Wima/WimaController.cc +++ b/src/Wima/WimaController.cc @@ -1,6 +1,134 @@ #include "WimaController.h" +#include "MissionController.h" -WimaController::WimaController(QObject *parent) : QObject(parent) +WimaController::WimaController(QObject *parent) : + QObject (parent) + ,_planView (true) + ,_visualItems (new QmlObjectListModel(parent)) +{ + connect(this, &WimaController::currentPolygonIndexChanged, this, &WimaController::recalcPolygonInteractivity); +} + +void WimaController::setMasterController(PlanMasterController *masterC) +{ + _masterController = masterC; + emit masterControllerChanged(); +} + +void WimaController::setMissionController(MissionController *missionC) +{ + _missionController = missionC; + emit missionControllerChanged(); +} + +void WimaController::setCurrentPolygonIndex(int index) +{ + if(index >= 0 && index < _visualItems->count() && index != _currentPolygonIndex){ + _currentPolygonIndex = index; + + emit currentPolygonIndexChanged(index); + } +} + +void WimaController::addGOperationArea() +{ + WimaGOperationArea* newPoly = new WimaGOperationArea(this); + _visualItems->append(newPoly); + int newIndex = _visualItems->count()-1; + _currentPolygonIndex = newIndex; + + emit currentPolygonIndexChanged(newIndex); + emit visualItemsChanged(); +} + +void WimaController::removeArea(int index) +{ + if(index >= 0 && index < _visualItems->count()){ + _visualItems->removeAt(index); + + emit visualItemsChanged(); + + if(_currentPolygonIndex >= _visualItems->count()){ + setCurrentPolygonIndex(_visualItems->count() - 1); + }else{ + recalcPolygonInteractivity(_currentPolygonIndex); + } + }else{ + qWarning("Index out of bounds!"); + } + +} + +void WimaController::addServiceArea() +{ + resetAllIsCurrentPolygon(); + WimaServiceArea* newPoly = new WimaServiceArea(this); + newPoly->setInteractive(true); + _visualItems->append(newPoly); + + emit visualItemsChanged(); +} + +void WimaController::startMission() +{ + +} + +void WimaController::abortMission() +{ + +} + +void WimaController::pauseMission() +{ + +} + +void WimaController::resumeMission() +{ + +} + +void WimaController::saveMission() +{ + +} + +void WimaController::loadMission() +{ + +} + +void WimaController::recalcVehicleCorridor() { } + +void WimaController::recalcVehicleMeasurementAreas() +{ + +} + +void WimaController::recalcAll() +{ + +} + +void WimaController::recalcPolygonInteractivity(int index) +{ + resetAllIsCurrentPolygon(); + WimaArea* interactivePoly = qobject_cast(_visualItems->get(index)); + interactivePoly->setInteractive(true); +} + +void WimaController::resetAllIsCurrentPolygon() +{ + int itemCount = _visualItems->count(); + for (int i = 0; i < itemCount; i++) { + WimaArea* iteratorPoly = qobject_cast(_visualItems->get(i)); + iteratorPoly->setInteractive(false); + } +} + + + diff --git a/src/Wima/WimaController.h b/src/Wima/WimaController.h index 4996dede5b78d1b112dcee38fb28b824b48715fc..c1b3435280b4fd1976d31c0828ef12d4c275b566 100644 --- a/src/Wima/WimaController.h +++ b/src/Wima/WimaController.h @@ -1,17 +1,78 @@ -#ifndef WIMACONTROLLER_H -#define WIMACONTROLLER_H +#pragma once #include +#include "QGCMapPolygon.h" +#include "QmlObjectListModel.h" + +#include "WimaArea.h" +#include "WimaGOperationArea.h" +#include "WimaServiceArea.h" + +#include "PlanMasterController.h" +#include "MissionController.h" + class WimaController : public QObject { Q_OBJECT public: - explicit WimaController(QObject *parent = nullptr); + WimaController(QObject *parent = nullptr); + + + 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(int currentPolygonIndex READ currentPolygonIndex WRITE setCurrentPolygonIndex NOTIFY currentPolygonIndexChanged) + + + // Property accessors + PlanMasterController* masterController (void) const { return _masterController;} + MissionController* missionController (void) const { return _missionController;} + QmlObjectListModel* visualItems (void) { return _visualItems; } + int currentPolygonIndex (void) const { return _currentPolygonIndex; } + + + + + // Property setters + void setMasterController (PlanMasterController* masterController); + void setMissionController (MissionController* missionController); + void setCurrentPolygonIndex (int index); + + Q_INVOKABLE void addGOperationArea(); + Q_INVOKABLE void removeArea(int index); + Q_INVOKABLE void addServiceArea(); + + Q_INVOKABLE void startMission(); + Q_INVOKABLE void abortMission(); + Q_INVOKABLE void pauseMission(); + Q_INVOKABLE void resumeMission(); + + Q_INVOKABLE void saveMission(); + Q_INVOKABLE void loadMission(); + + Q_INVOKABLE void resetAllIsCurrentPolygon(void); + + signals: + void masterControllerChanged (void); + void missionControllerChanged (void); + void visualItemsChanged (void); + void currentPolygonIndexChanged (int index); + +private slots: + void recalcVehicleCorridor(); + void recalcVehicleMeasurementAreas(); + void recalcAll(); + void recalcPolygonInteractivity(int index); -public slots: -}; -#endif // WIMACONTROLLER_H \ No newline at end of file +private: + bool _planView; + QmlObjectListModel* _visualItems; + PlanMasterController* _masterController; + MissionController* _missionController; + int _currentPolygonIndex; + +}; diff --git a/src/Wima/WimaGOperationArea.SettingsGroup.json b/src/Wima/WimaGOperationArea.SettingsGroup.json index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7c2656b30fa92ab3881a875a50eb9d391019a291 100644 --- a/src/Wima/WimaGOperationArea.SettingsGroup.json +++ b/src/Wima/WimaGOperationArea.SettingsGroup.json @@ -0,0 +1,27 @@ +[ +{ + "name": "BottomLayerAltitude", + "shortDescription": "Altitude of the bottom layer.", + "type": "double", + "units": "m", + "min": 1, + "decimalPlaces": 2, + "defaultValue": 50 +}, +{ + "name": "NumberOfLayers", + "shortDescription": "The number of layers.", + "type": "uint32", + "min": 1, + "defaultValue": 10 +}, +{ + "name": "LayerDistance", + "shortDescription": "The distance between two adjacent layers.", + "type": "double", + "units": "m", + "min": 0, + "decimalPlaces": 2, + "defaultValue": 10 +} +] diff --git a/src/Wima/WimaGOperationArea.cc b/src/Wima/WimaGOperationArea.cc index 4fe0ecf8a246da6994462d990a5f793fb4334e5b..8e27e1b7bda9e1ef1d8ddf0b29ca884985d4ed7b 100644 --- a/src/Wima/WimaGOperationArea.cc +++ b/src/Wima/WimaGOperationArea.cc @@ -1,6 +1,107 @@ #include "WimaGOperationArea.h" -WimaGOperationArea::WimaGOperationArea() + +const char* WimaGOperationArea::settingsGroup = "OperatingArea"; +const char* WimaGOperationArea::bottomLayerAltitudeName = "BottomLayerAltitude"; +const char* WimaGOperationArea::numberOfLayersName = "NumberOfLayers"; +const char* WimaGOperationArea::layerDistanceName = "LayerDistance"; + +WimaGOperationArea::WimaGOperationArea(QObject *parent) + : WimaGOperationArea (nullptr, parent) +{ + +} + +WimaGOperationArea::WimaGOperationArea(WimaArea *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]) + , _polyline (new WimaTrackerPolyline(this)) +{ + this->setObjectName("Operating Area"); + _polyline.bindPolygon(this); + //qWarning("Here I am!"); + //connect(&_polyline, &WimaTrackerPolyline::pathChanged, this, &WimaGOperationArea::polylineChanged ); +} + +void WimaGOperationArea::addVehicle(WimaVehicle *vehicle) { + if(vehicle != nullptr){ + _wimaVehicle = vehicle; + emit vehicleChanged(); + } +} +void WimaGOperationArea::removeVehicle(int vehicleIndex) +{ + if(vehicleIndex >= 0){ + _wimaVehicle = nullptr; + emit vehicleChanged(); + } } + +/*void WimaGOperationArea::recalculatesubPolygons() +{ + 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); + } +} + +void WimaGOperationArea::removeAllVehicles() +{ + int count = _vehicleList->count(); + + if(count > 0){ + do{ + _vehicleList->removeAt(0); + count--; + }while(count > 0); + + emit vehicleListChanged(); + } + +} + + +void WimaGOperationArea::addVehiclePolygon() +{ + _vehiclePolygons->append(new WimaVehicleMeasurementPolygon(this)); + + emit vehiclePolygonsChanged(); +} + +void WimaGOperationArea::removeVehiclePolygon(int polygonIndex) +{ + 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."); + } +}*/ + + + diff --git a/src/Wima/WimaGOperationArea.h b/src/Wima/WimaGOperationArea.h index fcc3de3c3e78cfce1fcaef058b30e131dad1880c..27e25d2ac078048db60a672d8c6f14dbdce2595d 100644 --- a/src/Wima/WimaGOperationArea.h +++ b/src/Wima/WimaGOperationArea.h @@ -1,11 +1,78 @@ -#ifndef WIMAGOPERATIONAREA_H -#define WIMAGOPERATIONAREA_H +#pragma once +#include +#include "WimaArea.h" +#include "SettingsFact.h" +#include "WimaTrackerPolyline.h" -class WimaGOperationArea +#include "QScopedPointer" + +class WimaGOperationArea : public WimaArea { + Q_OBJECT public: - WimaGOperationArea(); + WimaGOperationArea(QObject* parent = nullptr); + WimaGOperationArea(WimaArea* other, QObject* parent = nullptr); + + Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitude CONSTANT) + Q_PROPERTY(Fact* numberOfLayers READ numberOfLayers CONSTANT) + Q_PROPERTY(Fact* layerDistance READ layerDistance CONSTANT) + /*Q_PROPERTY(QmlObjectListModel* vehicleList READ vehicleList NOTIFY vehicleListChanged) + Q_PROPERTY(QmlObjectListModel* vehiclePolygons READ vehiclePolygons NOTIFY vehiclePolygonsChanged)*/ + Q_PROPERTY(WimaTrackerPolyline* polyline READ polyline CONSTANT) + + + Q_INVOKABLE void addVehicle (WimaVehicle *vehicle); + Q_INVOKABLE void removeVehicle (int vehicleIndex); + /*Q_INVOKABLE void recalculatesubPolygons (); + Q_INVOKABLE void removeAllVehicles (); + Q_INVOKABLE void addVehiclePolygon (); + Q_INVOKABLE void removeVehiclePolygon (int polygonIndex); + Q_INVOKABLE void removeVehiclePolygon (WimaVehicleMeasurementPolygon *wimaPolygon);*/ + + + // Overrides from WimaPolygon + QString mapVisualQML (void) const { return "WimaGOperationAreaMapVisual.qml";} + QString editorQML (void) const { return "WimaGOperationAreaEditor.qml";} + + // Property accessors + Fact* bottomLayerAltitude (void) { return &_bottomLayerAltitude;} + Fact* numberOfLayers (void) { return &_numberOfLayers;} + Fact* layerDistance (void) { return &_layerDistance;} + /*QmlObjectListModel* vehicleList (void) const { return _vehicleList;} + QmlObjectListModel* vehiclePolygons (void) const { return _vehiclePolygons;}*/ + WimaTrackerPolyline* polyline (void) { return &_polyline;} + + + static const char* settingsGroup; + static const char* bottomLayerAltitudeName; + static const char* numberOfLayersName; + static const char* layerDistanceName; + + +signals: + void bottomLayerAltitudeChanged (void); + void numberOfLayersChanged (void); + void layerDistanceChanged (void); + //void vehicleListChanged (void); + void polylineChanged (void); + //void vehiclePolygonsChanged (void); + + +private: + QMap _metaDataMap; + + SettingsFact _bottomLayerAltitude; + SettingsFact _numberOfLayers; + SettingsFact _layerDistance; + + + /*QmlObjectListModel* _vehicleList; + QmlObjectListModel* _vehiclePolygons;*/ + WimaTrackerPolyline _polyline; + + + }; -#endif // WIMAGOPERATIONAREA_H \ No newline at end of file + diff --git a/src/Wima/WimaServiceArea.cc b/src/Wima/WimaServiceArea.cc index e493648f095f0e19f5e7bf76ebb0b532676af832..af224e93ae1ba91fd2b12063753d33e1cc441263 100644 --- a/src/Wima/WimaServiceArea.cc +++ b/src/Wima/WimaServiceArea.cc @@ -1,6 +1,30 @@ #include "WimaServiceArea.h" -WimaServiceArea::WimaServiceArea() +WimaServiceArea::WimaServiceArea(QObject *parent): + WimaServiceArea (nullptr, parent) { } + +WimaServiceArea::WimaServiceArea(WimaArea *other, QObject *parent): + WimaArea (other, parent) +{ + this->setObjectName("Service Area"); +} + +void WimaServiceArea::setTakeOffPosition(QGeoCoordinate* coordinate) +{ + if(_takeOffPosition != *coordinate){ + _takeOffPosition = *coordinate; + emit takeOffPositionChanged(); + } +} + +void WimaServiceArea::setLandPosition(QGeoCoordinate* coordinate) +{ + if(_landPosition != *coordinate){ + _landPosition = *coordinate; + emit landPositionChanged(); + } +} + diff --git a/src/Wima/WimaServiceArea.h b/src/Wima/WimaServiceArea.h index 3d5922c852ec04256a2498adc4c0efcdf4815099..008191ac1cfeb15f9e4a8e379a763ab8c4b479c7 100644 --- a/src/Wima/WimaServiceArea.h +++ b/src/Wima/WimaServiceArea.h @@ -1,11 +1,35 @@ -#ifndef WIMASERVICEAREA_H -#define WIMASERVICEAREA_H +#pragma once +#include +#include "WimaArea.h" -class WimaServiceArea +class WimaServiceArea : public WimaArea { + Q_OBJECT public: - WimaServiceArea(); + WimaServiceArea(QObject* parent = nullptr); + WimaServiceArea(WimaArea* other = nullptr, QObject* parent = nullptr); + + Q_PROPERTY(QGeoCoordinate* takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged) + Q_PROPERTY(QGeoCoordinate* landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged) + + // Overrides from WimaPolygon + QString mapVisualQML (void) const { return "WimaServiceAreaMapVisual.qml";} + QString editorQML (void) const { return "WimaServiceAreaEditor.qml";} + + // Property acessors + QGeoCoordinate* takeOffPosition (void) { return &_takeOffPosition;} + QGeoCoordinate* landPosition (void) { return &_landPosition;} + + // Property setters + void setTakeOffPosition (QGeoCoordinate* coordinate); + void setLandPosition (QGeoCoordinate* coordinate); + +signals: + void takeOffPositionChanged (void); + void landPositionChanged (void); +private: + QGeoCoordinate _takeOffPosition; + QGeoCoordinate _landPosition; }; -#endif // WIMASERVICEAREA_H \ No newline at end of file diff --git a/src/Wima/WimaTrackerPolyline.cc b/src/Wima/WimaTrackerPolyline.cc index 4752bc0cc3cb400be818b83867c01aed08dd59fb..db5e2d8442ec27f80afb11a3888a2ec96616f991 100644 --- a/src/Wima/WimaTrackerPolyline.cc +++ b/src/Wima/WimaTrackerPolyline.cc @@ -1,6 +1,145 @@ #include "WimaTrackerPolyline.h" -WimaTrackerPolyline::WimaTrackerPolyline() +WimaTrackerPolyline::WimaTrackerPolyline(QObject *parent) + : WimaTrackerPolyline (nullptr, parent) { +} + +WimaTrackerPolyline::WimaTrackerPolyline(QGCMapPolyline *other, QObject *parent) + :QGCMapPolyline (other, parent) + , _boundArea (nullptr) + , _startVertexIndex(0) + , _endVertexIndex(0) +{ +} + +void WimaTrackerPolyline::bindPolygon(WimaArea *polygon) +{ + if(polygon != nullptr){ + _boundArea = polygon; + connect(polygon, &WimaArea::pathChanged, this, &WimaTrackerPolyline::recalcPolyline); + }else{ + qWarning("bindPolygon(): Invalid Object!"); + } +} + +void WimaTrackerPolyline::unbindPolygon() +{ + if(_boundArea != nullptr){ + disconnect(_boundArea, &WimaArea::pathChanged, this, &WimaTrackerPolyline::recalcPolyline); + _boundArea = nullptr; + }else{ + qWarning("unbindPolygon(): No Object bound!"); + } +} + +void WimaTrackerPolyline::swapLimits() +{ + int storage = _startVertexIndex; + _startVertexIndex = _endVertexIndex; + _endVertexIndex = storage; +} + + +void WimaTrackerPolyline::setStartVertexIndex(int PolygonVertexIndex) +{ + if(PolygonVertexIndex >= 0 && PolygonVertexIndex < _boundArea->count()){ + _startVertexIndex = PolygonVertexIndex; + emit startVertexIndexChanged(); + recalcPolyline(); + }else{ + qWarning("WimaTrackerPolyline::setStartVertexIndex(): Index out of bounds!"); + } +} +void WimaTrackerPolyline::setEndVertexIndex(int PolygonVertexIndex) +{ + if(PolygonVertexIndex >= 0 && PolygonVertexIndex < _boundArea->count()){ + _endVertexIndex = PolygonVertexIndex; + emit endVertexIndexChanged(); + recalcPolyline(); + }else{ + qWarning("WimaTrackerPolyline::setEndVertexIndex(): Index out of bounds!"); + } } + +void WimaTrackerPolyline::snapVertex(int polylineVertexIndex) +{ + int polylineVertexCount = this->count(); + if (polylineVertexIndex >= 0 && polylineVertexIndex < polylineVertexCount){ + if (polylineVertexIndex == 0){ + snapStartVertex(); + }else if (polylineVertexIndex == polylineVertexCount-1) { + snapEndVertex(); + }else { + int polygonVertexIndex = _startVertexIndex + polylineVertexIndex; + int polygonVertexCount = _boundArea->count(); + if (polygonVertexIndex >= polygonVertexCount){ + polygonVertexIndex = polygonVertexIndex - polygonVertexCount; + if (polygonVertexCount > _endVertexIndex) { + // This branch sould actually not be reachable, just in case... + qWarning("WimaTrackerPolyline::snapVertex(): polylineVertexIndex out of bounds!"); + return; + } + } + this->adjustVertex(polylineVertexIndex, _boundArea->vertexCoordinate(polygonVertexIndex)); + } + }else { + qWarning("WimaTrackerPolyline::snapVertex(): Index out of bounds!"); + } +} + +void WimaTrackerPolyline::snapEndVertex() +{ + if (_boundArea != nullptr && _boundArea->count() >= 3){ + int currentVertexIndex = this->count()-1; + int closestVertexIndex = _boundArea->getClosestVertexIndex(this->vertexCoordinate(currentVertexIndex)); + QGeoCoordinate closestVertex = _boundArea->vertexCoordinate(closestVertexIndex); + _endVertexIndex = closestVertexIndex; + this->adjustVertex(currentVertexIndex, closestVertex); + this->recalcPolyline(); + } +} + +void WimaTrackerPolyline::snapStartVertex() +{ + if (_boundArea != nullptr && _boundArea->count() >= 3){ + int currentVertexIndex = 0; + int closestVertexIndex = _boundArea->getClosestVertexIndex(this->vertexCoordinate(currentVertexIndex)); + QGeoCoordinate closestVertex = _boundArea->vertexCoordinate(closestVertexIndex); + _startVertexIndex = closestVertexIndex; + this->adjustVertex(currentVertexIndex, closestVertex); + this->recalcPolyline(); + } +} + +void WimaTrackerPolyline::recalcPolyline() +{ + qWarning("WimaTrackerPolyline::recalcPolyline()"); + if (_boundArea != nullptr && _boundArea->count() > 0){ + if (_startVertexIndex >= _boundArea->count()){ + _startVertexIndex = 0; + } + if (_endVertexIndex >= _boundArea->count()){ + _endVertexIndex = _boundArea->count()-1; + } + + _polyline.clear(); + int i = _startVertexIndex; + while(1){ + _polyline.appendVertex(_boundArea->vertexCoordinate(i)); + if (i == _boundArea->count()-1 && i != _endVertexIndex){ + i = 0; + }else if (i == _endVertexIndex) { + break; + }else { + i++; + } + + } + }else{ + qWarning("WimaTrackerPolyline::recalcPolyline(): No object bound!"); + } +} + + diff --git a/src/Wima/WimaTrackerPolyline.h b/src/Wima/WimaTrackerPolyline.h index 18952473977ca9edcf94538295921554553c486d..bee769032bfc79872ec546272a38159090788c9a 100644 --- a/src/Wima/WimaTrackerPolyline.h +++ b/src/Wima/WimaTrackerPolyline.h @@ -1,11 +1,59 @@ -#ifndef WIMATRACKERPOLYLINE_H -#define WIMATRACKERPOLYLINE_H +#pragma once +#include +#include "WimaArea.h" +#include "QGCMapPolyline.h" -class WimaTrackerPolyline + +class WimaTrackerPolyline : public QGCMapPolyline { + Q_OBJECT public: - WimaTrackerPolyline(); + WimaTrackerPolyline(QObject *parent = nullptr); + WimaTrackerPolyline(QGCMapPolyline *other, QObject *parent = nullptr); + + Q_PROPERTY(int startVertexIndex READ startVertexIndex WRITE setStartVertexIndex NOTIFY startVertexIndexChanged) + Q_PROPERTY(int endVertexIndex READ endVertexIndex WRITE setEndVertexIndex NOTIFY endVertexIndexChanged) + + // Property accessors + int startVertexIndex (void) const { return _startVertexIndex;} + int endVertexIndex (void) const { return _endVertexIndex;} + + + //Property setters + Q_INVOKABLE void bindPolygon (WimaArea* polygon); + Q_INVOKABLE void unbindPolygon (); + Q_INVOKABLE void swapLimits (); + Q_INVOKABLE void setStartVertexIndex (int PolygonVertexIndex); + Q_INVOKABLE void setEndVertexIndex (int PolygonVertexIndex); + + // Methodes + // calls updateEndVertex() if VertexIndex == _endVertexIndex, calls updateStartVertex() if VertexIndex == _startVertexIndex, or + // calls both if VertexIndex != _endVertexIndex && VertexIndex != _startVertexIndex + Q_INVOKABLE void snapVertex (int VertexIndex); + // snaps the end vertex to the closest coordinate of _boundArea when called + void snapEndVertex (); + // snaps the start vertex to the closest coordinate of _boundArea when called + void snapStartVertex (); + + + + + +signals: + void startVertexIndexChanged (void); + void endVertexIndexChanged (void); + +public slots: + void recalcPolyline(void); + +private: + QGCMapPolyline _polyline; + WimaArea* _boundArea; + // this->vertexCoordinate(this->count()-1) and _boundArea->vertexCoordinate(_startVertexIndex) are linked + int _startVertexIndex; + // this->vertexCoordinate(0) and _boundArea->vertexCoordinate(_endVertexIndex) are linked + int _endVertexIndex; + }; -#endif // WIMATRACKERPOLYLINE_H \ No newline at end of file diff --git a/src/Wima/WimaVCorridor.cc b/src/Wima/WimaVCorridor.cc index 646684d3698e2db62acd923560b32b58940f8088..7a51fdf3b9e130c5ba86a03a69ed7c1efc16f1c0 100644 --- a/src/Wima/WimaVCorridor.cc +++ b/src/Wima/WimaVCorridor.cc @@ -1,6 +1,13 @@ #include "WimaVCorridor.h" -WimaVCorridor::WimaVCorridor() +WimaVCorridor::WimaVCorridor(QObject *parent): + WimaVCorridor(nullptr, parent) { } + +WimaVCorridor::WimaVCorridor(WimaArea *other, QObject *parent): + WimaArea (other, parent) +{ + this->setObjectName("Corridor"); +} diff --git a/src/Wima/WimaVCorridor.h b/src/Wima/WimaVCorridor.h index 0b3c20d4465e9a59b25d54be14d5d8aef2220cb6..3af63c6c9e0aa9f6f6cb1ffa6ef7889952c8ae44 100644 --- a/src/Wima/WimaVCorridor.h +++ b/src/Wima/WimaVCorridor.h @@ -1,11 +1,17 @@ -#ifndef WIMAVCORRIDOR_H -#define WIMAVCORRIDOR_H +#pragma once +#include +#include "WimaArea.h" -class WimaVCorridor +class WimaVCorridor : public WimaArea { + Q_OBJECT public: - WimaVCorridor(); + WimaVCorridor(QObject* parent = nullptr); + WimaVCorridor(WimaArea* other = nullptr, QObject* parent = nullptr); + + // Overrides from WimaPolygon + QString mapVisualQML (void) const { return "WimaVCorridorMapVisual.qml";} + QString editorQML (void) const { return "WimaVCorridorEditor.qml";} }; -#endif // WIMAVCORRIDOR_H \ No newline at end of file diff --git a/src/Wima/WimaVehicle.cc b/src/Wima/WimaVehicle.cc index 4dc9309087184c51a432b02c9210704fdd1c7246..24bdee7c5d99497f4720d59a39cd99757fb53aa1 100644 --- a/src/Wima/WimaVehicle.cc +++ b/src/Wima/WimaVehicle.cc @@ -1,6 +1,49 @@ #include "WimaVehicle.h" -WimaVehicle::WimaVehicle() + + +WimaVehicle::WimaVehicle(QObject *parent): + QObject (parent) + ,_vehicle (nullptr) + ,_serviceArea (nullptr) + ,_vehicleCorridor (nullptr) + ,_operationArea (nullptr) +{ + +} + +void WimaVehicle::setVehicle(Vehicle *vehicle) +{ + if(vehicle != nullptr){ + _vehicle = vehicle; + }else { + qWarning("Not a valid vehicle!"); + } +} + +void WimaVehicle::setServiceArea(WimaServiceArea *servicePolygon) { + if(servicePolygon != nullptr){ + _serviceArea = servicePolygon; + }else{ + qWarning("Not a valid service Polygon!"); + } +} +void WimaVehicle::setVCorridor(WimaVCorridor *vehicleCorridor) +{ + if(vehicleCorridor != nullptr){ + _vehicleCorridor = vehicleCorridor; + }else{ + qWarning("Not a valid vehicle Corridor!"); + } +} + +void WimaVehicle::setOperationArea(WimaGOperationArea *operationArea) +{ + if(operationArea != nullptr){ + _operationArea = operationArea; + }else{ + qWarning("Not a valid measurementPolygon!"); + } } diff --git a/src/Wima/WimaVehicle.h b/src/Wima/WimaVehicle.h index c0fb671146d20f5cf968585bf0b2cb63695a1371..942fd45a7e3a4978a4387daf089351886533269f 100644 --- a/src/Wima/WimaVehicle.h +++ b/src/Wima/WimaVehicle.h @@ -1,11 +1,33 @@ -#ifndef WIMAVEHICLE_H -#define WIMAVEHICLE_H +#pragma once +#include +#include "Vehicle.h" -class WimaVehicle +class WimaServiceArea; +class WimaVCorridor; +class WimaGOperationArea; + +class WimaVehicle : public QObject { + Q_OBJECT public: - WimaVehicle(); + WimaVehicle(QObject* parent = nullptr); + + WimaServiceArea* serviceArea (void) const { return _serviceArea;} + WimaVCorridor* vehicleCorridor (void) const { return _vehicleCorridor;} + WimaGOperationArea* operationArea (void) const { return _operationArea;} + + void setVehicle (Vehicle* vehicle); + void setServiceArea (WimaServiceArea* serviceArea); + void setVCorridor (WimaVCorridor* vehicleCorridor); + void setOperationArea (WimaGOperationArea* operationArea); + +private: + Vehicle* _vehicle; + WimaServiceArea* _serviceArea; + WimaVCorridor* _vehicleCorridor; + WimaGOperationArea* _operationArea; + }; -#endif // WIMAVEHICLE_H \ No newline at end of file + diff --git a/src/WimaView/FlyAreaPolygonMapVisual.qml b/src/WimaView/FlyAreaPolygonMapVisual.qml deleted file mode 100644 index d7a5ef0016ecda4b9a0a52a35825b9d8855e183b..0000000000000000000000000000000000000000 --- a/src/WimaView/FlyAreaPolygonMapVisual.qml +++ /dev/null @@ -1,78 +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 - -/// Fly 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 _flyAreaPolygon - - - - - /// Add an initial 4 sided polygon if there is none - function _addInitialPolygon() { - if (_flyAreaPolygon.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.75 - rect.height *= 0.75 - - 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) - - _flyAreaPolygon.appendVertex(topLeftCoord) - _flyAreaPolygon.appendVertex(topRightCoord) - _flyAreaPolygon.appendVertex(bottomRightCoord) - _flyAreaPolygon.appendVertex(bottomLeftCoord) - } - } - - Component.onCompleted: { - _addInitialPolygon() - } - - QGCMapPolygonVisuals { - qgcView: _root.qgcView - mapControl: map - mapPolygon: _flyAreaPolygon - borderWidth: 1 - borderColor: "black" - interiorColor: "green" - interiorOpacity: 0.25 - } - -} diff --git a/src/WimaView/WimaGOperationAreaEditor.qml b/src/WimaView/WimaGOperationAreaEditor.qml index 9c36e13c5bfc938decd97e1b1eba471841e202c1..a0a8a2803fb1208d7bda911dcefa147c727d7ee9 100644 --- a/src/WimaView/WimaGOperationAreaEditor.qml +++ b/src/WimaView/WimaGOperationAreaEditor.qml @@ -1,5 +1,127 @@ -import QtQuick 2.0 +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Extras 1.4 +import QtQuick.Layouts 1.2 -Item { +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 +import QGroundControl.FlightMap 1.0 -} +// Editor for Operating Area items +Rectangle { + id: _root + height: visible ? (editorColumn.height + (_margin * 2)) : 0 + width: availableWidth + color: qgcPal.windowShadeDark + radius: _radius + + // The following properties must be available up the hierarchy chain + //property real availableWidth ///< Width for control + //property var areaItem ///< Mission Item for editor + + property real _margin: ScreenTools.defaultFontPixelWidth / 2 + property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5 + property var polyline: areaItem.polyline + property var operatingPolygon: areaItem + property bool initNecesarry: true + + function editPolyline(){ + polyline.interactive = true; + } + + + + + QGCPalette { id: qgcPal; colorGroupEnabled: true } + + Column { + id: editorColumn + anchors.margins: _margin + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + + SectionHeader { + id: scanHeader + text: qsTr("Settings") + } + + Column { + anchors.left: parent.left + anchors.right: parent.rightsetI + spacing: _margin + visible: scanHeader.checked + + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + + QGCLabel { + text: qsTr("Bottom Layer Altitude") + } + FactTextField { + fact: areaItem.bottomLayerAltitude + Layout.fillWidth: true + } + + /*QGCLabel { text: qsTr("Number of Layers") } + FactTextField { + fact: areaItem.numberOfLayers + Layout.fillWidth: true + } + + QGCLabel { text: qsTr("Layer Distance") } + FactTextField { + fact: areaItem.layerDistance + Layout.fillWidth: true + }*/ + + + } + + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: 1 + } + } // Column - Scan + SectionHeader { + id: polylineHeader + text: qsTr("Gateway Poly Line") + } + + QGCButton { + id: polylineEditor + anchors.topMargin: _margin / 2 + anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2 + anchors.rightMargin: ScreenTools.defaultFontPixelWidth + text: "Edit Polyline" + + onClicked: editPolyline() + } + + SectionHeader { + id: statsHeader + text: qsTr("Statistics") + } + + Grid { + columns: 2 + columnSpacing: ScreenTools.defaultFontPixelWidth + visible: statsHeader.checked + + /*QGCLabel { text: qsTr("Layers") } + QGCLabel { text: areaItem.layers.valueString }*/ + + } + } // Column +} // Rectangle diff --git a/src/WimaView/WimaGOperationAreaMapVisual.qml b/src/WimaView/WimaGOperationAreaMapVisual.qml index 9c36e13c5bfc938decd97e1b1eba471841e202c1..3c14b98fcde2777c26b179209ae6ff632dea355e 100644 --- a/src/WimaView/WimaGOperationAreaMapVisual.qml +++ b/src/WimaView/WimaGOperationAreaMapVisual.qml @@ -1,5 +1,116 @@ -import QtQuick 2.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 areaItem: object + property var _polygon: areaItem + property var _polyline: areaItem.polyline + + 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.75 + rect.height *= 0.75 + + 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) + } + } + + function _addInitialPolyline(){ + _polyline.setStartVertexIndex(0); + _polyline.setEndVertexIndex(2); + } + + + + Component.onCompleted: { + _addInitialPolygon() + _addInitialPolyline() + } + + Component.onDestruction: { + } + + + WimaMapPolygonVisuals { + qgcView: _root.qgcView + mapControl: map + mapPolygon: _polygon + borderWidth: 1 + borderColor: "black" + interiorColor: "green" + interiorOpacity: 0.25 + } + + + WimaMapPolylineVisuals { + qgcView: _root.qgcView + mapControl: map + mapPolyline: _polyline + lineWidth: 4 + lineColor: interactive ? "yellow" : "green" + } + + /*QGCMapPolylineVisuals { + id: mapPolylineVisuals + qgcView: _root.qgcView + mapControl: map + mapPolyline: _polyline + lineWidth: 3 + lineColor: "#be781c" + }*/ + + + + + + } diff --git a/src/WimaView/WimaGlobalMeasurementPolygonEditor.cc b/src/WimaView/WimaGlobalMeasurementPolygonEditor.cc deleted file mode 100644 index 60645d112813fc4845c5c041a7b054d96a535689..0000000000000000000000000000000000000000 --- a/src/WimaView/WimaGlobalMeasurementPolygonEditor.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "WimaGlobalMeasurementPolygonEditor.h" - -WimaGlobalMeasurementPolygonEditor::WimaGlobalMeasurementPolygonEditor(QObject *parent) - : QAbstractItemModel(parent) -{ -} - -QVariant WimaGlobalMeasurementPolygonEditor::headerData(int section, Qt::Orientation orientation, int role) const -{ - // FIXME: Implement me! -} - -QModelIndex WimaGlobalMeasurementPolygonEditor::index(int row, int column, const QModelIndex &parent) const -{ - // FIXME: Implement me! -} - -QModelIndex WimaGlobalMeasurementPolygonEditor::parent(const QModelIndex &index) const -{ - // FIXME: Implement me! -} - -int WimaGlobalMeasurementPolygonEditor::rowCount(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return 0; - - // FIXME: Implement me! -} - -int WimaGlobalMeasurementPolygonEditor::columnCount(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return 0; - - // FIXME: Implement me! -} - -QVariant WimaGlobalMeasurementPolygonEditor::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - // FIXME: Implement me! - return QVariant(); -} diff --git a/src/WimaView/WimaGlobalMeasurementPolygonEditor.h b/src/WimaView/WimaGlobalMeasurementPolygonEditor.h deleted file mode 100644 index f2ccafb47d7c4c1ca61a26c9d7a34aef7519b37c..0000000000000000000000000000000000000000 --- a/src/WimaView/WimaGlobalMeasurementPolygonEditor.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef WIMAGLOBALMEASUREMENTPOLYGONEDITOR_H -#define WIMAGLOBALMEASUREMENTPOLYGONEDITOR_H - -#include - -class WimaGlobalMeasurementPolygonEditor : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit WimaGlobalMeasurementPolygonEditor(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: -}; - -#endif // WIMAGLOBALMEASUREMENTPOLYGONEDITOR_H \ No newline at end of file diff --git a/src/WimaView/WimaItemEditor.qml b/src/WimaView/WimaItemEditor.qml index 050f2d63113adb290d46f7268061759741d7cbaf..5a48c9f00978b5dbc67e94c09d4ece82bd79e140 100644 --- a/src/WimaView/WimaItemEditor.qml +++ b/src/WimaView/WimaItemEditor.qml @@ -32,7 +32,6 @@ Rectangle { property var _masterController: masterController property var _missionController: _masterController.missionController - property var _polygon: areaItem.polygon property bool interactive: areaItem.interactive property color _outerTextColor: interactive ? qgcPal.primaryButtonText : qgcPal.text property real _sectionSpacer: ScreenTools.defaultFontPixelWidth / 2 // spacing between section headings @@ -95,8 +94,8 @@ Rectangle { id: hamburgerMenu MenuItem { - text: qsTr("Add Operating Area") - onTriggered: wimaController.addGlobalMeasurementArea() + text: qsTr("Add Operation Area") + onTriggered: wimaController.addGOperationArea() } MenuItem { diff --git a/src/WimaView/WimaMapPolygonVisuals.qml b/src/WimaView/WimaMapPolygonVisuals.qml index 9c36e13c5bfc938decd97e1b1eba471841e202c1..212439abcc690be0ed7e5f29d35c38e54ba29090 100644 --- a/src/WimaView/WimaMapPolygonVisuals.qml +++ b/src/WimaView/WimaMapPolygonVisuals.qml @@ -1,5 +1,563 @@ -import QtQuick 2.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 QtQuick.Dialogs 1.2 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.ShapeFileHelper 1.0 + +/// QGCMapPolygon map visuals Item { + id: _root + + property var qgcView ///< QGCView for popping dialogs + property var mapControl ///< Map control to place item in + property var mapPolygon ///< QGCMapPolygon object + property bool interactive: mapPolygon.interactive + property color interiorColor: "transparent" + property real interiorOpacity: 1 + property int borderWidth: 0 + property color borderColor: "black" + property bool initPolygon: false + + property var _polygonComponent + property var _dragHandlesComponent + property var _splitHandlesComponent + property var _centerDragHandleComponent + property bool _circle: false + property real _circleRadius + property bool _editCircleRadius: false + + property real _zorderDragHandle: QGroundControl.zOrderMapItems + 3 // Highest to prevent splitting when items overlap + property real _zorderSplitHandle: QGroundControl.zOrderMapItems + 2 + property real _zorderCenterHandle: QGroundControl.zOrderMapItems + 1 // Lowest such that drag or split takes precedence + + function addVisuals() { + _polygonComponent = polygonComponent.createObject(mapControl) + mapControl.addMapItem(_polygonComponent) + } + + function removeVisuals() { + _polygonComponent.destroy() + } + + function addHandles() { + if (!_dragHandlesComponent) { + _dragHandlesComponent = dragHandlesComponent.createObject(mapControl) + _splitHandlesComponent = splitHandlesComponent.createObject(mapControl) + _centerDragHandleComponent = centerDragHandleComponent.createObject(mapControl) + } + } + + function removeHandles() { + if (_dragHandlesComponent) { + _dragHandlesComponent.destroy() + _dragHandlesComponent = undefined + } + if (_splitHandlesComponent) { + _splitHandlesComponent.destroy() + _splitHandlesComponent = undefined + } + if (_centerDragHandleComponent) { + _centerDragHandleComponent.destroy() + _centerDragHandleComponent = undefined + } + } + + /// Calculate the default/initial 4 sided polygon + function defaultPolygonVertices() { + // Initial polygon is inset to take 2/3rds space + var rect = Qt.rect(mapControl.centerViewport.x, mapControl.centerViewport.y, mapControl.centerViewport.width, mapControl.centerViewport.height) + rect.x += (rect.width * 0.25) / 2 + rect.y += (rect.height * 0.25) / 2 + rect.width *= 0.75 + rect.height *= 0.75 + + var centerCoord = mapControl.toCoordinate(Qt.point(rect.x + (rect.width / 2), rect.y + (rect.height / 2)), false /* clipToViewPort */) + var topLeftCoord = mapControl.toCoordinate(Qt.point(rect.x, rect.y), false /* clipToViewPort */) + var topRightCoord = mapControl.toCoordinate(Qt.point(rect.x + rect.width, rect.y), false /* clipToViewPort */) + var bottomLeftCoord = mapControl.toCoordinate(Qt.point(rect.x, rect.y + rect.height), false /* clipToViewPort */) + var bottomRightCoord = mapControl.toCoordinate(Qt.point(rect.x + rect.width, rect.y + rect.height), false /* clipToViewPort */) + + // Initial polygon has max width and height of 3000 meters + var halfWidthMeters = Math.min(topLeftCoord.distanceTo(topRightCoord), 3000) / 2 + var halfHeightMeters = Math.min(topLeftCoord.distanceTo(bottomLeftCoord), 3000) / 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) + + return [ topLeftCoord, topRightCoord, bottomRightCoord, bottomLeftCoord, centerCoord ] + } + + /// Add an initial 4 sided polygon + function addInitialPolygon() { + if (mapPolygon.count < 3) { + var initialVertices = defaultPolygonVertices() + mapPolygon.appendVertex(initialVertices[0]) + mapPolygon.appendVertex(initialVertices[1]) + mapPolygon.appendVertex(initialVertices[2]) + mapPolygon.appendVertex(initialVertices[3]) + } + } + + /// Reset polygon back to initial default + function resetPolygon() { + var initialVertices = defaultPolygonVertices() + mapPolygon.clear() + for (var i=0; i<4; i++) { + mapPolygon.appendVertex(initialVertices[i]) + } + _circle = false + } + + function setCircleRadius(center, radius) { + var unboundCenter = center.atDistanceAndAzimuth(0, 0) + _circleRadius = radius + var segments = 16 + var angleIncrement = 360 / segments + var angle = 0 + mapPolygon.clear() + for (var i=0; i 3 && menu._editingVertexIndex >= 0) + menu.popup() + } + + function popupCenter() { + menu.popup() + } + + MenuItem { + id: removeVertexItem + visible: !_circle + text: qsTr("Remove vertex") + onTriggered: { + if (menu._editingVertexIndex >= 0) { + mapPolygon.removeVertex(menu._editingVertexIndex) + } + } + } + + MenuSeparator { + visible: removeVertexItem.visible + } + + /*MenuItem { + text: qsTr("Circle" ) + onTriggered: resetCircle() + }* + + /*MenuItem { + text: qsTr("Polygon") + onTriggered: resetPolygon() + }*/ + + /*MenuItem { + text: qsTr("Set radius..." ) + visible: _circle + onTriggered: _editCircleRadius = true + }*/ + + /*MenuItem { + text: qsTr("Edit position..." ) + visible: _circle + onTriggered: qgcView.showDialog(editCenterPositionDialog, qsTr("Edit Center Position"), qgcView.showDialogDefaultWidth, StandardButton.Close) + }*/ + + MenuItem { + text: qsTr("Edit position..." ) + visible: !_circle && menu._editingVertexIndex >= 0 + onTriggered: qgcView.showDialog(editVertexPositionDialog, qsTr("Edit Vertex Position"), qgcView.showDialogDefaultWidth, StandardButton.Close) + } + + /*MenuItem { + text: qsTr("Load KML/SHP...") + onTriggered: kmlOrSHPLoadDialog.openForLoad() + }*/ + } + + Component { + id: polygonComponent + + MapPolygon { + color: interiorColor + opacity: interiorOpacity + border.color: borderColor + border.width: borderWidth + path: mapPolygon.path + } + } + + Component { + id: splitHandleComponent + + MapQuickItem { + id: mapQuickItem + anchorPoint.x: dragHandle.width / 2 + anchorPoint.y: dragHandle.height / 2 + visible: !_circle + + property int vertexIndex + + sourceItem: Rectangle { + id: dragHandle + width: ScreenTools.defaultFontPixelHeight * 1.5 + height: width + radius: width / 2 + border.color: "white" + color: "transparent" + opacity: .50 + z: _zorderSplitHandle + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + text: "+" + } + QGCMouseArea { + fillItem: parent + onClicked: mapPolygon.splitPolygonSegment(mapQuickItem.vertexIndex) + } + } + } + } + + Component { + id: splitHandlesComponent + + Repeater { + model: mapPolygon.path + + delegate: Item { + property var _splitHandle + property var _vertices: mapPolygon.path + + function _setHandlePosition() { + var nextIndex = index + 1 + if (nextIndex > _vertices.length - 1) { + nextIndex = 0 + } + var distance = _vertices[index].distanceTo(_vertices[nextIndex]) + var azimuth = _vertices[index].azimuthTo(_vertices[nextIndex]) + _splitHandle.coordinate = _vertices[index].atDistanceAndAzimuth(distance / 2, azimuth) + } + + Component.onCompleted: { + _splitHandle = splitHandleComponent.createObject(mapControl) + _splitHandle.vertexIndex = index + _setHandlePosition() + mapControl.addMapItem(_splitHandle) + } + + Component.onDestruction: { + if (_splitHandle) { + _splitHandle.destroy() + } + } + } + } + } + + // Control which is used to drag polygon vertices + Component { + id: dragAreaComponent + + MissionItemIndicatorDrag { + id: dragArea + mapControl: _root.mapControl + z: _zorderDragHandle + visible: !_circle + onDragStop: mapPolygon.verifyClockwiseWinding() + + property int polygonVertex + + property bool _creationComplete: false + + Component.onCompleted: _creationComplete = true + + onItemCoordinateChanged: { + if (_creationComplete) { + // During component creation some bad coordinate values got through which screws up draw + mapPolygon.adjustVertex(polygonVertex, itemCoordinate) + } + } + + onClicked: menu.popupVertex(polygonVertex) + } + } + + Component { + id: centerDragHandle + MapQuickItem { + id: mapQuickItem + anchorPoint.x: dragHandle.width * 0.5 + anchorPoint.y: dragHandle.height * 0.5 + z: _zorderDragHandle + sourceItem: Rectangle { + id: dragHandle + width: ScreenTools.defaultFontPixelHeight * 1.5 + height: width + radius: width * 0.5 + color: Qt.rgba(1,1,1,0.8) + border.color: Qt.rgba(0,0,0,0.25) + border.width: 1 + QGCColoredImage { + width: parent.width + height: width + color: Qt.rgba(0,0,0,1) + mipmap: true + fillMode: Image.PreserveAspectFit + source: "/qmlimages/MapCenter.svg" + sourceSize.height: height + anchors.centerIn: parent + } + } + } + } + + Component { + id: dragHandleComponent + + MapQuickItem { + id: mapQuickItem + anchorPoint.x: dragHandle.width / 2 + anchorPoint.y: dragHandle.height / 2 + z: _zorderDragHandle + visible: !_circle + + property int polygonVertex + + sourceItem: Rectangle { + id: dragHandle + width: ScreenTools.defaultFontPixelHeight * 1.5 + height: width + radius: width * 0.5 + color: Qt.rgba(1,1,1,0.8) + border.color: Qt.rgba(0,0,0,0.25) + border.width: 1 + } + } + } + + // Add all polygon vertex drag handles to the map + Component { + id: dragHandlesComponent + + Repeater { + model: mapPolygon.pathModel + + delegate: Item { + property var _visuals: [ ] + + Component.onCompleted: { + var dragHandle = dragHandleComponent.createObject(mapControl) + dragHandle.coordinate = Qt.binding(function() { return object.coordinate }) + dragHandle.polygonVertex = Qt.binding(function() { return index }) + mapControl.addMapItem(dragHandle) + var dragArea = dragAreaComponent.createObject(mapControl, { "itemIndicator": dragHandle, "itemCoordinate": object.coordinate }) + dragArea.polygonVertex = Qt.binding(function() { return index }) + _visuals.push(dragHandle) + _visuals.push(dragArea) + } + + Component.onDestruction: { + for (var i=0; i<_visuals.length; i++) { + _visuals[i].destroy() + } + _visuals = [ ] + } + } + } + } + + Component { + id: editCenterPositionDialog + + EditPositionDialog { + coordinate: mapPolygon.center + onCoordinateChanged: { + // Prevent spamming signals on vertex changes by setting centerDrag = true when changing center position. + // This also fixes a bug where Qt gets confused by all the signalling and draws a bad visual. + mapPolygon.centerDrag = true + mapPolygon.center = coordinate + mapPolygon.centerDrag = false + } + } + } + + Component { + id: editVertexPositionDialog + + EditPositionDialog { + coordinate: mapPolygon.vertexCoordinate(menu._editingVertexIndex) + onCoordinateChanged: { + mapPolygon.adjustVertex(menu._editingVertexIndex, coordinate) + mapPolygon.verifyClockwiseWinding() + } + } + } + + Component { + id: centerDragAreaComponent + + MissionItemIndicatorDrag { + mapControl: _root.mapControl + z: _zorderCenterHandle + onItemCoordinateChanged: mapPolygon.center = itemCoordinate + onDragStart: mapPolygon.centerDrag = true + onDragStop: mapPolygon.centerDrag = false + + onClicked: menu.popupCenter() + + function setRadiusFromDialog() { + var radius = QGroundControl.appSettingsDistanceUnitsToMeters(radiusField.text) + setCircleRadius(mapPolygon.center, radius) + _editCircleRadius = false + } + + Rectangle { + anchors.margins: _margin + anchors.left: parent.right + width: radiusColumn.width + (_margin *2) + height: radiusColumn.height + (_margin *2) + color: qgcPal.window + border.color: qgcPal.text + visible: _editCircleRadius + + Column { + id: radiusColumn + anchors.margins: _margin + anchors.left: parent.left + anchors.top: parent.top + spacing: _margin + + QGCLabel { text: qsTr("Radius:") } + + QGCTextField { + id: radiusField + showUnits: true + unitsLabel: QGroundControl.appSettingsDistanceUnitsString + text: QGroundControl.metersToAppSettingsDistanceUnits(_circleRadius).toFixed(2) + onEditingFinished: setRadiusFromDialog() + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + } + + QGCLabel { + anchors.right: radiusColumn.right + anchors.top: radiusColumn.top + text: "X" + + QGCMouseArea { + fillItem: parent + onClicked: setRadiusFromDialog() + } + } + } + } + } + + Component { + id: centerDragHandleComponent + + Item { + property var dragHandle + property var dragArea + + Component.onCompleted: { + dragHandle = centerDragHandle.createObject(mapControl) + dragHandle.coordinate = Qt.binding(function() { return mapPolygon.center }) + mapControl.addMapItem(dragHandle) + dragArea = centerDragAreaComponent.createObject(mapControl, { "itemIndicator": dragHandle, "itemCoordinate": mapPolygon.center }) + } + + Component.onDestruction: { + dragHandle.destroy() + dragArea.destroy() + } + } + } } + diff --git a/src/WimaView/WimaMapPolylineVisuals.qml b/src/WimaView/WimaMapPolylineVisuals.qml index 9c36e13c5bfc938decd97e1b1eba471841e202c1..7f0e5444b4c4d389ff34dd84c10d6579bd8580ad 100644 --- a/src/WimaView/WimaMapPolylineVisuals.qml +++ b/src/WimaView/WimaMapPolylineVisuals.qml @@ -1,5 +1,347 @@ -import QtQuick 2.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 QtQuick.Dialogs 1.2 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.ShapeFileHelper 1.0 + +/// QGCmapPolyline map visuals Item { + id: _root + + property var qgcView ///< QGCView for popping dialogs + property var mapControl ///< Map control to place item in + property var mapPolyline ///< QGCMapPolyline object + property bool interactive: mapPolyline.interactive + property int lineWidth: 3 + property color lineColor: "#be781c" + property bool enableSplitHandels: true + property bool enableDragHandels: true + property bool edgeHandelsOnly: false + + + property var _polylineComponent + property var _dragHandlesComponent + property var _splitHandlesComponent + + property real _zorderDragHandle: QGroundControl.zOrderMapItems + 3 // Highest to prevent splitting when items overlap + property real _zorderSplitHandle: QGroundControl.zOrderMapItems + 2 + + function addVisuals() { + _polylineComponent = polylineComponent.createObject(mapControl) + mapControl.addMapItem(_polylineComponent) + } + + function removeVisuals() { + _polylineComponent.destroy() + } + + function addHandles() { + if (!_dragHandlesComponent) { + if (enableDragHandels){ + _dragHandlesComponent = dragHandlesComponent.createObject(mapControl) + } + + if (enableSplitHandels){ + _splitHandlesComponent = splitHandlesComponent.createObject(mapControl) + } + } + } + + function removeHandles() { + if (_dragHandlesComponent) { + _dragHandlesComponent.destroy() + _dragHandlesComponent = undefined + } + if (_splitHandlesComponent) { + _splitHandlesComponent.destroy() + _splitHandlesComponent = undefined + } + } + + /// Calculate the default/initial polyline + function defaultPolylineVertices() { + var x = map.centerViewport.x + (map.centerViewport.width / 2) + var yInset = map.centerViewport.height / 4 + var topPointCoord = map.toCoordinate(Qt.point(x, map.centerViewport.y + yInset), false /* clipToViewPort */) + var bottomPointCoord = map.toCoordinate(Qt.point(x, map.centerViewport.y + map.centerViewport.height - yInset), false /* clipToViewPort */) + return [ topPointCoord, bottomPointCoord ] + } + + /// Add an initial 2 point polyline + function addInitialPolyline() { + if (mapPolyline.count < 2) { + mapPolyline.clear() + var initialVertices = defaultPolylineVertices() + mapPolyline.appendVertex(initialVertices[0]) + mapPolyline.appendVertex(initialVertices[1]) + } + } + + /// Reset polyline back to initial default + function resetPolyline() { + mapPolyline.clear() + addInitialPolyline() + } + + onInteractiveChanged: { + if (interactive) { + addHandles() + } else { + removeHandles() + } + } + + Component.onCompleted: { + addVisuals() + if (interactive) { + addHandles() + } + } + + Component.onDestruction: { + removeVisuals() + removeHandles() + } + + QGCPalette { id: qgcPal } + + QGCFileDialog { + id: kmlLoadDialog + qgcView: _root.qgcView + folder: QGroundControl.settingsManager.appSettings.missionSavePath + title: qsTr("Select KML File") + selectExisting: true + nameFilters: ShapeFileHelper.fileDialogKMLFilters + fileExtension: QGroundControl.settingsManager.appSettings.kmlFileExtension + + onAcceptedForLoad: { + mapPolyline.loadKMLFile(file) + close() + } + } + + Menu { + id: menu + property int _removeVertexIndex + + function popUpWithIndex(curIndex) { + _removeVertexIndex = curIndex + removeVertexItem.visible = mapPolyline.count > 2 + menu.popup() + } + + MenuItem { + id: removeVertexItem + text: qsTr("Remove vertex" ) + onTriggered: mapPolyline.removeVertex(menu._removeVertexIndex) + } + + MenuSeparator { + visible: removeVertexItem.visible + } + + MenuItem { + text: qsTr("Edit position..." ) + onTriggered: qgcView.showDialog(editPositionDialog, qsTr("Edit Position"), qgcView.showDialogDefaultWidth, StandardButton.Cancel) + } + + /*MenuItem { + text: qsTr("Load KML...") + onTriggered: kmlLoadDialog.openForLoad() + }*/ + } + + Component { + id: editPositionDialog + + EditPositionDialog { + Component.onCompleted: coordinate = mapPolyline.path[menu._removeVertexIndex] + onCoordinateChanged: mapPolyline.adjustVertex(menu._removeVertexIndex,coordinate) + } + } + + Component { + id: polylineComponent + + MapPolyline { + line.width: lineWidth + line.color: lineColor + path: mapPolyline.path + } + } + Component { + id: splitHandleComponent + + MapQuickItem { + id: mapQuickItem + anchorPoint.x: splitHandle.width / 2 + anchorPoint.y: splitHandle.height / 2 + + property int vertexIndex + + sourceItem: Rectangle { + id: splitHandle + width: ScreenTools.defaultFontPixelHeight * 1.5 + height: width + radius: width / 2 + border.color: "white" + color: "transparent" + opacity: .50 + z: _zorderSplitHandle + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + text: "+" + } + + QGCMouseArea { + fillItem: parent + onClicked: mapPolyline.splitSegment(mapQuickItem.vertexIndex) + } + } + } + } + + Component { + id: splitHandlesComponent + + Repeater { + model: mapPolyline.path + + delegate: Item { + property var _splitHandle + property var _vertices: mapPolyline.path + + function _setHandlePosition() { + var nextIndex = index + 1 + var distance = _vertices[index].distanceTo(_vertices[nextIndex]) + var azimuth = _vertices[index].azimuthTo(_vertices[nextIndex]) + _splitHandle.coordinate = _vertices[index].atDistanceAndAzimuth(distance / 2, azimuth) + } + + Component.onCompleted: { + if (index + 1 <= _vertices.length - 1) { + _splitHandle = splitHandleComponent.createObject(mapControl) + _splitHandle.vertexIndex = index + _setHandlePosition() + mapControl.addMapItem(_splitHandle) + } + } + + Component.onDestruction: { + if (_splitHandle) { + _splitHandle.destroy() + } + } + } + } + } + + // Control which is used to drag polygon vertices + Component { + id: dragAreaComponent + + MissionItemIndicatorDrag { + mapControl: _root.mapControl + id: dragArea + z: _zorderDragHandle + + property int polylineVertex + + property bool _creationComplete: false + + Component.onCompleted: _creationComplete = true + + onItemCoordinateChanged: { + if (_creationComplete) { + // During component creation some bad coordinate values got through which screws up draw + mapPolyline.adjustVertex(polylineVertex, itemCoordinate) + } + } + + onClicked: { + menu.popUpWithIndex(polylineVertex) + } + onDragStop: { + if (_creationComplete) { + // During component creation some bad coordinate values got through which screws up draw + mapPolyline.snapVertices(polylineVertex) + } + } + + } + } + + Component { + id: dragHandleComponent + + MapQuickItem { + id: mapQuickItem + anchorPoint.x: dragHandle.width / 2 + anchorPoint.y: dragHandle.height / 2 + z: _zorderDragHandle + + property int polylineVertex + + sourceItem: Rectangle { + id: dragHandle + width: ScreenTools.defaultFontPixelHeight * 1.5 + height: width + radius: width * 0.5 + color: Qt.rgba(1,1,1,0.8) + border.color: Qt.rgba(0,0,0,0.25) + border.width: 1 + } + } + } + + // Add all polygon vertex drag handles to the map + Component { + id: dragHandlesComponent + + Repeater { + model: mapPolyline.pathModel + + delegate: Item { + property var _visuals: [ ] + + Component.onCompleted: { + var dragHandle = dragHandleComponent.createObject(mapControl) + dragHandle.coordinate = Qt.binding(function() { return object.coordinate }) + dragHandle.polylineVertex = Qt.binding(function() { return index }) + mapControl.addMapItem(dragHandle) + var dragArea = dragAreaComponent.createObject(mapControl, { "itemIndicator": dragHandle, "itemCoordinate": object.coordinate }) + dragArea.polylineVertex = Qt.binding(function() { return index }) + _visuals.push(dragHandle) + _visuals.push(dragArea) + } + + Component.onDestruction: { + for (var i=0; i<_visuals.length; i++) { + _visuals[i].destroy() + } + _visuals = [ ] + } + } + } + } } + diff --git a/src/WimaView/WimaServiceAreaMapVisual.qml b/src/WimaView/WimaServiceAreaMapVisual.qml index 9c36e13c5bfc938decd97e1b1eba471841e202c1..189a997f47f9818f36bd14d2a53dcae62bfa8ca0 100644 --- a/src/WimaView/WimaServiceAreaMapVisual.qml +++ b/src/WimaView/WimaServiceAreaMapVisual.qml @@ -1,5 +1,84 @@ -import QtQuick 2.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 _polygon: object + + 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: { + } + + WimaMapPolygonVisuals { + qgcView: _root.qgcView + mapControl: map + mapPolygon: _polygon + borderWidth: 1 + borderColor: "black" + interiorColor: "yellow" + interiorOpacity: 0.25 + } + + + } diff --git a/WimaGlobalMeasurementPolygonMapVisual.qml b/src/WimaView/WimaServicePolygonMapVisual.qml similarity index 87% rename from WimaGlobalMeasurementPolygonMapVisual.qml rename to src/WimaView/WimaServicePolygonMapVisual.qml index f7552276e9cd1ea729da393877baa3168aa06ad1..8fec7f55af9a07f780fc95aebd1392600b9cc1df 100644 --- a/WimaGlobalMeasurementPolygonMapVisual.qml +++ b/src/WimaView/WimaServicePolygonMapVisual.qml @@ -27,7 +27,6 @@ Item { property var _missionItem: object property var _polygon: object.polygon - property var _polyline: object.polyline signal clicked(int sequenceNumber) @@ -38,8 +37,8 @@ Item { 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.75 - rect.height *= 0.75 + 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 */) @@ -74,24 +73,14 @@ Item { qgcView: _root.qgcView mapControl: map mapPolygon: _polygon - interactive: _missionItem.isCurrentItem + interactive: _missionItem.isCurrentPolygon borderWidth: 1 borderColor: "black" - interiorColor: "green" - interiorOpacity: 1 - } - 1 - - QGCMapPolylineVisuals { - id: mapPolylineVisuals - qgcView: _root.qgcView - mapControl: map - mapPolyline: _polyline - interactive: true - lineWidth: 3 - lineColor: "blue" + interiorColor: "yellow" + interiorOpacity: 0.25 } + } diff --git a/src/WimaView/WimaView.qml b/src/WimaView/WimaView.qml index 1941577f97a487243d6f0ce82442c2b590375d58..d515b5a65d35e44b03ac75ea4d6647fa1bf9b724 100644 --- a/src/WimaView/WimaView.qml +++ b/src/WimaView/WimaView.qml @@ -610,7 +610,7 @@ QGCView { onClicked: { switch (index) { case 1: - wimaController.addGlobalMeasurementArea(); + wimaController.addGOperationArea(); //addComplexItem(_missionController.complexMissionItemNames[2]) /*_addWaypointOnClick = checked _addROIOnClick = false*/ @@ -1154,7 +1154,7 @@ QGCView { color: "lightsteelblue" radius: 1 Text { - text: "Hello World!" + text: "" } } } diff --git a/src/WimaView/flyAreaPolygonMapVisual.qml b/src/WimaView/flyAreaPolygonMapVisual.qml deleted file mode 100644 index 4c751114f4293908787d7ec4f7023677229c158b..0000000000000000000000000000000000000000 --- a/src/WimaView/flyAreaPolygonMapVisual.qml +++ /dev/null @@ -1,79 +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 - -/// Survey Complex Mission Item visuals -Item { - id: _root - - property var map ///< Map control to place item in - property var qgcView ///< QGCView to use for popping dialogs - property var _flyAreaPolygon - - - - - /// Add an initial 4 sided polygon if there is none - function _addInitialPolygon() { - if (_structurePolygon.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.75 - rect.height *= 0.75 - - 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) - - _structurePolygon.appendVertex(topLeftCoord) - _structurePolygon.appendVertex(topRightCoord) - _structurePolygon.appendVertex(bottomRightCoord) - _structurePolygon.appendVertex(bottomLeftCoord) - } - } - - Component.onCompleted: { - _addInitialPolygon() - } - - QGCMapPolygonVisuals { - qgcView: _root.qgcView - mapControl: map - mapPolygon: _flyAreaPolygon - interactive: true - borderWidth: 1 - borderColor: "black" - interiorColor: "green" - interiorOpacity: 0.25 - } - -}