diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index dfcc493f4812a70142dcc076d76b2bb6a451a4e5..808f020b8392e730eff2e6d3c2e29e931cbd425d 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -420,8 +420,7 @@ HEADERS += \
src/Wima/RoutingThread.h \
src/Wima/Snake/CircularGenerator.h \
src/Wima/Snake/GeneratorBase.h \
- src/Wima/Snake/GeneratorData.h \
- src/Wima/Snake/StandardData.h \
+ src/Wima/Snake/LinearGenerator.h \
src/Wima/Snake/clipper/clipper.hpp \
src/Wima/Snake/mapbox/feature.hpp \
src/Wima/Snake/mapbox/geometry.hpp \
@@ -516,7 +515,7 @@ SOURCES += \
src/Wima/RoutingThread.cpp \
src/Wima/Snake/CircularGenerator.cpp \
src/Wima/Snake/GeneratorBase.cc \
- src/Wima/Snake/StandardData.cpp \
+ src/Wima/Snake/LinearGenerator.cpp \
src/Wima/Snake/clipper/clipper.cpp \
src/Wima/Snake/snake.cpp \
src/Wima/Geometry/GeoPoint3D.cpp \
@@ -1456,5 +1455,8 @@ contains (CONFIG, QGC_DISABLE_INSTALLER_SETUP) {
}
DISTFILES += \
+ src/Wima/Routing/json/CircularGenerator.SettingsGroup.json \
+ src/Wima/Snake/json/LinearGenerator.SettingsGroup.json \
+ src/Wima/json/CircularSurvey.SettingsGroup.json \
src/WimaView/WimaMeasurementAreaEditor.qml \
src/Settings/Wima.SettingsGroup.json
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 82b70a88178ee45b1f121acf5b9bf7aa1c81a27c..f9202a72bfd39f62460574022a152b5ffa323d22 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -287,6 +287,8 @@
src/Wima/Geometry/json/WimaArea.SettingsGroup.json
src/Wima/json/WimaController.SettingsGroup.json
src/Settings/Wima.SettingsGroup.json
+ src/Wima/Snake/json/CircularGenerator.SettingsGroup.json
+ src/Wima/Snake/json/LinearGenerator.SettingsGroup.json
src/comm/APMArduCopterMockLink.params
diff --git a/src/Wima/CircularSurvey.cc b/src/Wima/CircularSurvey.cc
index 460abb69e707bbe3b8dc8bf4f5dd909e20f3839a..828d7ce429d1396e8455a7737ef6024ab0b01e27 100644
--- a/src/Wima/CircularSurvey.cc
+++ b/src/Wima/CircularSurvey.cc
@@ -9,6 +9,10 @@
#define CLIPPER_SCALE 1000000
#include "clipper/clipper.hpp"
+using namespace ClipperLib;
+template <> inline auto get<0>(const IntPoint &p) { return p.X; }
+template <> inline auto get<1>(const IntPoint &p) { return p.Y; }
+
#include "Geometry/GenericCircle.h"
#include "Snake/SnakeTile.h"
@@ -18,19 +22,6 @@
QGC_LOGGING_CATEGORY(CircularSurveyLog, "CircularSurveyLog")
-using namespace ClipperLib;
-template <> auto get<0>(const IntPoint &p) { return p.X; }
-template <> auto get<1>(const IntPoint &p) { return p.Y; }
-
-template class CommandRAII {
-public:
- CommandRAII(Functor f) : fun(f) {}
- ~CommandRAII() { fun(); }
-
-private:
- Functor fun;
-};
-
template
constexpr typename std::underlying_type::type integral(T value) {
return static_cast::type>(value);
@@ -456,7 +447,7 @@ void CircularSurvey::_updateWorker() {
// Routing par.
RoutingParameter par;
- par.numSolutionsPerRun = 5;
+ par.numSolutions = 5;
if (this->_numRuns.rawValue().toUInt() < 1) {
disconnect(&this->_numRuns, &Fact::rawValueChanged, this,
&CircularSurvey::_rebuildTransects);
diff --git a/src/Wima/RoutingThread.cpp b/src/Wima/RoutingThread.cpp
index 20f05f51619d8c6107fa5a877baa6f6ea4b8a32e..5b34bdd7e2a2f3a5e75ceffd9d3f33d4aeb6e353 100644
--- a/src/Wima/RoutingThread.cpp
+++ b/src/Wima/RoutingThread.cpp
@@ -59,7 +59,7 @@ void RoutingThread::run() {
lk.unlock();
auto safeAreaENU = par.safeArea;
auto numRuns = par.numRuns;
- auto numSolutionsPerRun = par.numSolutionsPerRun;
+ auto numSolutionsPerRun = par.numSolutions;
PtrRoutingData pRouteData(new RoutingData());
auto &transectsENU = pRouteData->transects;
diff --git a/src/Wima/RoutingThread.h b/src/Wima/RoutingThread.h
index 46ba2eb757aff864e10ad89c1bf4452e5cdfb41b..ee8444ab7aedc7864272b90f999717450122c3e5 100644
--- a/src/Wima/RoutingThread.h
+++ b/src/Wima/RoutingThread.h
@@ -17,9 +17,9 @@ struct RoutingData {
};
struct RoutingParameter {
- RoutingParameter() : numSolutionsPerRun(1), numRuns(1) {}
+ RoutingParameter() : numSolutions(1), numRuns(1) {}
snake::FPolygon safeArea;
- std::size_t numSolutionsPerRun;
+ std::size_t numSolutions;
std::size_t numRuns;
};
//!
diff --git a/src/Wima/Snake/CircularGenerator.cpp b/src/Wima/Snake/CircularGenerator.cpp
index 637ff4d2bbc47f77d57722ace308565b160c89d8..5e10112f9394d0185b0854c6808d461a28618978 100644
--- a/src/Wima/Snake/CircularGenerator.cpp
+++ b/src/Wima/Snake/CircularGenerator.cpp
@@ -6,19 +6,39 @@ QGC_LOGGING_CATEGORY(CircularGeneratorLog, "CircularGeneratorLog")
#define CLIPPER_SCALE 1000000
#include "Wima/Geometry/GenericCircle.h"
#include "clipper/clipper.hpp"
-// Clipper and GenericCircle
+
using namespace ClipperLib;
-template <> auto get<0>(const IntPoint &p) { return p.X; }
-template <> auto get<1>(const IntPoint &p) { return p.Y; }
+template <> inline auto get<0>(const IntPoint &p) { return p.X; }
+template <> inline auto get<1>(const IntPoint &p) { return p.Y; }
+
+#include "SnakeTile.h"
+#include "Wima/RoutingThread.h"
namespace routing {
-bool circularTransects(const snake::FPolygon &polygon,
+bool circularTransects(const snake::FPoint &reference,
+ const snake::FPolygon &polygon,
const std::vector &tiles,
snake::Length deltaR, snake::Angle deltaAlpha,
snake::Length minLength, snake::Transects &transects);
-CircularGenerator::CircularGenerator(QObject *parent) : GeneratorBase(parent) {}
+const char *CircularGenerator::settingsGroup = "CircularGenerator";
+const char *CircularGenerator::distanceName = "TransectDistance";
+const char *CircularGenerator::deltaAlphaName = "DeltaAlpha";
+const char *CircularGenerator::minLengthName = "MinLength";
+
+CircularGenerator::CircularGenerator(QObject *parent)
+ : CircularGenerator(nullptr, parent) {}
+
+CircularGenerator::CircularGenerator(GeneratorBase::Data d, QObject *parent)
+ : GeneratorBase(d, parent), _connectionsEstablished(false),
+ _metaDataMap(FactMetaData::createMapFromJsonFile(
+ QStringLiteral(":/json/CircularGenerator.SettingsGroup.json"), this)),
+ _distance(settingsGroup, _metaDataMap[distanceName]),
+ _deltaAlpha(settingsGroup, _metaDataMap[deltaAlphaName]),
+ _minLength(settingsGroup, _metaDataMap[minLengthName]) {
+ establishConnections();
+}
QString CircularGenerator::editorQML() {
return QStringLiteral("CircularGeneratorEditor.qml");
@@ -34,18 +54,171 @@ QString CircularGenerator::name() {
QString CircularGenerator::abbreviation() { return QStringLiteral("C. Gen."); }
-bool CircularGenerator::get(const WimaPlanData &data,
- GeneratorBase &generator) {
- auto generator = [depot, pPolygon, pTiles, distance, alpha,
- minLength](snake::Transects &transects) -> bool {
- bool value = circularTransects(*pPolygon, *pTiles, distance, alpha,
- minLength, transects);
- transects.insert(transects.begin(), snake::FLineString{depot});
- return value;
- };
+bool CircularGenerator::get(Generator &generator) {
+ if (this->_d) {
+ if (this->_d->isValid()) {
+ // Prepare data.
+ const auto &origin = this->_d->origin();
+ if (!origin.isValid()) {
+ qCWarning(CircularGeneratorLog) << "get(): origin invalid." << origin;
+ return false;
+ }
+
+ const auto &ref = this->_reference;
+ if (!ref.isValid()) {
+ qCWarning(CircularGeneratorLog) << "get(): reference invalid." << ref;
+ return false;
+ }
+ snake::FPoint reference;
+ snake::toENU(origin, ref, reference);
+
+ auto geoPolygon = this->_d->measurementArea().coordinateList();
+ for (auto &v : geoPolygon) {
+ if (v.isValid()) {
+ v.setAltitude(0);
+ } else {
+ qCWarning(CircularGeneratorLog) << "get(): measurement area invalid.";
+ for (const auto &w : geoPolygon) {
+ qCWarning(CircularGeneratorLog) << w;
+ }
+ return false;
+ }
+ }
+ auto pPolygon = std::make_shared();
+ snake::areaToEnu(origin, geoPolygon, *pPolygon);
+
+ // Progress and tiles.
+ const auto &progress = this->_d->measurementArea().progress();
+ const auto *tiles = this->_d->measurementArea().tiles();
+ auto pTiles = std::make_shared>();
+ if (progress.size() == tiles->count()) {
+ for (int i = 0; i < tiles->count(); ++i) {
+ if (progress[i] == 100) {
+ const auto *tile = tiles->value(i);
+ if (tile != nullptr) {
+ snake::FPolygon tileENU;
+ snake::areaToEnu(origin, tile->coordinateList(), tileENU);
+ pTiles->push_back(std::move(tileENU));
+ } else {
+ qCWarning(CircularGeneratorLog)
+ << "get(): progress.size() != tiles->count().";
+ return false;
+ }
+ }
+ }
+ } else {
+ qCWarning(CircularGeneratorLog)
+ << "get(): progress.size() != tiles->count().";
+ return false;
+ }
+
+ auto geoDepot = this->_d->serviceArea().depot();
+ if (!geoDepot.isValid()) {
+ qCWarning(CircularGeneratorLog) << "get(): depot invalid." << geoDepot;
+ return false;
+ }
+ snake::FPoint depot;
+ snake::toENU(origin, geoDepot, depot);
+
+ // Fetch transect parameter.
+ auto distance =
+ snake::Length(this->_distance.rawValue().toDouble() * bu::si::meter);
+ auto minLength =
+ snake::Length(this->_minLength.rawValue().toDouble() * bu::si::meter);
+ auto alpha = snake::Angle(this->_deltaAlpha.rawValue().toDouble() *
+ bu::degree::degree);
+
+ generator = [reference, depot, pPolygon, pTiles, distance, alpha,
+ minLength](snake::Transects &transects) -> bool {
+ bool value = circularTransects(reference, *pPolygon, *pTiles, distance,
+ alpha, minLength, transects);
+ transects.insert(transects.begin(), snake::FLineString{depot});
+ return value;
+ };
+ return true;
+ } else {
+ qCWarning(CircularGeneratorLog) << "get(): data invalid.";
+ return false;
+ }
+ } else {
+ qCWarning(CircularGeneratorLog) << "get(): data member not set.";
+ return false;
+ }
+}
+
+QGeoCoordinate CircularGenerator::reference() const { return _reference; }
+
+void CircularGenerator::setReference(const QGeoCoordinate &reference) {
+ if (_reference != reference) {
+ _reference = reference;
+ emit referenceChanged();
+ }
+}
+
+void CircularGenerator::resetReference() {
+ setReference(_d->measurementArea().center());
+}
+
+void CircularGenerator::establishConnections() {
+ if (this->_d && !this->_connectionsEstablished) {
+ connect(this->_d.get(), &WimaPlanData::measurementAreaChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->_d.get(), &WimaPlanData::originChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::progressChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::tileDataChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->distance(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->deltaAlpha(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->minLength(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this, &CircularGenerator::referenceChanged, this,
+ &GeneratorBase::generatorChanged);
+ this->_connectionsEstablished = true;
+ }
+}
+
+void CircularGenerator::deleteConnections() {
+ if (this->_d && this->_connectionsEstablished) {
+ disconnect(this->_d.get(), &WimaPlanData::measurementAreaChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this->_d.get(), &WimaPlanData::originChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::progressChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::tileDataChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged,
+ this, &GeneratorBase::generatorChanged);
+ disconnect(this->distance(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this->deltaAlpha(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this->minLength(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this, &CircularGenerator::referenceChanged, this,
+ &GeneratorBase::generatorChanged);
+ this->_connectionsEstablished = false;
+ }
}
-bool circularTransects(const snake::FPolygon &polygon,
+Fact *CircularGenerator::distance() { return &_distance; }
+
+Fact *CircularGenerator::deltaAlpha() { return &_deltaAlpha; }
+
+Fact *CircularGenerator::minLength() { return &_minLength; }
+
+bool circularTransects(const snake::FPoint &reference,
+ const snake::FPolygon &polygon,
const std::vector &tiles,
snake::Length deltaR, snake::Angle deltaAlpha,
snake::Length minLength, snake::Transects &transects) {
@@ -55,7 +228,6 @@ bool circularTransects(const snake::FPolygon &polygon,
if (polygon.outer().size() >= 3) {
using namespace boost::units;
// Convert geo polygon to ENU polygon.
- snake::FPoint origin{0, 0};
std::string error;
// Check validity.
if (!bg::is_valid(polygon, error)) {
@@ -75,7 +247,7 @@ bool circularTransects(const snake::FPolygon &polygon,
// qCWarning(CircularGeneratorLog) << "circularTransects():";
//#endif
for (const auto &p : polygon.outer()) {
- snake::Length distance = bg::distance(origin, p) * si::meter;
+ snake::Length distance = bg::distance(reference, p) * si::meter;
distances.push_back(distance);
snake::Angle alpha = (std::atan2(p.get<1>(), p.get<0>())) * si::radian;
alpha = alpha < 0 * si::radian ? alpha + 2 * M_PI * si::radian : alpha;
@@ -95,8 +267,8 @@ bool circularTransects(const snake::FPolygon &polygon,
snake::Angle alpha1(0 * degree::degree);
snake::Angle alpha2(360 * degree::degree);
// Determine r_min by successive approximation
- if (!bg::within(origin, polygon.outer())) {
- rMin = bg::distance(origin, polygon) * si::meter;
+ if (!bg::within(reference, polygon.outer())) {
+ rMin = bg::distance(reference, polygon) * si::meter;
}
auto rMax = (*std::max_element(distances.begin(),
@@ -107,9 +279,9 @@ bool circularTransects(const snake::FPolygon &polygon,
ClipperLib::cInt(std::round(rMin.value() * CLIPPER_SCALE));
const auto deltaRScaled =
ClipperLib::cInt(std::round(deltaR.value() * CLIPPER_SCALE));
- auto originScaled =
- ClipperLib::IntPoint{ClipperLib::cInt(std::round(origin.get<0>())),
- ClipperLib::cInt(std::round(origin.get<1>()))};
+ auto referenceScaled = ClipperLib::IntPoint{
+ ClipperLib::cInt(std::round(reference.get<0>())),
+ ClipperLib::cInt(std::round(reference.get<1>()))};
// Generate circle sectors.
auto rScaled = rMinScaled;
@@ -136,7 +308,7 @@ bool circularTransects(const snake::FPolygon &polygon,
using ClipperCircle =
GenericCircle;
for (auto §or : sectors) {
- ClipperCircle circle(rScaled, originScaled);
+ ClipperCircle circle(rScaled, referenceScaled);
approximate(circle, nSectors, sector);
rScaled += deltaRScaled;
}
diff --git a/src/Wima/Snake/CircularGenerator.h b/src/Wima/Snake/CircularGenerator.h
index eb9e58ce0007cd94fce749084103a6aa91a6819d..57b7c5f65aa3515e342e9ce15207345fe08435ce 100644
--- a/src/Wima/Snake/CircularGenerator.h
+++ b/src/Wima/Snake/CircularGenerator.h
@@ -1,12 +1,20 @@
#include "GeneratorBase.h"
-#include "StandardData.h"
+
+#include
namespace routing {
class CircularGenerator : public GeneratorBase {
Q_OBJECT
public:
- CircularGenerator(QObject *parent = nullptr) override;
+ CircularGenerator(QObject *parent = nullptr);
+ CircularGenerator(Data d, QObject *parent = nullptr);
+
+ Q_PROPERTY(QGeoCoordinate reference READ reference WRITE setReference NOTIFY
+ referenceChanged)
+ Q_PROPERTY(Fact *distance READ distance CONSTANT)
+ Q_PROPERTY(Fact *deltaAlpha READ deltaAlpha CONSTANT)
+ Q_PROPERTY(Fact *minLength READ minLength CONSTANT)
virtual QString editorQML() override;
virtual QString mapVisualQML() override;
@@ -14,7 +22,36 @@ public:
virtual QString name() override;
virtual QString abbreviation() override;
- virtual bool get(const WimaPlanData &data, GeneratorBase &generator);
+ virtual bool get(Generator &generator) override;
+
+ QGeoCoordinate reference() const;
+ Fact *distance();
+ Fact *deltaAlpha();
+ Fact *minLength();
+
+ void setReference(const QGeoCoordinate &reference);
+ void resetReference();
+
+ static const char *settingsGroup;
+ static const char *distanceName;
+ static const char *deltaAlphaName;
+ static const char *minLengthName;
+
+signals:
+ void referenceChanged();
+
+protected:
+ virtual void establishConnections() override;
+ virtual void deleteConnections() override;
+
+private:
+ bool _connectionsEstablished;
+
+ QGeoCoordinate _reference;
+ QMap _metaDataMap;
+ SettingsFact _distance;
+ SettingsFact _deltaAlpha;
+ SettingsFact _minLength;
};
} // namespace routing
diff --git a/src/Wima/Snake/GeneratorBase.cc b/src/Wima/Snake/GeneratorBase.cc
index 32bcaeede1c93e4124003ca12beb7ab320372cb8..77aa3c7731c4a7a296e6673717d6d088a1d91fda 100644
--- a/src/Wima/Snake/GeneratorBase.cc
+++ b/src/Wima/Snake/GeneratorBase.cc
@@ -2,12 +2,26 @@
namespace routing {
-GeneratorBase::GeneratorBase(QObject *parent) : QObject(parent) {}
+GeneratorBase::GeneratorBase(QObject *parent)
+ : GeneratorBase(nullptr, parent) {}
-GeneratorBase::GeneratorBase(std::shared_ptr par,
- QObject *parent)
- : QObject(parent) {}
+GeneratorBase::GeneratorBase(GeneratorBase::Data d, QObject *parent)
+ : QObject(parent), _d(d) {
+ establishConnections();
+}
GeneratorBase::~GeneratorBase() {}
+GeneratorBase::Data GeneratorBase::data() const { return _d; }
+
+void GeneratorBase::setData(const Data &d) {
+ deleteConnections();
+ _d = d;
+ establishConnections();
+}
+
+void GeneratorBase::establishConnections() {}
+
+void GeneratorBase::deleteConnections() {}
+
} // namespace routing
diff --git a/src/Wima/Snake/GeneratorBase.h b/src/Wima/Snake/GeneratorBase.h
index 6bf36889ace3baef97846bbcc5c250fcec1dd817..c60249d055f76351df0549e18e8ad807fd60b249 100644
--- a/src/Wima/Snake/GeneratorBase.h
+++ b/src/Wima/Snake/GeneratorBase.h
@@ -12,9 +12,11 @@ namespace routing {
class GeneratorBase : public QObject {
Q_OBJECT
public:
+ using Data = std::shared_ptr;
using Generator = std::function;
explicit GeneratorBase(QObject *parent = nullptr);
+ explicit GeneratorBase(Data d, QObject *parent = nullptr);
~GeneratorBase();
virtual QString editorQML() = 0;
@@ -23,10 +25,18 @@ public:
virtual QString name() = 0;
virtual QString abbreviation() = 0;
- virtual bool get(const WimaPlanData &data, GeneratorBase &generator) = 0;
+ virtual bool get(Generator &generator) = 0;
+
+ Data data() const;
+ void setData(const Data &d);
signals:
void generatorChanged();
+
+protected:
+ virtual void establishConnections();
+ virtual void deleteConnections();
+ Data _d;
};
} // namespace routing
diff --git a/src/Wima/Snake/GeneratorData.h b/src/Wima/Snake/GeneratorData.h
deleted file mode 100644
index 2d67a27b946e54468ab92a9fb627e61daa817d44..0000000000000000000000000000000000000000
--- a/src/Wima/Snake/GeneratorData.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include
-
-class GeneratorData : public QObject {
- Q_OBJECT
-public:
- explicit GeneratorData(QObject *parent = nullptr);
-};
diff --git a/src/Wima/Snake/LinearGenerator.cpp b/src/Wima/Snake/LinearGenerator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a019de8dde2c9a91906c0d709cc45624e19d59d
--- /dev/null
+++ b/src/Wima/Snake/LinearGenerator.cpp
@@ -0,0 +1,332 @@
+#include "LinearGenerator.h"
+
+#include "QGCLoggingCategory.h"
+QGC_LOGGING_CATEGORY(LinearGeneratorLog, "LinearGeneratorLog")
+
+#define CLIPPER_SCALE 1000000
+#include "clipper/clipper.hpp"
+
+#include "SnakeTile.h"
+#include "Wima/RoutingThread.h"
+
+namespace routing {
+
+bool linearTransects(const snake::FPolygon &polygon,
+ const std::vector &tiles,
+ snake::Length distance, snake::Angle angle,
+ snake::Length minLength, snake::Transects &transects);
+
+const char *LinearGenerator::settingsGroup = "LinearGenerator";
+const char *LinearGenerator::distanceName = "TransectDistance";
+const char *LinearGenerator::alphaName = "Alpha";
+const char *LinearGenerator::minLengthName = "MinLength";
+
+LinearGenerator::LinearGenerator(QObject *parent)
+ : LinearGenerator(nullptr, parent) {}
+
+LinearGenerator::LinearGenerator(GeneratorBase::Data d, QObject *parent)
+ : GeneratorBase(d, parent),
+ _metaDataMap(FactMetaData::createMapFromJsonFile(
+ QStringLiteral(":/json/LinearGenerator.SettingsGroup.json"), this)),
+ _distance(settingsGroup, _metaDataMap[distanceName]),
+ _alpha(settingsGroup, _metaDataMap[alphaName]),
+ _minLength(settingsGroup, _metaDataMap[minLengthName]) {
+ establishConnections();
+}
+
+QString LinearGenerator::editorQML() {
+ return QStringLiteral("LinearGeneratorEditor.qml");
+}
+
+QString LinearGenerator::mapVisualQML() {
+ return QStringLiteral("LinearGeneratorMapVisual.qml");
+}
+
+QString LinearGenerator::name() { return QStringLiteral("Linear Generator"); }
+
+QString LinearGenerator::abbreviation() { return QStringLiteral("L. Gen."); }
+
+bool LinearGenerator::get(Generator &generator) {
+ if (_d) {
+
+ if (this->_d->isValid()) {
+
+ // Prepare data.
+ const auto &origin = this->_d->origin();
+ auto geoPolygon = this->_d->measurementArea().coordinateList();
+ for (auto &v : geoPolygon) {
+ if (v.isValid()) {
+ v.setAltitude(0);
+ } else {
+ qCWarning(LinearGeneratorLog) << "get(): measurement area invalid.";
+ for (const auto &w : geoPolygon) {
+ qCWarning(LinearGeneratorLog) << w;
+ }
+ return false;
+ }
+ }
+ auto pPolygon = std::make_shared();
+ snake::areaToEnu(origin, geoPolygon, *pPolygon);
+
+ // Progress and tiles.
+ const auto &progress = this->_d->measurementArea().progress();
+ const auto *tiles = this->_d->measurementArea().tiles();
+ auto pTiles = std::make_shared>();
+ if (progress.size() == tiles->count()) {
+ for (int i = 0; i < tiles->count(); ++i) {
+ if (progress[i] == 100) {
+ const auto *tile = tiles->value(i);
+ if (tile != nullptr) {
+ snake::FPolygon tileENU;
+ snake::areaToEnu(origin, tile->coordinateList(), tileENU);
+ pTiles->push_back(std::move(tileENU));
+ } else {
+ qCWarning(LinearGeneratorLog)
+ << "get(): progress.size() != tiles->count().";
+ return false;
+ }
+ }
+ }
+ } else {
+ qCWarning(LinearGeneratorLog)
+ << "get(): progress.size() != tiles->count().";
+ return false;
+ }
+
+ auto geoDepot = this->_d->serviceArea().depot();
+ if (!geoDepot.isValid()) {
+ qCWarning(LinearGeneratorLog) << "get(): depot invalid." << geoDepot;
+ return false;
+ }
+ snake::FPoint depot;
+ snake::toENU(origin, geoDepot, depot);
+
+ // Fetch transect parameter.
+ auto distance =
+ snake::Length(this->_distance.rawValue().toDouble() * bu::si::meter);
+ auto minLength =
+ snake::Length(this->_minLength.rawValue().toDouble() * bu::si::meter);
+ auto alpha =
+ snake::Angle(this->_alpha.rawValue().toDouble() * bu::degree::degree);
+ generator = [depot, pPolygon, pTiles, distance, alpha,
+ minLength](snake::Transects &transects) -> bool {
+ bool value = linearTransects(*pPolygon, *pTiles, distance, alpha,
+ minLength, transects);
+ transects.insert(transects.begin(), snake::FLineString{depot});
+ return value;
+ };
+ return true;
+ } else {
+ qCWarning(LinearGeneratorLog) << "get(): data invalid.";
+ return false;
+ }
+ } else {
+ qCWarning(LinearGeneratorLog) << "get(): data member not set.";
+ return false;
+ }
+}
+
+Fact *LinearGenerator::distance() { return &_distance; }
+
+Fact *LinearGenerator::alpha() { return &_alpha; }
+
+Fact *LinearGenerator::minLength() { return &_minLength; }
+
+void LinearGenerator::establishConnections() {
+ if (this->_d && !this->_connectionsEstablished) {
+ connect(this->_d.get(), &WimaPlanData::measurementAreaChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->_d.get(), &WimaPlanData::originChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::progressChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::tileDataChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->distance(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->alpha(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ connect(this->minLength(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ this->_connectionsEstablished = true;
+ }
+}
+
+void LinearGenerator::deleteConnections() {
+ if (this->_d && this->_connectionsEstablished) {
+ disconnect(this->_d.get(), &WimaPlanData::measurementAreaChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this->_d.get(), &WimaPlanData::originChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::progressChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(&this->_d->measurementArea(),
+ &WimaMeasurementAreaData::tileDataChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(&this->_d->serviceArea(), &WimaServiceAreaData::depotChanged,
+ this, &GeneratorBase::generatorChanged);
+ disconnect(this->distance(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this->alpha(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ disconnect(this->minLength(), &Fact::rawValueChanged, this,
+ &GeneratorBase::generatorChanged);
+ this->_connectionsEstablished = false;
+ }
+}
+
+bool linearTransects(const snake::FPolygon &polygon,
+ const std::vector &tiles,
+ snake::Length distance, snake::Angle angle,
+ snake::Length minLength, snake::Transects &transects) {
+ namespace tr = bg::strategy::transform;
+ auto s1 = std::chrono::high_resolution_clock::now();
+
+ // Check preconitions
+ if (polygon.outer().size() >= 3) {
+ // Convert to ENU system.
+ std::string error;
+ // Check validity.
+ if (!bg::is_valid(polygon, error)) {
+ std::stringstream ss;
+ ss << bg::wkt(polygon);
+
+ qCWarning(LinearGeneratorLog) << "linearTransects(): "
+ "invalid polygon. "
+ << error.c_str() << ss.str().c_str();
+ } else {
+ tr::rotate_transformer rotate(angle.value() *
+ 180 / M_PI);
+ // Rotate polygon by angle and calculate bounding box.
+ snake::FPolygon polygonENURotated;
+ bg::transform(polygon.outer(), polygonENURotated.outer(), rotate);
+ snake::FBox box;
+ boost::geometry::envelope(polygonENURotated, box);
+ double x0 = box.min_corner().get<0>();
+ double y0 = box.min_corner().get<1>();
+ double x1 = box.max_corner().get<0>();
+ double y1 = box.max_corner().get<1>();
+
+ // Generate transects and convert them to clipper path.
+ size_t num_t = ceil((y1 - y0) / distance.value()); // number of transects
+ vector transectsClipper;
+ transectsClipper.reserve(num_t);
+ for (size_t i = 0; i < num_t; ++i) {
+ // calculate transect
+ snake::FPoint v1{x0, y0 + i * distance.value()};
+ snake::FPoint v2{x1, y0 + i * distance.value()};
+ snake::FLineString transect;
+ transect.push_back(v1);
+ transect.push_back(v2);
+ // transform back
+ snake::FLineString temp_transect;
+ tr::rotate_transformer rotate_back(
+ -angle.value() * 180 / M_PI);
+ bg::transform(transect, temp_transect, rotate_back);
+ // to clipper
+ ClipperLib::IntPoint c1{static_cast(
+ temp_transect[0].get<0>() * CLIPPER_SCALE),
+ static_cast(
+ temp_transect[0].get<1>() * CLIPPER_SCALE)};
+ ClipperLib::IntPoint c2{static_cast(
+ temp_transect[1].get<0>() * CLIPPER_SCALE),
+ static_cast(
+ temp_transect[1].get<1>() * CLIPPER_SCALE)};
+ ClipperLib::Path path{c1, c2};
+ transectsClipper.push_back(path);
+ }
+
+ if (transectsClipper.size() == 0) {
+ std::stringstream ss;
+ ss << "Not able to generate transects. Parameter: distance = "
+ << distance << std::endl;
+ qCWarning(LinearGeneratorLog)
+ << "linearTransects(): " << ss.str().c_str();
+ return false;
+ }
+
+ // Convert measurement area to clipper path.
+ snake::FPolygon shrinked;
+ snake::offsetPolygon(polygon, shrinked, -0.2);
+ auto &outer = shrinked.outer();
+ ClipperLib::Path polygonClipper;
+ for (auto vertex : outer) {
+ polygonClipper.push_back(ClipperLib::IntPoint{
+ static_cast(vertex.get<0>() * CLIPPER_SCALE),
+ static_cast(vertex.get<1>() * CLIPPER_SCALE)});
+ }
+
+ // Perform clipping.
+ // Clip transects to measurement area.
+ ClipperLib::Clipper clipper;
+ clipper.AddPath(polygonClipper, ClipperLib::ptClip, true);
+ clipper.AddPaths(transectsClipper, ClipperLib::ptSubject, false);
+ ClipperLib::PolyTree clippedTransecs;
+ clipper.Execute(ClipperLib::ctIntersection, clippedTransecs,
+ ClipperLib::pftNonZero, ClipperLib::pftNonZero);
+
+ // Subtract holes.
+ if (tiles.size() > 0) {
+ vector processedTiles;
+ for (const auto &tile : tiles) {
+ ClipperLib::Path path;
+ for (const auto &v : tile.outer()) {
+ path.push_back(ClipperLib::IntPoint{
+ static_cast(v.get<0>() * CLIPPER_SCALE),
+ static_cast(v.get<1>() * CLIPPER_SCALE)});
+ }
+ processedTiles.push_back(std::move(path));
+ }
+
+ clipper.Clear();
+ for (const auto &child : clippedTransecs.Childs) {
+ clipper.AddPath(child->Contour, ClipperLib::ptSubject, false);
+ }
+ clipper.AddPaths(processedTiles, ClipperLib::ptClip, true);
+ clippedTransecs.Clear();
+ clipper.Execute(ClipperLib::ctDifference, clippedTransecs,
+ ClipperLib::pftNonZero, ClipperLib::pftNonZero);
+ }
+
+ // Extract transects from PolyTree and convert them to BoostLineString
+ for (const auto &child : clippedTransecs.Childs) {
+ const auto &clipperTransect = child->Contour;
+ snake::FPoint v1{
+ static_cast(clipperTransect[0].X) / CLIPPER_SCALE,
+ static_cast(clipperTransect[0].Y) / CLIPPER_SCALE};
+ snake::FPoint v2{
+ static_cast(clipperTransect[1].X) / CLIPPER_SCALE,
+ static_cast(clipperTransect[1].Y) / CLIPPER_SCALE};
+
+ snake::FLineString transect{v1, v2};
+ if (bg::length(transect) >= minLength.value()) {
+ transects.push_back(transect);
+ }
+ }
+
+ if (transects.size() == 0) {
+ std::stringstream ss;
+ ss << "Not able to generatetransects. Parameter: minLength = "
+ << minLength << std::endl;
+ qCWarning(LinearGeneratorLog)
+ << "linearTransects(): " << ss.str().c_str();
+ return false;
+ }
+
+ qCWarning(LinearGeneratorLog)
+ << "linearTransects(): time: "
+ << std::chrono::duration_cast(
+ std::chrono::high_resolution_clock::now() - s1)
+ .count()
+ << " ms";
+ return true;
+ }
+ }
+ return false;
+}
+} // namespace routing
diff --git a/src/Wima/Snake/LinearGenerator.h b/src/Wima/Snake/LinearGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb1c1bdcbb74d3cc803fd173706d93e595699f3d
--- /dev/null
+++ b/src/Wima/Snake/LinearGenerator.h
@@ -0,0 +1,47 @@
+#include "GeneratorBase.h"
+
+#include
+
+namespace routing {
+
+class LinearGenerator : public GeneratorBase {
+ Q_OBJECT
+public:
+ LinearGenerator(QObject *parent = nullptr);
+ LinearGenerator(Data d, QObject *parent = nullptr);
+
+ Q_PROPERTY(Fact *distance READ distance CONSTANT)
+ Q_PROPERTY(Fact *alpha READ alpha CONSTANT)
+ Q_PROPERTY(Fact *minLength READ minLength CONSTANT)
+
+ virtual QString editorQML() override;
+ virtual QString mapVisualQML() override;
+
+ virtual QString name() override;
+ virtual QString abbreviation() override;
+
+ virtual bool get(Generator &generator) override;
+
+ Fact *distance();
+ Fact *alpha();
+ Fact *minLength();
+
+ static const char *settingsGroup;
+ static const char *distanceName;
+ static const char *alphaName;
+ static const char *minLengthName;
+
+protected:
+ virtual void establishConnections() override;
+ virtual void deleteConnections() override;
+
+private:
+ bool _connectionsEstablished;
+
+ QMap _metaDataMap;
+ SettingsFact _distance;
+ SettingsFact _alpha;
+ SettingsFact _minLength;
+};
+
+} // namespace routing
diff --git a/src/Wima/Snake/StandardData.cpp b/src/Wima/Snake/StandardData.cpp
deleted file mode 100644
index 171c4faa713cd4f3a8274ea1655306800891b572..0000000000000000000000000000000000000000
--- a/src/Wima/Snake/StandardData.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "StandardData.h"
-
-StandardParameter::StandardParameter() {}
diff --git a/src/Wima/Snake/StandardData.h b/src/Wima/Snake/StandardData.h
deleted file mode 100644
index b2075c6e0ae1d2b73c9da0dc8772992ecd48db85..0000000000000000000000000000000000000000
--- a/src/Wima/Snake/StandardData.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "GeneratorData.h"
-
-namespace routing {
-
-class StandardData : public GeneratorData {};
-
-} // namespace routing
diff --git a/src/Wima/Snake/json/CircularGenerator.SettingsGroup.json b/src/Wima/Snake/json/CircularGenerator.SettingsGroup.json
new file mode 100644
index 0000000000000000000000000000000000000000..001a3df5fcfa545657a0fe98b32ce8dfc8032365
--- /dev/null
+++ b/src/Wima/Snake/json/CircularGenerator.SettingsGroup.json
@@ -0,0 +1,30 @@
+[
+{
+ "name": "TransectDistance",
+ "shortDescription": "The distance between transects.",
+ "type": "double",
+ "units": "m",
+ "min": 0.3,
+ "decimalPlaces": 1,
+ "defaultValue": 5.0
+},
+{
+ "name": "DeltaAlpha",
+ "shortDescription": "Angle discretisation.",
+ "type": "double",
+ "units": "Deg",
+ "min": 0.3,
+ "max": 90,
+ "decimalPlaces": 1,
+ "defaultValue": 5.0
+},
+{
+ "name": "MinLength",
+ "shortDescription": "The minimal transect length.",
+ "type": "double",
+ "units": "m",
+ "min": 0.3,
+ "decimalPlaces": 1,
+ "defaultValue": 5.0
+}
+]
diff --git a/src/Wima/Snake/json/LinearGenerator.SettingsGroup.json b/src/Wima/Snake/json/LinearGenerator.SettingsGroup.json
new file mode 100644
index 0000000000000000000000000000000000000000..cc3bc7130e880d8a52eaffb91a3d289a92929476
--- /dev/null
+++ b/src/Wima/Snake/json/LinearGenerator.SettingsGroup.json
@@ -0,0 +1,30 @@
+[
+{
+ "name": "TransectDistance",
+ "shortDescription": "The distance between transects.",
+ "type": "double",
+ "units": "m",
+ "min": 0.3,
+ "decimalPlaces": 1,
+ "defaultValue": 5.0
+},
+{
+ "name": "Alpha",
+ "shortDescription": "Transect angle.",
+ "type": "double",
+ "units": "Deg",
+ "min": 0,
+ "max": 180,
+ "decimalPlaces": 1,
+ "defaultValue": 0.0
+},
+{
+ "name": "MinLength",
+ "shortDescription": "The minimal transect length.",
+ "type": "double",
+ "units": "m",
+ "min": 0.3,
+ "decimalPlaces": 1,
+ "defaultValue": 5.0
+}
+]
diff --git a/src/Wima/WimaController.cc b/src/Wima/WimaController.cc
index 7a9aa89ffc37dc2ad13ad0dda92661838f6b9736..7c9a050b06138c90293b8c9827802221699fb58b 100644
--- a/src/Wima/WimaController.cc
+++ b/src/Wima/WimaController.cc
@@ -230,74 +230,53 @@ void WimaController::planDataChangedHandler() {
_serviceArea = WimaServiceAreaData();
_corridor = WimaCorridorData();
_joinedArea = WimaJoinedAreaData();
+ _planDataValid = false;
emit visualItemsChanged();
emit missionItemsChanged();
emit waypointPathChanged();
- _planDataValid = false;
-
+ // Extract areas.
auto planData = WimaBridge::instance()->planData();
- // extract list with WimaAreas
- QList areaList = planData.areaList();
-
- int areaCounter = 0;
- const int numAreas = 4; // extract only numAreas Areas, if there are more
- // they are invalid and ignored
- for (int i = 0; i < areaList.size(); i++) {
- const WimaAreaData *areaData = areaList[i];
-
- if (areaData->type() ==
- WimaServiceAreaData::typeString) { // is it a service area?
- _serviceArea = *qobject_cast(areaData);
- areaCounter++;
- _areas.append(&_serviceArea);
-
- continue;
- }
- if (areaData->type() ==
- WimaMeasurementAreaData::typeString) { // is it a measurement area?
- _measurementArea =
- *qobject_cast(areaData);
- areaCounter++;
- _areas.append(&_measurementArea);
+ // Measurement Area.
+ if (planData.measurementArea().coordinateList().size() >= 3) {
+ _measurementArea = planData.measurementArea();
+ _areas.append(&_measurementArea);
- continue;
- }
+ // Service Area.
+ if (planData.serviceArea().coordinateList().size() >= 3) {
+ _serviceArea = planData.serviceArea();
+ _areas.append(&_serviceArea);
- if (areaData->type() == WimaCorridorData::typeString) { // is it a corridor?
- _corridor = *qobject_cast(areaData);
- areaCounter++;
- //_visualItems.append(&_corridor); // not needed
+ _WMSettings.setHomePosition(
+ QGeoCoordinate(_serviceArea.depot().latitude(),
+ _serviceArea.depot().longitude(), 0));
- continue;
- }
+ // Joined Area.
+ if (planData.joinedArea().coordinateList().size() >= 3) {
+ _joinedArea = planData.joinedArea();
+ _areas.append(&_joinedArea);
- if (areaData->type() ==
- WimaJoinedAreaData::typeString) { // is it a corridor?
- _joinedArea = *qobject_cast(areaData);
- areaCounter++;
- _areas.append(&_joinedArea);
+ _planDataValid = true;
- continue;
+ // Corridor.
+ if (planData.corridor().coordinateList().size() >= 3) {
+ _corridor = planData.corridor();
+ }
+ }
}
-
- if (areaCounter >= numAreas)
- break;
}
- if (areaCounter != numAreas) {
- Q_ASSERT(false);
- return;
+ if (_planDataValid) {
+ emit visualItemsChanged();
+ } else {
+ _areas.clear();
+ _measurementArea = WimaMeasurementAreaData();
+ _serviceArea = WimaServiceAreaData();
+ _corridor = WimaCorridorData();
+ _joinedArea = WimaJoinedAreaData();
}
-
- emit visualItemsChanged();
-
- _WMSettings.setHomePosition(QGeoCoordinate(
- _serviceArea.depot().latitude(), _serviceArea.depot().longitude(), 0));
-
- _planDataValid = true;
}
void WimaController::progressChangedHandler() {
diff --git a/src/Wima/WimaPlanData.cc b/src/Wima/WimaPlanData.cc
index b70c40280bcf188b00e3b4478911e72c5f568ec6..139a1d15553c2627fb3731df91410488a8d688c3 100644
--- a/src/Wima/WimaPlanData.cc
+++ b/src/Wima/WimaPlanData.cc
@@ -1,25 +1,17 @@
#include "WimaPlanData.h"
-enum Signal {
- measuremtAreaChanged,
- serviceAreaChanged,
- joinedAreaChanged,
- corridorChanged,
-};
-
-WimaPlanData::WimaPlanData(QObject *parent)
- : QObject(parent), _editing(false) {}
+WimaPlanData::WimaPlanData(QObject *parent) : QObject(parent) {}
WimaPlanData::WimaPlanData(const WimaPlanData &other, QObject *parent)
- : QObject(parent), _editing(false) {
+ : QObject(parent) {
*this = other;
}
WimaPlanData &WimaPlanData::operator=(const WimaPlanData &other) {
- this->_measurementArea = other._measurementArea;
- this->_serviceArea = other._serviceArea;
- this->_joinedArea = other._joinedArea;
- this->_corridor = other._corridor;
+ this->set(other.measurementArea());
+ this->set(other.serviceArea());
+ this->set(other.joinedArea());
+ this->set(other.corridor());
return *this;
}
@@ -27,36 +19,44 @@ WimaPlanData &WimaPlanData::operator=(const WimaPlanData &other) {
void WimaPlanData::set(const WimaJoinedAreaData &areaData) {
if (_joinedArea != areaData) {
_joinedArea = areaData;
- emitJoinedAreaChanged();
+ emit joinedAreaChanged();
}
}
void WimaPlanData::set(const WimaServiceAreaData &areaData) {
if (_serviceArea != areaData) {
_serviceArea = areaData;
- emitServiceAreaChanged();
+ emit serviceAreaChanged();
}
}
void WimaPlanData::set(const WimaCorridorData &areaData) {
if (_corridor != areaData) {
_corridor = areaData;
- emitCorridorChanged();
+ emit corridorChanged();
}
}
void WimaPlanData::set(const WimaMeasurementAreaData &areaData) {
if (_measurementArea != areaData) {
_measurementArea = areaData;
- emitMeasurementAreaChanged();
+ emit measurementAreaChanged();
+
+ if (_measurementArea.coordinateList().size() > 0) {
+ setOrigin(_measurementArea.coordinateList().first());
+ } else {
+ setOrigin(QGeoCoordinate());
+ }
}
}
-void WimaPlanData::clear() {
- _joinedArea = WimaJoinedAreaData();
- _serviceArea = WimaServiceAreaData();
- _corridor = WimaCorridorData();
- _measurementArea = WimaMeasurementAreaData();
+void WimaPlanData::clear() { *this = WimaPlanData(); }
+
+QGeoCoordinate WimaPlanData::origin() { return _origin; }
+
+bool WimaPlanData::isValid() {
+ return _measurementArea.coordinateList().size() >= 3 &&
+ _serviceArea.coordinateList().size() >= 3 && _origin.isValid();
}
const WimaJoinedAreaData &WimaPlanData::joinedArea() const {
@@ -75,24 +75,14 @@ const WimaMeasurementAreaData &WimaPlanData::measurementArea() const {
return this->_measurementArea;
}
-void WimaPlanData::startEditing() {
- if (!this->_editing) {
- this->_editing = true;
- }
-}
+WimaJoinedAreaData &WimaPlanData::joinedArea() { return this->_joinedArea; }
-void WimaPlanData::stopEditing() {
- if (this->_editing) {
- this->_editing = false;
- for (auto &s : this->_queuedSignals) {
- s.second();
- }
- this->_queuedSignals.clear();
- }
-}
+WimaServiceAreaData &WimaPlanData::serviceArea() { return this->_serviceArea; }
+
+WimaCorridorData &WimaPlanData::corridor() { return this->_corridor; }
-WimaPlanData::Guard WimaPlanData::guard() {
- return Guard(std::bind(&WimaPlanData::stopEditing, this));
+WimaMeasurementAreaData &WimaPlanData::measurementArea() {
+ return this->_measurementArea;
}
bool WimaPlanData::operator==(const WimaPlanData &other) const {
@@ -105,42 +95,9 @@ bool WimaPlanData::operator!=(const WimaPlanData &other) const {
return !(*this == other);
}
-void WimaPlanData::emitJoinedAreaChanged() {
- if (!this->_editing) {
- emit joinedAreaChanged();
- } else {
- this->_queuedSignals.insert(
- std::make_pair(Signal::joinedAreaChanged,
- std::bind(&WimaPlanData::joinedAreaChanged, this)));
- }
-}
-
-void WimaPlanData::emitMeasurementAreaChanged() {
- if (!this->_editing) {
- emit measurementAreaChanged();
- } else {
- this->_queuedSignals.insert(
- std::make_pair(Signal::measuremtAreaChanged,
- std::bind(&WimaPlanData::measurementAreaChanged, this)));
- }
-}
-
-void WimaPlanData::emitServiceAreaChanged() {
- if (!this->_editing) {
- emit serviceAreaChanged();
- } else {
- this->_queuedSignals.insert(
- std::make_pair(Signal::serviceAreaChanged,
- std::bind(&WimaPlanData::serviceAreaChanged, this)));
- }
-}
-
-void WimaPlanData::emitCorridorChanged() {
- if (!this->_editing) {
- emit corridorChanged();
- } else {
- this->_queuedSignals.insert(
- std::make_pair(Signal::corridorChanged,
- std::bind(&WimaPlanData::corridorChanged, this)));
+void WimaPlanData::setOrigin(const QGeoCoordinate &origin) {
+ if (this->_origin != origin) {
+ this->_origin = origin;
+ emit originChanged();
}
}
diff --git a/src/Wima/WimaPlanData.h b/src/Wima/WimaPlanData.h
index 9fb0adc29c987986ce45756593929a7e4e36551f..bed16c9852d8ce6f0cdfa2416d385972dabd7858 100644
--- a/src/Wima/WimaPlanData.h
+++ b/src/Wima/WimaPlanData.h
@@ -1,8 +1,5 @@
#pragma once
-#include
-#include