Commit dd135422 authored by Valentin Platzgummer's avatar Valentin Platzgummer

editing added to RouteComplexItem

parent 0877c5b7
...@@ -421,6 +421,8 @@ INCLUDEPATH += \ ...@@ -421,6 +421,8 @@ INCLUDEPATH += \
src/Vehicle \ src/Vehicle \
src/Audio \ src/Audio \
src/comm \ src/comm \
src/RouteMissionItem \
src/RouteMissionItem/geometry \
src/comm/ros_bridge \ src/comm/ros_bridge \
src/input \ src/input \
src/lib/qmapcontrol \ src/lib/qmapcontrol \
...@@ -445,7 +447,11 @@ contains (DEFINES, QGC_ENABLE_PAIRING) { ...@@ -445,7 +447,11 @@ contains (DEFINES, QGC_ENABLE_PAIRING) {
HEADERS += \ HEADERS += \
src/QmlControls/QmlUnitsConversion.h \ src/QmlControls/QmlUnitsConversion.h \
src/RouteMissionItem/geometry/GeoArea.h \
src/RouteMissionItem/geometry/MeasurementArea.h \
src/RouteMissionItem/geometry/SafeArea.h \
src/Vehicle/VehicleEscStatusFactGroup.h \ src/Vehicle/VehicleEscStatusFactGroup.h \
src/RouteMissionItem/AreaData.h \
src/RouteMissionItem/RouteComplexItem.h \ src/RouteMissionItem/RouteComplexItem.h \
src/RouteMissionItem/GenericSingelton.h \ src/RouteMissionItem/GenericSingelton.h \
src/RouteMissionItem/geometry/GenericCircle.h \ src/RouteMissionItem/geometry/GenericCircle.h \
...@@ -492,12 +498,6 @@ HEADERS += \ ...@@ -492,12 +498,6 @@ HEADERS += \
src/api/QGCSettings.h \ src/api/QGCSettings.h \
src/api/QmlComponentInfo.h \ src/api/QmlComponentInfo.h \
src/GPS/Drivers/src/base_station.h \ src/GPS/Drivers/src/base_station.h \
src/RouteMissionItem/geometry/WimaArea.h \
src/RouteMissionItem/geometry/WimaServiceArea.h \
src/RouteMissionItem/geometry/WimaMeasurementArea.h \
src/RouteMissionItem/geometry/PlanimetryCalculus.h \
src/RouteMissionItem/geometry/PolygonCalculus.h \
src/RouteMissionItem/OptimisationTools.h \
src/Settings/WimaSettings.h \ src/Settings/WimaSettings.h \
src/comm/ros_bridge/include/RosBridgeClient.h \ src/comm/ros_bridge/include/RosBridgeClient.h \
src/comm/ros_bridge/include/com_private.h \ src/comm/ros_bridge/include/com_private.h \
...@@ -522,6 +522,9 @@ contains (DEFINES, QGC_ENABLE_PAIRING) { ...@@ -522,6 +522,9 @@ contains (DEFINES, QGC_ENABLE_PAIRING) {
} }
SOURCES += \ SOURCES += \
src/RouteMissionItem/geometry/GeoArea.cc \
src/RouteMissionItem/geometry/MeasurementArea.cc \
src/RouteMissionItem/geometry/SafeArea.cc \
src/Vehicle/VehicleEscStatusFactGroup.cc \ src/Vehicle/VehicleEscStatusFactGroup.cc \
src/RouteMissionItem/AreaData.cc \ src/RouteMissionItem/AreaData.cc \
src/api/QGCCorePlugin.cc \ src/api/QGCCorePlugin.cc \
...@@ -554,12 +557,6 @@ SOURCES += \ ...@@ -554,12 +557,6 @@ SOURCES += \
src/comm/ros_bridge/include/server.cpp \ src/comm/ros_bridge/include/server.cpp \
src/comm/ros_bridge/include/topic_publisher.cpp \ src/comm/ros_bridge/include/topic_publisher.cpp \
src/comm/ros_bridge/include/topic_subscriber.cpp \ src/comm/ros_bridge/include/topic_subscriber.cpp \
src/RouteMissionItem/geometry/WimaArea.cc \
src/RouteMissionItem/geometry/WimaServiceArea.cc \
src/RouteMissionItem/geometry/WimaMeasurementArea.cc \
src/RouteMissionItem/geometry/PlanimetryCalculus.cc \
src/RouteMissionItem/OptimisationTools.cc \
src/RouteMissionItem/geometry/PolygonCalculus.cc \
src/Settings/WimaSettings.cc \ src/Settings/WimaSettings.cc \
src/comm/ros_bridge/src/ros_bridge.cpp src/comm/ros_bridge/src/ros_bridge.cpp
......
...@@ -261,7 +261,6 @@ ...@@ -261,7 +261,6 @@
<file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file> <file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file>
<file alias="RadioComponent.qml">src/AutoPilotPlugins/Common/RadioComponent.qml</file> <file alias="RadioComponent.qml">src/AutoPilotPlugins/Common/RadioComponent.qml</file>
<file alias="SerialSettings.qml">src/ui/preferences/SerialSettings.qml</file> <file alias="SerialSettings.qml">src/ui/preferences/SerialSettings.qml</file>
<file alias="Wima/WimaAreaNoVisual.qml">src/Wima/Snake/WimaAreaNoVisual.qml</file>
<file alias="CircularGeneratorEditor.qml">src/WimaView/CircularGeneratorEditor.qml</file> <file alias="CircularGeneratorEditor.qml">src/WimaView/CircularGeneratorEditor.qml</file>
<file alias="QGroundControl/Controls/CircularGeneratorMapVisual.qml">src/WimaView/CircularGeneratorMapVisual.qml</file> <file alias="QGroundControl/Controls/CircularGeneratorMapVisual.qml">src/WimaView/CircularGeneratorMapVisual.qml</file>
<file alias="CircularSurveyItemEditor.qml">src/WimaView/CircularSurveyItemEditor.qml</file> <file alias="CircularSurveyItemEditor.qml">src/WimaView/CircularSurveyItemEditor.qml</file>
...@@ -273,21 +272,14 @@ ...@@ -273,21 +272,14 @@
<file alias="Wima/ProgressIndicator.qml">src/WimaView/ProgressIndicator.qml</file> <file alias="Wima/ProgressIndicator.qml">src/WimaView/ProgressIndicator.qml</file>
<file alias="Wima/qmldir">src/WimaView/Wima.qmldir</file> <file alias="Wima/qmldir">src/WimaView/Wima.qmldir</file>
<file alias="Wima/WimaAreaMapVisual.qml">src/WimaView/WimaAreaMapVisual.qml</file> <file alias="Wima/WimaAreaMapVisual.qml">src/WimaView/WimaAreaMapVisual.qml</file>
<file alias="Wima/WimaCorridorDataVisual.qml">src/WimaView/WimaCorridorDataVisual.qml</file>
<file alias="Wima/WimaCorridorEditor.qml">src/WimaView/WimaCorridorEditor.qml</file> <file alias="Wima/WimaCorridorEditor.qml">src/WimaView/WimaCorridorEditor.qml</file>
<file alias="Wima/WimaCorridorMapVisual.qml">src/WimaView/WimaCorridorMapVisual.qml</file>
<file alias="Wima/WimaItemEditor.qml">src/WimaView/WimaItemEditor.qml</file> <file alias="Wima/WimaItemEditor.qml">src/WimaView/WimaItemEditor.qml</file>
<file alias="Wima/WimaJoinedAreaDataVisual.qml">src/WimaView/WimaJoinedAreaDataVisual.qml</file>
<file alias="Wima/WimaJoinedAreaMapVisual.qml">src/WimaView/WimaJoinedAreaMapVisual.qml</file>
<file alias="Wima/WimaMapPolygonVisuals.qml">src/WimaView/WimaMapPolygonVisuals.qml</file> <file alias="Wima/WimaMapPolygonVisuals.qml">src/WimaView/WimaMapPolygonVisuals.qml</file>
<file alias="Wima/WimaMapPolylineVisuals.qml">src/WimaView/WimaMapPolylineVisuals.qml</file>
<file alias="Wima/WimaMapVisual.qml">src/WimaView/WimaMapVisual.qml</file> <file alias="Wima/WimaMapVisual.qml">src/WimaView/WimaMapVisual.qml</file>
<file alias="Wima/WimaMeasurementAreaDataVisual.qml">src/WimaView/WimaMeasurementAreaDataVisual.qml</file> <file alias="Wima/WimaMeasurementAreaEditor.qml">src/WimaView/MeasurementAreaEditor.qml</file>
<file alias="Wima/WimaMeasurementAreaEditor.qml">src/WimaView/WimaMeasurementAreaEditor.qml</file> <file alias="Wima/WimaMeasurementAreaMapVisual.qml">src/WimaView/MeasurementAreaMapVisual.qml</file>
<file alias="Wima/WimaMeasurementAreaMapVisual.qml">src/WimaView/WimaMeasurementAreaMapVisual.qml</file> <file alias="Wima/WimaServiceAreaEditor.qml">src/WimaView/SafeAreaEditor.qml</file>
<file alias="Wima/WimaServiceAreaDataVisual.qml">src/WimaView/WimaServiceAreaDataVisual.qml</file> <file alias="Wima/WimaServiceAreaMapVisual.qml">src/WimaView/SafeAreaMapVisual.qml</file>
<file alias="Wima/WimaServiceAreaEditor.qml">src/WimaView/WimaServiceAreaEditor.qml</file>
<file alias="Wima/WimaServiceAreaMapVisual.qml">src/WimaView/WimaServiceAreaMapVisual.qml</file>
<file alias="Wima/WimaToolBar.qml">src/WimaView/WimaToolBar.qml</file> <file alias="Wima/WimaToolBar.qml">src/WimaView/WimaToolBar.qml</file>
<file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file> <file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file> <file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
...@@ -360,9 +352,9 @@ ...@@ -360,9 +352,9 @@
<file alias="Video.SettingsGroup.json">src/Settings/Video.SettingsGroup.json</file> <file alias="Video.SettingsGroup.json">src/Settings/Video.SettingsGroup.json</file>
<file alias="VTOLLandingPattern.FactMetaData.json">src/MissionManager/VTOLLandingPattern.FactMetaData.json</file> <file alias="VTOLLandingPattern.FactMetaData.json">src/MissionManager/VTOLLandingPattern.FactMetaData.json</file>
<file alias="Wima.SettingsGroup.json">src/Settings/Wima.SettingsGroup.json</file> <file alias="Wima.SettingsGroup.json">src/Settings/Wima.SettingsGroup.json</file>
<file alias="CircularSurvey.SettingsGroup.json">src/Wima/json/CircularSurvey.SettingsGroup.json</file> <file alias="RouteComplexItem.SettingsGroup.json">src/RouteMissionItem/json/RouteComplexItem.SettingsGroup.json</file>
<file alias="LinearGenerator.SettingsGroup.json">src/Wima/Snake/json/LinearGenerator.SettingsGroup.json</file> <file alias="LinearGenerator.SettingsGroup.json">src/RouteMissionItem/json/LinearGenerator.SettingsGroup.json</file>
<file alias="CircularGenerator.SettingsGroup.json">src/Wima/Snake/json/CircularGenerator.SettingsGroup.json</file> <file alias="CircularGenerator.SettingsGroup.json">src/RouteMissionItem/json/CircularGenerator.SettingsGroup.json</file>
</qresource> </qresource>
<qresource prefix="/MockLink"> <qresource prefix="/MockLink">
<file alias="APMArduSubMockLink.params">src/comm/APMArduSubMockLink.params</file> <file alias="APMArduSubMockLink.params">src/comm/APMArduSubMockLink.params</file>
......
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "QmlObjectListModel.h" #include "QmlObjectListModel.h"
class SurveyComplexItem; class SurveyComplexItem;
class CircularSurvey; class RouteComplexItem;
class SimpleMissionItem; class SimpleMissionItem;
class MissionController; class MissionController;
#ifdef UNITTEST_BUILD #ifdef UNITTEST_BUILD
...@@ -153,7 +153,7 @@ private: ...@@ -153,7 +153,7 @@ private:
static const char* _jsonParam4Key; static const char* _jsonParam4Key;
friend class SurveyComplexItem; friend class SurveyComplexItem;
friend class CircularSurvey; friend class RouteComplexItem;
friend class SimpleMissionItem; friend class SimpleMissionItem;
friend class MissionController; friend class MissionController;
#ifdef UNITTEST_BUILD #ifdef UNITTEST_BUILD
......
This diff is collapsed.
#include "WimaPlanData.h" #include "AreaData.h"
AreaData::AreaData(QObject *parent) : QObject(parent) {} #include "geometry/MeasurementArea.h"
#include "geometry/SafeArea.h"
AreaData::AreaData(const AreaData &other, QObject *parent) #include "QGCLoggingCategory.h"
: QObject(parent) { #include "QGCQGeoCoordinate.h"
*this = other;
}
AreaData &AreaData::operator=(const AreaData &other) { QGC_LOGGING_CATEGORY(AreaDataLog, "AreaDataLog")
this->append(other.measurementArea());
this->append(other.serviceArea());
this->append(other.joinedArea());
this->append(other.corridor());
return *this; AreaData::AreaData(QObject *parent) : QObject(parent) {}
}
void AreaData::append(const WimaJoinedAreaData &areaData) { AreaData::~AreaData() {}
if (_joinedArea != areaData) {
_joinedArea = areaData;
emit joinedAreaChanged();
}
}
void AreaData::append(const WimaServiceAreaData &areaData) { AreaData::AreaData(const AreaData &other, QObject *parent) : QObject(parent) {
if (_serviceArea != areaData) { if (!copyAreaList(other._areaList, _areaList, this)) {
_serviceArea = areaData; qCWarning(AreaDataLog) << "AreaData(): not able to copy other._areaList";
emit serviceAreaChanged(); } else {
_origin = other._origin;
} }
} }
void AreaData::append(const WimaCorridorData &areaData) { AreaData &AreaData::operator=(const AreaData &other) {
if (_corridor != areaData) { if (!copyAreaList(other._areaList, _areaList, this)) {
_corridor = areaData; qCWarning(AreaDataLog) << "operator=(): not able to copy other._areaList";
emit corridorChanged(); } else {
_origin = other._origin;
} }
return *this;
} }
void AreaData::append(const WimaMeasurementAreaData &areaData) { bool AreaData::insert(GeoArea *areaData) {
if (_measurementArea != areaData) { {
_measurementArea = areaData; SafeArea *area = qobject_cast<SafeArea *>(areaData);
emit measurementAreaChanged(); if (area != nullptr) {
if (Q_LIKELY(!this->_areaList.contains(area))) {
if (_measurementArea.coordinateList().size() > 0) { _areaList.append(area);
setOrigin(_measurementArea.coordinateList().first()); emit areaList();
} else { return true;
setOrigin(QGeoCoordinate()); } else {
return false;
}
} }
} }
}
void AreaData::append(const WimaJoinedArea &areaData) { {
if (_joinedArea != areaData) { MeasurementArea *area = qobject_cast<MeasurementArea *>(areaData);
_joinedArea = areaData; if (area != nullptr) {
emit joinedAreaChanged(); if (Q_LIKELY(!this->_areaList.contains(area))) {
_areaList.append(area);
emit areaList();
return true;
} else {
return false;
}
}
} }
}
void AreaData::append(const WimaArea &areaData) { return false;
if (_serviceArea != areaData) {
_serviceArea = areaData;
emit serviceAreaChanged();
}
} }
void AreaData::append(const WimaCorridor &areaData) { void AreaData::remove(GeoArea *areaData) {
if (_corridor != areaData) { int index = _areaList.indexOf(areaData);
_corridor = areaData; if (index >= 0) {
emit corridorChanged(); QObject *obj = _areaList.removeAt(index);
}
}
void AreaData::append(const WimaMeasurementArea &areaData) { _setOrigin(_newOrigin());
if (_measurementArea != areaData) {
_measurementArea = areaData;
emit measurementAreaChanged();
if (_measurementArea.coordinateList().size() > 0) { if (obj->parent() == nullptr) {
setOrigin(_measurementArea.coordinateList().first()); obj->deleteLater();
} else {
setOrigin(QGeoCoordinate());
} }
}
}
void AreaData::clear() { *this = AreaData(); }
const QGeoCoordinate &AreaData::origin() const { return _origin; }
bool AreaData::isValid() { emit areaListChanged();
return _measurementArea.coordinateList().size() >= 3 && }
_serviceArea.coordinateList().size() >= 3 && _origin.isValid();
} }
const WimaJoinedAreaData &AreaData::joinedArea() const { void AreaData::clear() {
return this->_joinedArea; if (_areaList.count() > 0) {
for (int i = 0; i < _areaList.count(); ++i) {
remove(_areaList.value<GeoArea *>(i));
}
emit areaListChanged();
}
} }
const WimaServiceAreaData &AreaData::serviceArea() const { QmlObjectListModel *AreaData::areaList() { return &_areaList; }
return this->_serviceArea;
}
const WimaCorridorData &AreaData::corridor() const { const QmlObjectListModel *AreaData::areaList() const { return &_areaList; }
return this->_corridor;
}
const WimaMeasurementAreaData &AreaData::measurementArea() const { const QGeoCoordinate &AreaData::origin() const { return _origin; }
return this->_measurementArea;
}
WimaJoinedAreaData &AreaData::joinedArea() { return this->_joinedArea; } bool AreaData::isValid() const {
qWarning("AreaData::isValid(): impl. incomplete.");
auto *measurementArea = getGeoArea<const MeasurementArea *>(_areaList);
auto *safeArea = getGeoArea<const SafeArea *>(_areaList);
return measurementArea != nullptr && safeArea != nullptr &&
measurementArea->count() >= 3 && safeArea->count() >= 3 &&
_origin.isValid();
}
bool AreaData::tryMakeValid() {
qWarning("AreaData::tryMakeValid(): impl. missing.");
return true;
}
bool AreaData::initialize(const QGeoCoordinate &bottomLeft,
const QGeoCoordinate &topRight) {
// bottomLeft and topRight define the bounding box.
if (bottomLeft.isValid() && topRight.isValid() && bottomLeft != topRight) {
auto *measurementArea = getGeoArea<MeasurementArea *>(_areaList);
auto *safeArea = getGeoArea<SafeArea *>(_areaList);
if (safeArea == nullptr) {
if (!insert(new SafeArea())) {
qCCritical(AreaDataLog)
<< "initialize(): safeArea == nullptr, but insert() failed.";
return false;
}
}
WimaServiceAreaData &AreaData::serviceArea() { return this->_serviceArea; } if (measurementArea == nullptr) {
if (!insert(new MeasurementArea())) {
qCCritical(AreaDataLog) << "initialize(): measurementArea == nullptr, "
"but insert() failed.";
return false;
}
}
WimaCorridorData &AreaData::corridor() { return this->_corridor; } // Fit safe area to bounding box.
safeArea->clear();
safeArea->appendVertex(bottomLeft);
safeArea->appendVertex(
QGeoCoordinate(topRight.latitude(), bottomLeft.longitude()));
safeArea->appendVertex(topRight);
safeArea->appendVertex(
QGeoCoordinate(bottomLeft.latitude(), topRight.longitude()));
// Put measurement area inside safeArea;
measurementArea->clear();
measurementArea->appendVertex(QGeoCoordinate(
0.8 * bottomLeft.latitude() + 0.2 * topRight.latitude(),
0.8 * bottomLeft.longitude() + 0.2 * topRight.longitude()));
measurementArea->appendVertex(QGeoCoordinate(
0.2 * bottomLeft.latitude() + 0.8 * topRight.latitude(),
0.8 * bottomLeft.longitude() + 0.2 * topRight.longitude()));
measurementArea->appendVertex(QGeoCoordinate(
0.2 * bottomLeft.latitude() + 0.8 * topRight.latitude(),
0.2 * bottomLeft.longitude() + 0.8 * topRight.longitude()));
measurementArea->appendVertex(QGeoCoordinate(
0.8 * bottomLeft.latitude() + 0.2 * topRight.latitude(),
0.2 * bottomLeft.longitude() + 0.8 * topRight.longitude()));
return true;
} else {
qCWarning(AreaDataLog)
<< "initialize(): bounding box invaldid (bottomLeft, topRight) "
<< bottomLeft << "," << topRight;
return false;
}
}
WimaMeasurementAreaData &AreaData::measurementArea() { bool AreaData::initialized() {
return this->_measurementArea; auto *measurementArea = getGeoArea<MeasurementArea *>(_areaList);
auto *safeArea = getGeoArea<SafeArea *>(_areaList);
return measurementArea != nullptr && safeArea != nullptr &&
measurementArea->count() >= 3 && safeArea->count() >= 3;
} }
bool AreaData::operator==(const AreaData &other) const { bool AreaData::operator==(const AreaData &other) const {
return this->_joinedArea == other._joinedArea && if (_areaList.count() == other._areaList.count()) {
this->_measurementArea == other._measurementArea && for (int i = 0; i < _areaList.count(); ++i) {
this->_corridor == other._corridor && if (_areaList[i] != other._areaList[i]) {
this->_serviceArea == other._serviceArea; return false;
}
}
return true;
} else {
return false;
}
} }
bool AreaData::operator!=(const AreaData &other) const { bool AreaData::operator!=(const AreaData &other) const {
return !(*this == other); return !(*this == other);
} }
void AreaData::setOrigin(const QGeoCoordinate &origin) { void AreaData::_setOrigin(const QGeoCoordinate &origin) {
if (this->_origin != origin) { if (this->_origin != origin) {
this->_origin = origin; this->_origin = origin;
emit originChanged(); emit originChanged();
} }
} }
QGeoCoordinate AreaData::_newOrigin() {
auto *measurementArea = getGeoArea<MeasurementArea *>(_areaList);
auto *safeArea = getGeoArea<SafeArea *>(_areaList);
if (measurementArea != nullptr && measurementArea->pathModel().count() > 0) {
QGCQGeoCoordinate *ori =
measurementArea->pathModel().value<QGCQGeoCoordinate *>(0);
if (ori != nullptr && ori->coordinate().isValid()) {
return ori->coordinate();
}
}
if (safeArea != nullptr && safeArea->pathModel().count() > 0) {
QGCQGeoCoordinate *ori =
measurementArea->pathModel().value<QGCQGeoCoordinate *>(0);
if (ori != nullptr && ori->coordinate().isValid()) {
return ori->coordinate();
}
}
return QGeoCoordinate();
}
#pragma once
#include <QGeoCoordinate>
#include <QObject>
#include "QmlObjectListModel.h"
class GeoArea;
class SafeArea;
class MeasurementArea;
class AreaData : public QObject {
Q_OBJECT
public:
AreaData(QObject *parent = nullptr);
~AreaData();
AreaData(const AreaData &other, QObject *parent = nullptr);
AreaData &operator=(const AreaData &other);
// Member Methodes
//!
//! \brief insert Inserts the area if areaList does not contain it.
//! \param areaData
bool insert(GeoArea *areaData);
//!
//! \brief remove
//! \param areaData Removes the area.
//! \note Deletes the area if it has no parent.
void remove(GeoArea *areaData);
void clear();
//!
//! \brief areaList
//! \return Returns the list of areas.
//! \note For Qml use only, don't alter the list, or risk to break invariants.
QmlObjectListModel *areaList();
//!
//! \brief areaList
//! \return Returns the list of areas.
const QmlObjectListModel *areaList() const;
//!
//! \brief origin
//! \return Returns an origin near one of the areas.
//! \note Origin might change if the list of areas changes.
const QGeoCoordinate &origin() const;
Q_INVOKABLE bool isValid() const;
Q_INVOKABLE bool tryMakeValid();
//!
//! \brief initialize Initializes the areas in a valid way, such that they
//! area inside the bounding box. \param bottomLeft bottom left corner of the
//! bounding box. \param topRight top right corner of the bounding box. \note
//! Behavior is undefined, if \p bottomLeft and \p topRight are not the bottom
//! left and the top right corner of the bounding box. \return Returns true on
//! succes, false either.
//!
Q_INVOKABLE bool initialize(const QGeoCoordinate &bottomLeft,
const QGeoCoordinate &topRight);
//!
//! \brief initialized Checks if area data is initialized
//! \return Returns true if area list contains a SafeArea and a
//! MeasurementArea and both areas have atleast three vertices, returns false
//! either.
//!
Q_INVOKABLE bool initialized();
bool operator==(const AreaData &other) const;
bool operator!=(const AreaData &other) const;
signals:
void areaListChanged();
void originChanged();
private:
void _setOrigin(const QGeoCoordinate &origin);
QGeoCoordinate _newOrigin();
QGeoCoordinate _origin;
QmlObjectListModel _areaList;
};
#include "CircularGenerator.h" #include "CircularGenerator.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
QGC_LOGGING_CATEGORY(CircularGeneratorLog, "CircularGeneratorLog") #include "SettingsFact.h"
#define CLIPPER_SCALE 1000000 #define CLIPPER_SCALE 1000000
#include "Wima/Geometry/GenericCircle.h" #include "RoutingThread.h"
#include "clipper/clipper.hpp" #include "geometry/GenericCircle.h"
#include "geometry/MeasurementArea.h"
#include "geometry/SafeArea.h"
#include "geometry/clipper/clipper.hpp"
#include "nemo_interface/SnakeTile.h"
QGC_LOGGING_CATEGORY(CircularGeneratorLog, "CircularGeneratorLog")
using namespace ClipperLib; using namespace ClipperLib;
template <> inline auto get<0>(const IntPoint &p) { return p.X; } template <> inline auto get<0>(const IntPoint &p) { return p.X; }
template <> inline auto get<1>(const IntPoint &p) { return p.Y; } template <> inline auto get<1>(const IntPoint &p) { return p.Y; }
#include "SnakeTile.h"
#include "Wima/RoutingThread.h"
namespace routing { namespace routing {
bool circularTransects(const snake::FPoint &reference, bool circularTransects(const snake::FPoint &reference,
...@@ -77,7 +80,13 @@ bool CircularGenerator::get(Generator &generator) { ...@@ -77,7 +80,13 @@ bool CircularGenerator::get(Generator &generator) {
snake::FPoint reference; snake::FPoint reference;
snake::toENU(origin, ref, reference); snake::toENU(origin, ref, reference);
auto geoPolygon = this->_d->measurementArea().coordinateList(); auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
if (measurementArea == nullptr) {
qCDebug(CircularGeneratorLog) << "get(): measurement area == nullptr";
return false;
}
auto geoPolygon = measurementArea->coordinateList();
for (auto &v : geoPolygon) { for (auto &v : geoPolygon) {
if (v.isValid()) { if (v.isValid()) {
v.setAltitude(0); v.setAltitude(0);
...@@ -93,8 +102,8 @@ bool CircularGenerator::get(Generator &generator) { ...@@ -93,8 +102,8 @@ bool CircularGenerator::get(Generator &generator) {
snake::areaToEnu(origin, geoPolygon, *pPolygon); snake::areaToEnu(origin, geoPolygon, *pPolygon);
// Progress and tiles. // Progress and tiles.
const auto &progress = this->_d->measurementArea().progress(); const auto &progress = measurementArea->progress();
const auto *tiles = this->_d->measurementArea().tiles(); const auto *tiles = measurementArea->tiles();
auto pTiles = std::make_shared<std::vector<snake::FPolygon>>(); auto pTiles = std::make_shared<std::vector<snake::FPolygon>>();
if (progress.size() == tiles->count()) { if (progress.size() == tiles->count()) {
for (int i = 0; i < tiles->count(); ++i) { for (int i = 0; i < tiles->count(); ++i) {
...@@ -119,7 +128,12 @@ bool CircularGenerator::get(Generator &generator) { ...@@ -119,7 +128,12 @@ bool CircularGenerator::get(Generator &generator) {
return false; return false;
} }
auto geoDepot = this->_d->serviceArea().depot(); auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
if (measurementArea == nullptr) {
qCDebug(CircularGeneratorLog) << "get(): measurement area == nullptr";
return false;
}
auto geoDepot = serviceArea->depot();
if (!geoDepot.isValid()) { if (!geoDepot.isValid()) {
qCDebug(CircularGeneratorLog) << "get(): depot invalid." << geoDepot; qCDebug(CircularGeneratorLog) << "get(): depot invalid." << geoDepot;
return false; return false;
...@@ -169,73 +183,85 @@ void CircularGenerator::resetReferenceIfInvalid() { ...@@ -169,73 +183,85 @@ void CircularGenerator::resetReferenceIfInvalid() {
} }
void CircularGenerator::resetReference() { void CircularGenerator::resetReference() {
if (this->_d->measurementArea().center().isValid()) { auto measurementArea =
setReference(this->_d->measurementArea().center()); getGeoArea<const MeasurementArea *>(*this->_d->areaList());
if (measurementArea != nullptr) {
if (measurementArea->center().isValid()) {
setReference(measurementArea->center());
} else {
qCWarning(CircularGeneratorLog)
<< "measurement area center" << measurementArea->center();
}
} else { } else {
qCWarning(CircularGeneratorLog) qCDebug(CircularGeneratorLog)
<< "measurement area center" << this->_d->measurementArea().center(); << "resetReference(): measurement area == nullptr";
} }
} }
void CircularGenerator::establishConnections() { void CircularGenerator::establishConnections() {
if (this->_d && !this->_connectionsEstablished) { if (this->_d && !this->_connectionsEstablished) {
connect(this->_d.get(), &AreaData::originChanged, this, auto measurementArea =
&GeneratorBase::generatorChanged); getGeoArea<const MeasurementArea *>(*this->_d->areaList());
connect(&this->_d->measurementArea(), auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
&WimaMeasurementAreaData::progressChanged, this, if (measurementArea != nullptr && serviceArea != nullptr) {
&GeneratorBase::generatorChanged); GeneratorBase::establishConnections();
connect(&this->_d->measurementArea(),
&WimaMeasurementAreaData::tileDataChanged, this, connect(this->_d, &AreaData::originChanged, this,
&GeneratorBase::generatorChanged); &GeneratorBase::generatorChanged);
connect(&this->_d->measurementArea(), connect(measurementArea, &MeasurementArea::progressChanged, this,
&WimaMeasurementAreaData::centerChanged, this, &GeneratorBase::generatorChanged);
&CircularGenerator::resetReferenceIfInvalid); connect(measurementArea, &MeasurementArea::tilesChanged, this,
connect(&this->_d->measurementArea(), &WimaMeasurementAreaData::pathChanged, &GeneratorBase::generatorChanged);
this, &GeneratorBase::generatorChanged); connect(measurementArea, &MeasurementArea::centerChanged, this,
connect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged, this, &CircularGenerator::resetReferenceIfInvalid);
&GeneratorBase::generatorChanged); connect(measurementArea, &MeasurementArea::pathChanged, this,
connect(&this->_d->joinedArea(), &WimaJoinedAreaData::pathChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(serviceArea, &SafeArea::depotChanged, this,
connect(this->distance(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(this->distance(), &Fact::rawValueChanged, this,
connect(this->deltaAlpha(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(this->deltaAlpha(), &Fact::rawValueChanged, this,
connect(this->minLength(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(this->minLength(), &Fact::rawValueChanged, this,
connect(this, &CircularGenerator::referenceChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(this, &CircularGenerator::referenceChanged, this,
this->_connectionsEstablished = true; &GeneratorBase::generatorChanged);
this->_connectionsEstablished = true;
}
} }
} }
void CircularGenerator::deleteConnections() { void CircularGenerator::deleteConnections() {
if (this->_d && this->_connectionsEstablished) { if (this->_d && this->_connectionsEstablished) {
disconnect(this->_d.get(), &AreaData::originChanged, this, auto measurementArea =
&GeneratorBase::generatorChanged); getGeoArea<const MeasurementArea *>(*this->_d->areaList());
disconnect(&this->_d->measurementArea(), auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
&WimaMeasurementAreaData::progressChanged, this, if (measurementArea != nullptr && serviceArea != nullptr) {
&GeneratorBase::generatorChanged); GeneratorBase::deleteConnections();
disconnect(&this->_d->measurementArea(),
&WimaMeasurementAreaData::tileDataChanged, this, disconnect(this->_d, &AreaData::originChanged, this,
&GeneratorBase::generatorChanged); &GeneratorBase::generatorChanged);
disconnect(&this->_d->measurementArea(), &WimaMeasurementAreaData::center, disconnect(measurementArea, &MeasurementArea::progressChanged, this,
this, &CircularGenerator::resetReferenceIfInvalid); &GeneratorBase::generatorChanged);
disconnect(&this->_d->measurementArea(), disconnect(measurementArea, &MeasurementArea::tilesChanged, this,
&WimaMeasurementAreaData::pathChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(measurementArea, &MeasurementArea::centerChanged, this,
disconnect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged, &CircularGenerator::resetReferenceIfInvalid);
this, &GeneratorBase::generatorChanged); disconnect(measurementArea, &MeasurementArea::pathChanged, this,
disconnect(&this->_d->joinedArea(), &WimaJoinedAreaData::pathChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(serviceArea, &SafeArea::depotChanged, this,
disconnect(this->distance(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(this->distance(), &Fact::rawValueChanged, this,
disconnect(this->deltaAlpha(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(this->deltaAlpha(), &Fact::rawValueChanged, this,
disconnect(this->minLength(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(this->minLength(), &Fact::rawValueChanged, this,
disconnect(this, &CircularGenerator::referenceChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(this, &CircularGenerator::referenceChanged, this,
this->_connectionsEstablished = false; &GeneratorBase::generatorChanged);
this->_connectionsEstablished = true;
}
} }
} }
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include <QGeoCoordinate> #include <QGeoCoordinate>
#include "SettingsFact.h"
namespace routing { namespace routing {
class CircularGenerator : public GeneratorBase { class CircularGenerator : public GeneratorBase {
......
...@@ -12,10 +12,6 @@ GeneratorBase::GeneratorBase(GeneratorBase::Data d, QObject *parent) ...@@ -12,10 +12,6 @@ GeneratorBase::GeneratorBase(GeneratorBase::Data d, QObject *parent)
GeneratorBase::~GeneratorBase() {} GeneratorBase::~GeneratorBase() {}
QString GeneratorBase::editorQml() { return QStringLiteral(""); }
QString GeneratorBase::mapVisualQml() { return QStringLiteral(""); }
GeneratorBase::Data GeneratorBase::data() const { return _d; } GeneratorBase::Data GeneratorBase::data() const { return _d; }
void GeneratorBase::setData(const Data &d) { void GeneratorBase::setData(const Data &d) {
...@@ -28,4 +24,9 @@ void GeneratorBase::establishConnections() {} ...@@ -28,4 +24,9 @@ void GeneratorBase::establishConnections() {}
void GeneratorBase::deleteConnections() {} void GeneratorBase::deleteConnections() {}
void GeneratorBase::_areaListChangedHandler() {
deleteConnections();
establishConnections();
}
} // namespace routing } // namespace routing
...@@ -5,16 +5,16 @@ ...@@ -5,16 +5,16 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include "snake.h" #include "geometry/snake.h"
#include "Wima/WimaPlanData.h" #include "AreaData.h"
namespace routing { namespace routing {
class GeneratorBase : public QObject { class GeneratorBase : public QObject {
Q_OBJECT Q_OBJECT
public: public:
using Data = std::shared_ptr<AreaData>; using Data = AreaData *;
using Generator = std::function<bool(snake::Transects &)>; using Generator = std::function<bool(snake::Transects &)>;
explicit GeneratorBase(QObject *parent = nullptr); explicit GeneratorBase(QObject *parent = nullptr);
...@@ -24,8 +24,8 @@ public: ...@@ -24,8 +24,8 @@ public:
Q_PROPERTY(QString editorQml READ editorQml CONSTANT) Q_PROPERTY(QString editorQml READ editorQml CONSTANT)
Q_PROPERTY(QString mapVisualQml READ mapVisualQml CONSTANT) Q_PROPERTY(QString mapVisualQml READ mapVisualQml CONSTANT)
virtual QString editorQml(); virtual QString editorQml() = 0;
virtual QString mapVisualQml(); virtual QString mapVisualQml() = 0;
virtual QString name() = 0; virtual QString name() = 0;
virtual QString abbreviation() = 0; virtual QString abbreviation() = 0;
...@@ -42,6 +42,9 @@ protected: ...@@ -42,6 +42,9 @@ protected:
virtual void establishConnections(); virtual void establishConnections();
virtual void deleteConnections(); virtual void deleteConnections();
Data _d; Data _d;
private:
void _areaListChangedHandler();
}; };
} // namespace routing } // namespace routing
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
QGC_LOGGING_CATEGORY(LinearGeneratorLog, "LinearGeneratorLog") QGC_LOGGING_CATEGORY(LinearGeneratorLog, "LinearGeneratorLog")
#define CLIPPER_SCALE 1000000 #define CLIPPER_SCALE 1000000
#include "clipper/clipper.hpp" #include "geometry/MeasurementArea.h"
#include "geometry/SafeArea.h"
#include "geometry/clipper/clipper.hpp"
#include "SnakeTile.h" #include "RoutingThread.h"
#include "Wima/RoutingThread.h" #include "nemo_interface/SnakeTile.h"
namespace routing { namespace routing {
...@@ -38,6 +40,8 @@ QString LinearGenerator::editorQml() { ...@@ -38,6 +40,8 @@ QString LinearGenerator::editorQml() {
return QStringLiteral("LinearGeneratorEditor.qml"); return QStringLiteral("LinearGeneratorEditor.qml");
} }
QString LinearGenerator::mapVisualQml() { return QStringLiteral(""); }
QString LinearGenerator::name() { return QStringLiteral("Linear Generator"); } QString LinearGenerator::name() { return QStringLiteral("Linear Generator"); }
QString LinearGenerator::abbreviation() { return QStringLiteral("L. Gen."); } QString LinearGenerator::abbreviation() { return QStringLiteral("L. Gen."); }
...@@ -52,7 +56,13 @@ bool LinearGenerator::get(Generator &generator) { ...@@ -52,7 +56,13 @@ bool LinearGenerator::get(Generator &generator) {
qCDebug(LinearGeneratorLog) << "get(): origin invalid." << origin; qCDebug(LinearGeneratorLog) << "get(): origin invalid." << origin;
} }
auto geoPolygon = this->_d->measurementArea().coordinateList(); auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
if (measurementArea == nullptr) {
qCDebug(LinearGeneratorLog) << "get(): measurement area == nullptr";
return false;
}
auto geoPolygon = measurementArea->coordinateList();
for (auto &v : geoPolygon) { for (auto &v : geoPolygon) {
if (v.isValid()) { if (v.isValid()) {
v.setAltitude(0); v.setAltitude(0);
...@@ -68,8 +78,8 @@ bool LinearGenerator::get(Generator &generator) { ...@@ -68,8 +78,8 @@ bool LinearGenerator::get(Generator &generator) {
snake::areaToEnu(origin, geoPolygon, *pPolygon); snake::areaToEnu(origin, geoPolygon, *pPolygon);
// Progress and tiles. // Progress and tiles.
const auto &progress = this->_d->measurementArea().progress(); const auto &progress = measurementArea->progress();
const auto *tiles = this->_d->measurementArea().tiles(); const auto *tiles = measurementArea->tiles();
auto pTiles = std::make_shared<std::vector<snake::FPolygon>>(); auto pTiles = std::make_shared<std::vector<snake::FPolygon>>();
if (progress.size() == tiles->count()) { if (progress.size() == tiles->count()) {
for (int i = 0; i < tiles->count(); ++i) { for (int i = 0; i < tiles->count(); ++i) {
...@@ -93,7 +103,12 @@ bool LinearGenerator::get(Generator &generator) { ...@@ -93,7 +103,12 @@ bool LinearGenerator::get(Generator &generator) {
return false; return false;
} }
auto geoDepot = this->_d->serviceArea().depot(); auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
if (serviceArea == nullptr) {
qCDebug(LinearGeneratorLog) << "get(): service area == nullptr";
return false;
}
auto geoDepot = serviceArea->depot();
if (!geoDepot.isValid()) { if (!geoDepot.isValid()) {
qCDebug(LinearGeneratorLog) << "get(): depot invalid." << geoDepot; qCDebug(LinearGeneratorLog) << "get(): depot invalid." << geoDepot;
return false; return false;
...@@ -134,53 +149,61 @@ Fact *LinearGenerator::minLength() { return &_minLength; } ...@@ -134,53 +149,61 @@ Fact *LinearGenerator::minLength() { return &_minLength; }
void LinearGenerator::establishConnections() { void LinearGenerator::establishConnections() {
if (this->_d && !this->_connectionsEstablished) { if (this->_d && !this->_connectionsEstablished) {
connect(this->_d.get(), &AreaData::originChanged, this, auto measurementArea =
&GeneratorBase::generatorChanged); getGeoArea<const MeasurementArea *>(*this->_d->areaList());
connect(&this->_d->measurementArea(), auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
&WimaMeasurementAreaData::progressChanged, this,
&GeneratorBase::generatorChanged); if (measurementArea != nullptr && serviceArea != nullptr) {
connect(&this->_d->measurementArea(), GeneratorBase::establishConnections();
&WimaMeasurementAreaData::tileDataChanged, this,
&GeneratorBase::generatorChanged); connect(this->_d, &AreaData::originChanged, this,
connect(&this->_d->measurementArea(), &WimaMeasurementAreaData::pathChanged, &GeneratorBase::generatorChanged);
this, &GeneratorBase::generatorChanged); connect(measurementArea, &MeasurementArea::progressChanged, this,
connect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(measurementArea, &MeasurementArea::tilesChanged, this,
connect(&this->_d->joinedArea(), &WimaJoinedAreaData::pathChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(measurementArea, &MeasurementArea::pathChanged, this,
connect(this->distance(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(serviceArea, &SafeArea::depotChanged, this,
connect(this->alpha(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(this->distance(), &Fact::rawValueChanged, this,
connect(this->minLength(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); connect(this->alpha(), &Fact::rawValueChanged, this,
this->_connectionsEstablished = true; &GeneratorBase::generatorChanged);
connect(this->minLength(), &Fact::rawValueChanged, this,
&GeneratorBase::generatorChanged);
this->_connectionsEstablished = true;
}
} }
} }
void LinearGenerator::deleteConnections() { void LinearGenerator::deleteConnections() {
if (this->_d && this->_connectionsEstablished) { if (this->_d && this->_connectionsEstablished) {
connect(this->_d.get(), &AreaData::originChanged, this, auto measurementArea =
&GeneratorBase::generatorChanged); getGeoArea<const MeasurementArea *>(*this->_d->areaList());
connect(&this->_d->measurementArea(), auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
&WimaMeasurementAreaData::progressChanged, this,
&GeneratorBase::generatorChanged); if (measurementArea != nullptr && serviceArea != nullptr) {
connect(&this->_d->measurementArea(), GeneratorBase::deleteConnections();
&WimaMeasurementAreaData::tileDataChanged, this,
&GeneratorBase::generatorChanged); disconnect(this->_d, &AreaData::originChanged, this,
connect(&this->_d->measurementArea(), &WimaMeasurementAreaData::pathChanged, &GeneratorBase::generatorChanged);
this, &GeneratorBase::generatorChanged); disconnect(measurementArea, &MeasurementArea::progressChanged, this,
connect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(measurementArea, &MeasurementArea::tilesChanged, this,
connect(&this->_d->joinedArea(), &WimaJoinedAreaData::pathChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(measurementArea, &MeasurementArea::pathChanged, this,
connect(this->distance(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(serviceArea, &SafeArea::depotChanged, this,
connect(this->alpha(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(this->distance(), &Fact::rawValueChanged, this,
connect(this->minLength(), &Fact::rawValueChanged, this, &GeneratorBase::generatorChanged);
&GeneratorBase::generatorChanged); disconnect(this->alpha(), &Fact::rawValueChanged, this,
this->_connectionsEstablished = false; &GeneratorBase::generatorChanged);
disconnect(this->minLength(), &Fact::rawValueChanged, this,
&GeneratorBase::generatorChanged);
this->_connectionsEstablished = true;
}
} }
} }
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include <QGeoCoordinate> #include <QGeoCoordinate>
#include "SettingsFact.h"
namespace routing { namespace routing {
class LinearGenerator : public GeneratorBase { class LinearGenerator : public GeneratorBase {
...@@ -15,6 +17,7 @@ public: ...@@ -15,6 +17,7 @@ public:
Q_PROPERTY(Fact *minLength READ minLength CONSTANT) Q_PROPERTY(Fact *minLength READ minLength CONSTANT)
virtual QString editorQml() override; virtual QString editorQml() override;
virtual QString mapVisualQml() override;
virtual QString name() override; virtual QString name() override;
virtual QString abbreviation() override; virtual QString abbreviation() override;
......
#include "NemoInterface.h" #include "NemoInterface.h"
#include "SnakeTilesLocal.h" #include "nemo_interface/SnakeTilesLocal.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
#include <QTimer> #include <QTimer>
#include "QNemoHeartbeat.h" #include "geometry/MeasurementArea.h"
#include "QNemoProgress.h" #include "geometry/snake.h"
#include "Wima/Geometry/WimaMeasurementArea.h" #include "nemo_interface/QNemoHeartbeat.h"
#include "Wima/Snake/SnakeTile.h" #include "nemo_interface/QNemoProgress.h"
#include "Wima/Snake/snake.h" #include "nemo_interface/SnakeTile.h"
#include "ros_bridge/include/messages/geographic_msgs/geopoint.h" #include "ros_bridge/include/messages/geographic_msgs/geopoint.h"
#include "ros_bridge/include/messages/jsk_recognition_msgs/polygon_array.h" #include "ros_bridge/include/messages/jsk_recognition_msgs/polygon_array.h"
......
#include "OptimisationTools.h"
namespace OptimisationTools {
namespace {
} // end anonymous namespace
bool dijkstraAlgorithm(const int numElements, int startIndex, int endIndex, QVector<int> &elementPath, std::function<double (const int, const int)> distanceDij)
{
if ( numElements < 0
|| startIndex < 0
|| endIndex < 0
|| startIndex >= numElements
|| endIndex >= numElements
|| endIndex == startIndex) {
return false;
}
// Node struct
// predecessorIndex is the index of the predecessor node (nodeList[predecessorIndex])
// distance is the distance between the node and the start node
// node number is stored by the position in nodeList
struct Node{
int predecessorIndex = -1;
double distance = std::numeric_limits<qreal>::infinity();
};
// The list with all Nodes (elements)
QVector<Node> nodeList(numElements);
// This list will be initalized with indices referring to the elements of nodeList.
// Elements will be successively remove during the execution of the Dijkstra Algorithm.
QVector<int> workingSet(numElements);
//append elements to node list
for (int i = 0; i < numElements; ++i) workingSet[i] = i;
nodeList[startIndex].distance = 0;
// qDebug() << "nodeList" ;
// for (auto node : nodeList) {
// qDebug() << "predecessor: " << node.predecessorIndex;
// qDebug() << "distance: " << node.distance;
// }
// qDebug() << "workingSet";
// for (auto node : workingSet) {
// qDebug() << "index: " << node;
// }
// Dijkstra Algorithm
// https://de.wikipedia.org/wiki/Dijkstra-Algorithmus
while (workingSet.size() > 0) {
// serach Node with minimal distance
double minDist = std::numeric_limits<qreal>::infinity();
int minDistIndex_WS = -1; // WS = workinSet
for (int i = 0; i < workingSet.size(); ++i) {
const int nodeIndex = workingSet.at(i);
const double dist = nodeList.at(nodeIndex).distance;
if (dist < minDist) {
minDist = dist;
minDistIndex_WS = i;
}
}
if (minDistIndex_WS == -1)
return false;
int indexU_NL = workingSet.takeAt(minDistIndex_WS); // NL = nodeList
if (indexU_NL == endIndex) // shortest path found
break;
const double distanceU = nodeList.at(indexU_NL).distance;
//update distance
for (int i = 0; i < workingSet.size(); ++i) {
int indexV_NL = workingSet[i]; // NL = nodeList
Node* v = &nodeList[indexV_NL];
double dist = distanceDij(indexU_NL, indexV_NL);
// is ther an alternative path which is shorter?
double alternative = distanceU + dist;
if (alternative < v->distance) {
v->distance = alternative;
v->predecessorIndex = indexU_NL;
}
}
}
// end Djikstra Algorithm
// reverse assemble path
int e = endIndex;
while (1) {
if (e == -1) {
if (elementPath[0] == startIndex)// check if starting point was reached
break;
return false;
}
elementPath.prepend(e);
//Update Node
e = nodeList[e].predecessorIndex;
}
return true;
}
} // end OptimisationTools namespace
#pragma once
#include <QObject>
#include <QDebug>
#include <functional>
#include <QVector>
namespace OptimisationTools {
bool dijkstraAlgorithm(const int numElements, int startIndex, int endIndex, QVector<int> &elementPath, std::function<double(const int, const int)> distanceDij);
}
This diff is collapsed.
...@@ -7,9 +7,7 @@ ...@@ -7,9 +7,7 @@
#include "SettingsFact.h" #include "SettingsFact.h"
#include "TransectStyleComplexItem.h" #include "TransectStyleComplexItem.h"
#include "Geometry/WimaJoinedAreaData.h" #include "AreaData.h"
#include "Geometry/WimaMeasurementAreaData.h"
#include "WimaPlanData.h"
class RoutingThread; class RoutingThread;
class RoutingData; class RoutingData;
...@@ -18,21 +16,22 @@ namespace routing { ...@@ -18,21 +16,22 @@ namespace routing {
class GeneratorBase; class GeneratorBase;
} }
class CircularSurvey : public TransectStyleComplexItem { class RouteComplexItem : public TransectStyleComplexItem {
Q_OBJECT Q_OBJECT
using PtrGenerator = std::shared_ptr<routing::GeneratorBase>; using PtrGenerator = routing::GeneratorBase *;
using PtrAreaData = AreaData *;
using PtrRoutingData = std::shared_ptr<RoutingData>; using PtrRoutingData = std::shared_ptr<RoutingData>;
using PtrWorker = std::unique_ptr<RoutingThread>; using PtrWorker = RoutingThread *;
using Transects = QList<QList<CoordInfo_t>>; using Transects = QList<QList<CoordInfo_t>>;
using Variant = Transects; using Variant = Transects;
enum class STATE { IDLE, ROUTING, SKIPP, REVERT_PATH, CHANGE_VARIANT }; enum class STATE { IDLE, ROUTING, SKIPP, REVERT_PATH, CHANGE_VARIANT };
public: public:
CircularSurvey(PlanMasterController *masterController, bool flyView, RouteComplexItem(PlanMasterController *masterController, bool flyView,
const QString &kmlOrShpFile, QObject *parent); const QString &kmlOrShpFile, QObject *parent);
~CircularSurvey(); ~RouteComplexItem();
Q_PROPERTY(Fact *variant READ variant CONSTANT) Q_PROPERTY(Fact *variant READ variant CONSTANT)
Q_PROPERTY( Q_PROPERTY(
...@@ -43,14 +42,18 @@ public: ...@@ -43,14 +42,18 @@ public:
Q_PROPERTY( Q_PROPERTY(
routing::GeneratorBase *generator READ generator NOTIFY generatorChanged) routing::GeneratorBase *generator READ generator NOTIFY generatorChanged)
Q_PROPERTY(int generatorIndex READ generatorIndex NOTIFY generatorChanged) Q_PROPERTY(int generatorIndex READ generatorIndex NOTIFY generatorChanged)
Q_PROPERTY(bool editing READ editing NOTIFY editingChanged)
Q_PROPERTY(AreaData *areaData READ areaData NOTIFY areaDataChanged)
Q_INVOKABLE void revert_path(void); Q_INVOKABLE void revertPath(void);
// Property getters // Property getters
const AreaData &planData() const; const AreaData *areaData() const;
AreaData *areaData();
Fact *variant(); Fact *variant();
QStringList variantNames() const; QStringList variantNames() const;
bool calculating() const; bool calculating() const;
bool editing() const;
// Overrides // Overrides
virtual bool load(const QJsonObject &complexObject, int sequenceNumber, virtual bool load(const QJsonObject &complexObject, int sequenceNumber,
...@@ -67,8 +70,7 @@ public: ...@@ -67,8 +70,7 @@ public:
virtual QString patternName(void) const override; virtual QString patternName(void) const override;
// Generator // Generator
bool registerGenerator(const QString &name, bool registerGenerator(const QString &name, routing::GeneratorBase *g);
std::shared_ptr<routing::GeneratorBase> g);
bool unregisterGenerator(const QString &name); bool unregisterGenerator(const QString &name);
bool unregisterGenerator(int index); bool unregisterGenerator(int index);
Q_INVOKABLE bool switchToGenerator(const QString &name); Q_INVOKABLE bool switchToGenerator(const QString &name);
...@@ -77,6 +79,22 @@ public: ...@@ -77,6 +79,22 @@ public:
routing::GeneratorBase *generator(); routing::GeneratorBase *generator();
int generatorIndex(); int generatorIndex();
// Editing.
//!
//! \brief editingStart Starts area data editing.
//!
//! Starts area data editing. Transects will not be updated bewteen a call
//! sequence of editingStart() and editingStop().
//!
void editingStart();
//!
//! \brief editingStop Stops area editing.
//!
//! Stops area editing. Will reset area data to the state before
//! editingStart() if it is invalid. Triggers a transect update.
//!
void editingStop();
static const char *settingsGroup; static const char *settingsGroup;
static const char *variantName; static const char *variantName;
static const char *jsonComplexItemTypeValue; static const char *jsonComplexItemTypeValue;
...@@ -87,6 +105,8 @@ signals: ...@@ -87,6 +105,8 @@ signals:
void variantNamesChanged(); void variantNamesChanged();
void generatorNameListChanged(); void generatorNameListChanged();
void generatorChanged(); void generatorChanged();
void editingChanged();
void areaDataChanged();
private slots: private slots:
// Overrides from TransectStyleComplexItem // Overrides from TransectStyleComplexItem
...@@ -101,20 +121,25 @@ private slots: ...@@ -101,20 +121,25 @@ private slots:
void _reverseWorker(); void _reverseWorker();
private: private:
bool _switchToGenerator(const PtrGenerator &newG); bool _setGenerator(PtrGenerator newG);
void _setState(STATE state); void _setState(STATE state);
bool _calculating(STATE state) const; bool _calculating(STATE state) const;
void _setEditing(bool editing);
void _setAreaData(PtrAreaData data);
// State. // State.
STATE _state; STATE _state;
// center of the circular lanes, e.g. base station // Facts
QMap<QString, FactMetaData *> _metaDataMap; QMap<QString, FactMetaData *> _metaDataMap;
SettingsFact _variant; SettingsFact _variant;
QStringList _variantNames; QStringList _variantNames;
// Area data // Area data
AreaData _areaData; PtrAreaData _areaData;
PtrAreaData _editorData;
PtrAreaData _currentData;
bool _editing;
// Generators // Generators
QList<PtrGenerator> _generatorList; QList<PtrGenerator> _generatorList;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <QSharedPointer> #include <QSharedPointer>
#include <QThread> #include <QThread>
#include "snake.h" #include "geometry/snake.h"
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <functional> #include <functional>
......
#include "GeoArea.h"
#include <QDebug>
const char *GeoArea::wimaAreaName = "GeoArea";
const char *GeoArea::areaTypeName = "AreaType";
const char *GeoArea::settingsGroup = "GeoArea";
// Constructors
GeoArea::GeoArea(QObject *parent) : QGCMapPolygon(parent) { init(); }
GeoArea::GeoArea(const GeoArea &other, QObject *parent)
: QGCMapPolygon(other, parent) {
init();
}
GeoArea &GeoArea::operator=(const GeoArea &other) {
QGCMapPolygon::operator=(other);
return *this;
}
void GeoArea::saveToJson(QJsonObject &json) {
this->QGCMapPolygon::saveToJson(json);
}
bool GeoArea::loadFromJson(const QJsonObject &json, QString &errorString) {
if (!this->QGCMapPolygon::loadFromJson(json, false /*no poly required*/,
errorString)) {
qWarning() << errorString;
return false;
}
return true;
}
bool GeoArea::isSimplePolygon() {
qWarning() << "WimaArea::isSimplePolygon: impl. missing.";
return false;
}
void GeoArea::init() { this->setObjectName(wimaAreaName); }
bool copyAreaList(const QmlObjectListModel &from, QmlObjectListModel &to,
QObject *parent) {
// Check if elements are valid.
for (int i = 0; i < from.count(); ++i) {
auto obj = from[i];
auto area = qobject_cast<const GeoArea *>(obj);
if (area == nullptr) {
return false;
}
}
// Clone elements.
for (int i = 0; i < from.count(); ++i) {
auto obj = from[i];
auto area = qobject_cast<const GeoArea *>(obj);
to.append(area->clone(parent));
}
return true;
}
#pragma once
#include <QObject>
#include "QGCMapPolygon.h"
class GeoArea : public QGCMapPolygon {
Q_OBJECT
public:
GeoArea(QObject *parent = nullptr);
GeoArea(const GeoArea &other, QObject *parent = nullptr);
GeoArea &operator=(const GeoArea &other);
Q_PROPERTY(QString mapVisualQML READ mapVisualQML CONSTANT)
Q_PROPERTY(QString editorQML READ editorQML CONSTANT)
virtual QString mapVisualQML(void) const = 0;
virtual QString editorQML(void) const = 0;
virtual void saveToJson(QJsonObject &jsonObject);
virtual bool loadFromJson(const QJsonObject &jsonObject,
QString &errorString);
virtual GeoArea *clone(QObject *parent = nullptr) const = 0;
bool isSimplePolygon();
// static Members
static const char *wimaAreaName;
static const char *areaTypeName;
static const char *settingsGroup;
private:
void init();
};
// Example usage:
// QmlObjecListModel list;
// .... add areas ....
// auto area = getArea<WimaMeasurementArea *>(list); // returns the first
// WimaMeasurementArea or nullptr
template <class AreaPtr, class QObjectList>
inline AreaPtr getGeoArea(QObjectList &list) {
static_assert(std::is_pointer<AreaPtr>::value,
"AreaPtr must be a pointer type.");
for (int i = 0; i < list.count(); ++i) {
auto obj = list[i];
auto area = qobject_cast<AreaPtr>(obj);
if (area != nullptr) {
return area;
}
}
return nullptr;
}
bool copyAreaList(const QmlObjectListModel &from, QmlObjectListModel &to,
QObject *parent);
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QObject> #include <QObject>
#include <QSharedPointer>
#include <QTimer> #include <QTimer>
#include "WimaArea.h" #include "GeoArea.h"
#include "SettingsFact.h" #include "SettingsFact.h"
...@@ -24,17 +25,16 @@ public: ...@@ -24,17 +25,16 @@ public:
std::size_t size() const; std::size_t size() const;
}; };
class WimaMeasurementArea : public WimaArea { class MeasurementArea : public GeoArea {
Q_OBJECT Q_OBJECT
enum class STATE { IDLE, DEFERED, UPDATEING, RESTARTING, STOP }; enum class STATE { IDLE, DEFERED, UPDATEING, RESTARTING, STOP };
using DataPtr = QSharedPointer<TileData>;
public: public:
WimaMeasurementArea(QObject *parent = nullptr); MeasurementArea(QObject *parent = nullptr);
WimaMeasurementArea(const WimaMeasurementArea &other, MeasurementArea(const MeasurementArea &other, QObject *parent = nullptr);
QObject *parent = nullptr); MeasurementArea &operator=(const MeasurementArea &other);
WimaMeasurementArea &operator=(const WimaMeasurementArea &other); ~MeasurementArea();
~WimaMeasurementArea();
Q_PROPERTY(Fact *tileHeight READ tileHeight CONSTANT) Q_PROPERTY(Fact *tileHeight READ tileHeight CONSTANT)
Q_PROPERTY(Fact *tileWidth READ tileWidth CONSTANT) Q_PROPERTY(Fact *tileWidth READ tileWidth CONSTANT)
...@@ -44,9 +44,12 @@ public: ...@@ -44,9 +44,12 @@ public:
Q_PROPERTY(int maxTiles READ maxTiles NOTIFY maxTilesChanged) Q_PROPERTY(int maxTiles READ maxTiles NOTIFY maxTilesChanged)
Q_PROPERTY(QVector<int> progress READ progressQml NOTIFY progressChanged) Q_PROPERTY(QVector<int> progress READ progressQml NOTIFY progressChanged)
// Overrides from WimaPolygon // Overrides from GeoArea
QString mapVisualQML(void) const; QString mapVisualQML(void) const override;
QString editorQML(void) const; QString editorQML(void) const override;
MeasurementArea *clone(QObject *parent = nullptr) const;
void saveToJson(QJsonObject &json) override;
bool loadFromJson(const QJsonObject &json, QString &errorString) override;
// Property getters. // Property getters.
Fact *tileHeight(); Fact *tileHeight();
...@@ -62,17 +65,13 @@ public: ...@@ -62,17 +65,13 @@ public:
int maxTiles() const; int maxTiles() const;
bool ready() const; bool ready() const;
// Member Methodes
void saveToJson(QJsonObject &json);
bool loadFromJson(const QJsonObject &json, QString &errorString);
// Static Variables // Static Variables
static const char *settingsGroup; static const char *settingsGroup;
static const char *tileHeightName; static const char *tileHeightName;
static const char *tileWidthName; static const char *tileWidthName;
static const char *minTileAreaName; static const char *minTileAreaName;
static const char *showTilesName; static const char *showTilesName;
static const char *WimaMeasurementAreaName; static const char *MeasurementAreaName;
signals: signals:
void tilesChanged(); void tilesChanged();
...@@ -109,7 +108,6 @@ private: ...@@ -109,7 +108,6 @@ private:
// Tile stuff. // Tile stuff.
// Tile stuff. // Tile stuff.
mutable QTimer _timer; mutable QTimer _timer;
using DataPtr = std::shared_ptr<TileData>;
mutable STATE _state; mutable STATE _state;
mutable TileData _tileData; mutable TileData _tileData;
mutable QFutureWatcher<DataPtr> _watcher; mutable QFutureWatcher<DataPtr> _watcher;
......
This diff is collapsed.
#pragma once
#include <QLineF>
#include <QPointF>
#include <QPolygonF>
#include <QtMath>
#include "GenericCircle.h"
#include "PolygonCalculus.h"
using Circle = GenericCircle<qreal, QPointF>;
namespace PlanimetryCalculus {
enum IntersectType {
InsideNoIntersection,
InsideTouching,
InsideIntersection,
OutsideIntersection,
OutsideTouching,
OutsideNoIntersection,
CirclesEqual, // Circle Circle intersection
Tangent,
Secant, // Circle Line Intersetion
EdgeCornerIntersection,
EdgeEdgeIntersection,
CornerCornerIntersection,
LinesParallel,
LinesEqual, // Line Line intersection
Interior, // Polygon contains
NoIntersection,
Error // general
};
typedef QVector<QPair<int, int>> NeighbourVector;
typedef QVector<QPointF> QPointFVector;
typedef QVector<IntersectType> IntersectVector;
void rotateReference(QPointF &point, double alpha);
void rotateReference(QPointFVector &points, double alpha);
void rotateReference(QLineF &line, double alpha);
// void rotateReference(QPolygonF &polygon, double alpha);
QPointF rotateReturn(QPointF point, double alpha);
QPointFVector rotateReturn(QPointFVector points, double alpha);
QLineF rotateReturn(QLineF line, double alpha);
// QPolygonF rotateReturn(QPolygonF &polygon, double alpha);
bool intersects(const Circle &circle1, const Circle &circle2);
bool intersects(const Circle &circle1, const Circle &circle2,
IntersectType &type);
bool intersects(const Circle &circle1, const Circle &circle2,
QPointFVector &intersectionPoints);
bool intersects(const Circle &circle1, const Circle &circle2,
QPointFVector &intersectionPoints, IntersectType &type);
bool intersects(const Circle &circle, const QLineF &line);
bool intersects(const Circle &circle, const QLineF &line, IntersectType &type);
bool intersects(const Circle &circle, const QLineF &line,
QPointFVector &intersectionPoints);
bool intersects(const Circle &circle, const QLineF &line,
QPointFVector &intersectionPoints, IntersectType &type);
bool intersects(const Circle &circle, const QPolygonF &polygon);
bool intersects(const Circle &circle, const QPolygonF &polygon,
QVector<QPointFVector> &intersectionPoints);
bool intersects(const Circle &circle, const QPolygonF &polygon,
QVector<QPointFVector> &intersectionPoints,
IntersectVector &typeList);
bool intersects(const Circle &circle, const QPolygonF &polygon,
QVector<QPointFVector> &intersectionPoints,
NeighbourVector &neighbourList);
bool intersects(const Circle &circle, const QPolygonF &polygon,
QVector<QPointFVector> &intersectionPoints,
NeighbourVector &neighbourList, IntersectVector &typeList);
bool intersects(const QLineF &line1, const QLineF &line2);
bool intersects(const QLineF &line1, const QLineF &line2,
QPointF &intersectionPt);
bool intersects(const QLineF &line1, const QLineF &line2,
QPointF &intersectionPt, IntersectType &type);
// bool intersectsFast(const QLineF &line1, const QLineF &line2, QPointF
// &intersectionPt, IntersectType &type);
bool intersects(const QPolygonF &polygon, const QLineF &line,
QPointFVector &intersectionList);
bool intersects(const QPolygonF &polygon, const QLineF &line,
QPointFVector &intersectionList, IntersectVector &typeList);
bool intersects(const QPolygonF &polygon, const QLineF &line,
QPointFVector &intersectionList,
NeighbourVector &neighbourList);
bool intersects(const QPolygonF &polygon, const QLineF &line,
QPointFVector &intersectionList, NeighbourVector &neighbourList,
IntersectVector &typeList);
bool intersectsFast(const QPolygonF &polygon, const QLineF &line);
bool contains(const QLineF &line, const QPointF &point);
bool contains(const QLineF &line, const QPointF &point, IntersectType &type);
bool contains(const QPolygonF &polygon, const QPointF &point);
bool contains(const QPolygonF &polygon, const QPointF &point,
IntersectType &type);
double distance(const QPointF &p1, const QPointF p2);
double norm(double x, double y);
double norm(const QPointF &p);
double angle(const QPointF &p1, const QPointF p2);
double angle(const QPointF &p1);
double angle(const QLineF &line);
double angleDegree(const QPointF &p1, const QPointF p2);
double truncateAngle(double angle);
double truncateAngleDegree(double angle);
/*!
* \fntemplate <typename T> int signum(T val)
* Returns the signum of a value \a val.
*
* \sa QPair, QVector
*/
template <typename T> int signum(T val) { return (T(0) < val) - (val < T(0)); }
} // namespace PlanimetryCalculus
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once #pragma once
#include "Wima/Geometry/GenericPolygon.h" #include "geometry/GenericPolygon.h"
using SnakeTileLocal = GenericPolygon<QPointF, std::vector>; using SnakeTileLocal = GenericPolygon<QPointF, std::vector>;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment