Commit ab5abb37 authored by Valentin Platzgummer's avatar Valentin Platzgummer

proper pictures added to MeasurementItemEditor.qml

parent 1b05f323
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<file alias="counter-clockwise-arrow.svg">resources/counter-clockwise-arrow.svg</file> <file alias="counter-clockwise-arrow.svg">resources/counter-clockwise-arrow.svg</file>
<file alias="chevron-down.svg">resources/chevron-down.svg</file> <file alias="chevron-down.svg">resources/chevron-down.svg</file>
<file alias="chevron-up.svg">resources/chevron-up.svg</file> <file alias="chevron-up.svg">resources/chevron-up.svg</file>
<file alias="DropArrow.svg">resources/DropArrow.svg</file> <file alias="DropArrow.svg">resources/DropArrow.svg</file>
<file alias="gear-black.svg">resources/gear-black.svg</file> <file alias="gear-black.svg">resources/gear-black.svg</file>
<file alias="gear-white.svg">resources/gear-white.svg</file> <file alias="gear-white.svg">resources/gear-white.svg</file>
<file alias="helicoptericon.svg">resources/helicoptericon.svg</file> <file alias="helicoptericon.svg">resources/helicoptericon.svg</file>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<file alias="Play">resources/Play.svg</file> <file alias="Play">resources/Play.svg</file>
<file alias="PowerButton">resources/PowerButton.svg</file> <file alias="PowerButton">resources/PowerButton.svg</file>
<file alias="QGCLogoBlack">resources/QGCLogoBlack.svg</file> <file alias="QGCLogoBlack">resources/QGCLogoBlack.svg</file>
<file alias="QGCLogoFull">resources/QGCLogoFull.svg</file> <file alias="QGCLogoFull">resources/QGCLogoFull.svg</file>
<file alias="QGCLogoWhite">resources/QGCLogoWhite.svg</file> <file alias="QGCLogoWhite">resources/QGCLogoWhite.svg</file>
<file alias="QGCLogoArrow">resources/QGCLogoArrow.svg</file> <file alias="QGCLogoArrow">resources/QGCLogoArrow.svg</file>
<file alias="QGroundControlConnect">resources/QGroundControlConnect.svg</file> <file alias="QGroundControlConnect">resources/QGroundControlConnect.svg</file>
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
<file alias="street.png">resources/street.png</file> <file alias="street.png">resources/street.png</file>
<file alias="measurement.png">resources/measurement.png</file> <file alias="measurement.png">resources/measurement.png</file>
<file alias="calculator.png">resources/calculator.png</file> <file alias="calculator.png">resources/calculator.png</file>
<file alias="fish.svg">resources/fish.svg</file>
</qresource> </qresource>
<qresource prefix="/res/firmware"> <qresource prefix="/res/firmware">
<file alias="3drradio.png">resources/firmware/3drradio.png</file> <file alias="3drradio.png">resources/firmware/3drradio.png</file>
......
...@@ -293,6 +293,7 @@ ...@@ -293,6 +293,7 @@
<file alias="MeasurementComplexItem/AreaDataEditor.qml">src/MeasurementComplexItem/qml/AreaDataEditor.qml</file> <file alias="MeasurementComplexItem/AreaDataEditor.qml">src/MeasurementComplexItem/qml/AreaDataEditor.qml</file>
<file alias="MeasurementComplexItem/ParameterEditor.qml">src/MeasurementComplexItem/qml/ParameterEditor.qml</file> <file alias="MeasurementComplexItem/ParameterEditor.qml">src/MeasurementComplexItem/qml/ParameterEditor.qml</file>
<file alias="MeasurementComplexItem/qmldir">src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir</file> <file alias="MeasurementComplexItem/qmldir">src/MeasurementComplexItem/qml/MeasurementComplexItem.qmldir</file>
<file alias="MeasurementComplexItem/NemoEditor.qml">src/MeasurementComplexItem/qml/NemoEditor.qml</file>
</qresource> </qresource>
<qresource prefix="/FirstRunPromptDialogs"> <qresource prefix="/FirstRunPromptDialogs">
<file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file> <file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file>
......
[Dolphin]
PreviewsShown=true
Timestamp=2020,12,19,15,18,21
Version=4
fish.svg: from https://commons.wikimedia.org/wiki/File:Font_Awesome_5_solid_fish.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M327.1 96c-89.97 0-168.54 54.77-212.27 101.63L27.5 131.58c-12.13-9.18-30.24.6-27.14 14.66L24.54 256 .35 365.77c-3.1 14.06 15.01 23.83 27.14 14.66l87.33-66.05C158.55 361.23 237.13 416 327.1 416 464.56 416 576 288 576 256S464.56 96 327.1 96zm87.43 184c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24 13.26 0 24 10.74 24 24 0 13.25-10.75 24-24 24z"/></svg>
<!--
Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
\ No newline at end of file
...@@ -126,8 +126,9 @@ bool AreaData::isCorrect(bool showError) { ...@@ -126,8 +126,9 @@ bool AreaData::isCorrect(bool showError) {
// ss << "safeAreaENU: " << bg::wkt(safeAreaENU) << std::endl; // ss << "safeAreaENU: " << bg::wkt(safeAreaENU) << std::endl;
// qDebug() << ss.str().c_str(); // qDebug() << ss.str().c_str();
if (!bg::covered_by(measurementAreaENU, safeAreaENU)) { if (!bg::covered_by(measurementAreaENU, safeAreaENU)) {
_processError(tr("Measurement Area not inside Safe Area. Please adjust " _processError(tr("Measurement Area is not covered by Safe "
"the Measurement Area.\n"), "Area. Please adjust "
"the areas accordingly.\n"),
showError); showError);
return false; return false;
} }
...@@ -228,10 +229,10 @@ void AreaData::intersection(bool showError) { ...@@ -228,10 +229,10 @@ void AreaData::intersection(bool showError) {
boost::geometry::intersection(measurementAreaENU, safeAreaENU, outputENU); boost::geometry::intersection(measurementAreaENU, safeAreaENU, outputENU);
if (outputENU.size() < 1 || outputENU[0].outer().size() < 4) { if (outputENU.size() < 1 || outputENU[0].outer().size() < 4) {
_processError( _processError("Intersection did't deliver any result. The Measurement "
"Intersection did't deliver any result. Measurement Area and " "Area(s) and "
"Safe Area must touch each other.", "The Safe Area must touch each other.",
showError); showError);
return; return;
} }
...@@ -266,11 +267,29 @@ void AreaData::intersection(bool showError) { ...@@ -266,11 +267,29 @@ void AreaData::intersection(bool showError) {
} }
} }
MeasurementArea *AreaData::measurementArea() { QVector<MeasurementArea *> AreaData::measurementAreaArray() {
return getGeoArea<MeasurementArea *>(_areaList); return getGeoAreaList<MeasurementArea *, QVector>(_areaList);
}
QVector<SafeArea *> AreaData::safeAreaArray() {
return getGeoAreaList<SafeArea *, QVector>(_areaList);
} }
SafeArea *AreaData::safeArea() { return getGeoArea<SafeArea *>(_areaList); } QmlObjectListModel *AreaData::measurementAreaList() {
_measurementAreaList.clear();
auto array = getGeoAreaList<MeasurementArea *, QVector>(_areaList);
for (auto area : array)
_measurementAreaList.append(area);
return &_measurementAreaList;
}
QmlObjectListModel *AreaData::safeAreaList() {
_safeAreaList.clear();
auto array = getGeoAreaList<SafeArea *, QVector>(_areaList);
for (auto &area : array)
_safeAreaList.append(area);
return &_safeAreaList;
}
bool AreaData::operator==(const AreaData &other) const { bool AreaData::operator==(const AreaData &other) const {
if (_areaList.count() == other._areaList.count()) { if (_areaList.count() == other._areaList.count()) {
...@@ -442,13 +461,13 @@ bool AreaData::_getAreas(MeasurementArea **measurementArea, SafeArea **safeArea, ...@@ -442,13 +461,13 @@ bool AreaData::_getAreas(MeasurementArea **measurementArea, SafeArea **safeArea,
*measurementArea = getGeoArea<MeasurementArea *>(_areaList); *measurementArea = getGeoArea<MeasurementArea *>(_areaList);
if (*measurementArea == nullptr) { if (*measurementArea == nullptr) {
_processError( _processError(
tr("Measurement Area missing. Please define a measurement area."), tr("Measurement Area is missing. Please define a Measurement Area."),
showError); showError);
return false; return false;
} }
*safeArea = getGeoArea<SafeArea *>(_areaList); *safeArea = getGeoArea<SafeArea *>(_areaList);
if (*safeArea == nullptr) { if (*safeArea == nullptr) {
_processError(tr("Safe Area missing. Please define a safe area."), _processError(tr("Safe Area is missing. Please define a Safe Area."),
showError); showError);
return false; return false;
} }
......
...@@ -20,6 +20,10 @@ public: ...@@ -20,6 +20,10 @@ public:
AreaData &operator=(const AreaData &other); AreaData &operator=(const AreaData &other);
Q_PROPERTY(QmlObjectListModel *areaList READ areaList NOTIFY areaListChanged) Q_PROPERTY(QmlObjectListModel *areaList READ areaList NOTIFY areaListChanged)
Q_PROPERTY(QmlObjectListModel *measurementAreaList READ measurementAreaList
NOTIFY areaListChanged)
Q_PROPERTY(
QmlObjectListModel *safeAreaList READ safeAreaList NOTIFY areaListChanged)
Q_PROPERTY(QString errorString READ errorString NOTIFY error) Q_PROPERTY(QString errorString READ errorString NOTIFY error)
// Member Methodes // Member Methodes
...@@ -70,8 +74,10 @@ public: ...@@ -70,8 +74,10 @@ public:
Q_INVOKABLE bool initialized(); Q_INVOKABLE bool initialized();
Q_INVOKABLE void intersection(bool showError = true); Q_INVOKABLE void intersection(bool showError = true);
Q_INVOKABLE MeasurementArea *measurementArea(); QVector<MeasurementArea *> measurementAreaArray();
Q_INVOKABLE SafeArea *safeArea(); QVector<SafeArea *> safeAreaArray();
QmlObjectListModel *measurementAreaList();
QmlObjectListModel *safeAreaList();
bool operator==(const AreaData &other) const; bool operator==(const AreaData &other) const;
bool operator!=(const AreaData &other) const; bool operator!=(const AreaData &other) const;
...@@ -97,5 +103,7 @@ private: ...@@ -97,5 +103,7 @@ private:
QGeoCoordinate _origin; QGeoCoordinate _origin;
QmlObjectListModel _areaList; QmlObjectListModel _areaList;
QmlObjectListModel _measurementAreaList;
QmlObjectListModel _safeAreaList;
QString _errorString; QString _errorString;
}; };
...@@ -83,9 +83,9 @@ private: ...@@ -83,9 +83,9 @@ private:
std::map<QString, Creator> _creatorMap; std::map<QString, Creator> _creatorMap;
}; };
#define pGeneratorFactory ::routing::GeneratorFactory::instance()
#define REGISTER_GENERATOR(type, creator) \ #define REGISTER_GENERATOR(type, creator) \
namespace { \ namespace { \
auto registered = \ auto registered = pGeneratorFactory -> registerGenerator(type, creator); \
GeneratorFactory::instance() -> registerGenerator(type, creator); \
} }
} // namespace routing } // namespace routing
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <QScopedPointer> #include <QScopedPointer>
#include <QtGlobal> #include <QtGlobal>
// from https://stackoverflow.com/questions/46172607/qt-singleton-implementation
template <class T> class GenericSingelton { template <class T> class GenericSingelton {
private: private:
typedef T *(*CreateInstanceFunction)(); typedef T *(*CreateInstanceFunction)();
......
...@@ -247,8 +247,7 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject, ...@@ -247,8 +247,7 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject,
QString e; QString e;
// create generator // create generator
auto gen = routing::GeneratorFactory::instance()->create( auto gen = pGeneratorFactory->create(jsonGen, e, &parent /*parent*/);
jsonGen, e, &parent /*parent*/);
if (gen != nullptr) { if (gen != nullptr) {
// remove generators of same type and insert this generator. // remove generators of same type and insert this generator.
...@@ -267,7 +266,7 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject, ...@@ -267,7 +266,7 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject,
errorString.append( errorString.append(
tr("Error loading generator of type ") + tr("Error loading generator of type ") +
jsonGen[routing::GeneratorBase::typeKey].toString() + ".\n"); jsonGen[routing::GeneratorBase::typeKey].toString() + ".\n");
if (!routing::GeneratorFactory::instance()->registered( if (!pGeneratorFactory->registered(
jsonGen[routing::GeneratorBase::typeKey].toString())) { jsonGen[routing::GeneratorBase::typeKey].toString())) {
errorString.append(tr("This type is unknown.\n")); errorString.append(tr("This type is unknown.\n"));
qCritical() qCritical()
...@@ -360,8 +359,10 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject, ...@@ -360,8 +359,10 @@ bool MeasurementComplexItem::load(const QJsonObject &complexObject,
// Check if variants are covered by safe area. // Check if variants are covered by safe area.
if (variantsSuccess) { if (variantsSuccess) {
auto safeArea = _pCurrentData->safeArea(); auto safeAreaArray = _pCurrentData->safeAreaArray();
if (safeArea != nullptr) {
if (safeAreaArray.size() > 0 && safeAreaArray.at(0) != nullptr) {
auto safeArea = safeAreaArray[0];
QGeoCoordinate origin = QGeoCoordinate origin =
safeArea->pathModel().value<QGCQGeoCoordinate *>(0)->coordinate(); safeArea->pathModel().value<QGCQGeoCoordinate *>(0)->coordinate();
snake::FPolygon safeAreaENU; snake::FPolygon safeAreaENU;
...@@ -733,8 +734,11 @@ void MeasurementComplexItem::_updateFlightpathSegments() { ...@@ -733,8 +734,11 @@ void MeasurementComplexItem::_updateFlightpathSegments() {
if (hasCollisionOld != hasCollision) { if (hasCollisionOld != hasCollision) {
emit terrainCollisionChanged(hasCollision); emit terrainCollisionChanged(hasCollision);
} }
if (_pAreaData->measurementArea() != nullptr) { auto measurementAreaArray = _pAreaData->measurementAreaArray();
_pAreaData->measurementArea()->setShowAltColor(hasCollision); for (auto area : measurementAreaArray) {
if (area != nullptr) {
area->setShowAltColor(hasCollision);
}
} }
_masterController->missionController()->recalcTerrainProfile(); _masterController->missionController()->recalcTerrainProfile();
...@@ -782,6 +786,20 @@ void MeasurementComplexItem::_updateRoute() { ...@@ -782,6 +786,20 @@ void MeasurementComplexItem::_updateRoute() {
if (this->_pAreaData->isCorrect()) { if (this->_pAreaData->isCorrect()) {
auto measurmentAreaArray = _pAreaData->measurementAreaArray();
bool measurementComplete = true;
for (const auto &area : measurmentAreaArray) {
if (!area->measurementCompleted()) {
measurementComplete = false;
}
}
if (measurementComplete) {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): measurement complete!";
return;
}
// Prepare data. // Prepare data.
auto origin = this->_pAreaData->origin(); auto origin = this->_pAreaData->origin();
origin.setAltitude(0); origin.setAltitude(0);
...@@ -1039,13 +1057,13 @@ void MeasurementComplexItem::resetGenerators() { ...@@ -1039,13 +1057,13 @@ void MeasurementComplexItem::resetGenerators() {
removeGenerator(0); removeGenerator(0);
} }
auto lg = routing::GeneratorFactory::instance()->create( auto lg =
routing::LinearGenerator::typeString, this); pGeneratorFactory->create(routing::LinearGenerator::typeString, this);
lg->setData(this->_pAreaData); lg->setData(this->_pAreaData);
addGenerator(lg); addGenerator(lg);
auto cg = routing::GeneratorFactory::instance()->create( auto cg =
routing::CircularGenerator::typeString, this); pGeneratorFactory->create(routing::CircularGenerator::typeString, this);
cg->setData(this->_pAreaData); cg->setData(this->_pAreaData);
addGenerator(cg); addGenerator(cg);
} }
...@@ -1139,6 +1157,24 @@ void MeasurementComplexItem::abortEditing() { ...@@ -1139,6 +1157,24 @@ void MeasurementComplexItem::abortEditing() {
} }
} }
void MeasurementComplexItem::reset() {
if (editing()) {
*_pEditorData = *_pAreaData;
}
}
bool MeasurementComplexItem::initialize(const QGeoCoordinate &bottomLeft,
const QGeoCoordinate &topRight) {
bool r1 = _pAreaData->initialize(bottomLeft, topRight);
bool r2 = _pEditorData->initialize(bottomLeft, topRight);
return r1 && r2;
}
bool MeasurementComplexItem::initialized() {
return _pCurrentData->initialized();
}
void MeasurementComplexItem::_storeRoutingData( void MeasurementComplexItem::_storeRoutingData(
MeasurementComplexItem::PtrRoutingData pRoute) { MeasurementComplexItem::PtrRoutingData pRoute) {
if (this->_state == STATE::ROUTING) { if (this->_state == STATE::ROUTING) {
......
...@@ -174,6 +174,31 @@ public: ...@@ -174,6 +174,31 @@ public:
//! editingStart(). //! editingStart().
//! //!
Q_INVOKABLE void abortEditing(); Q_INVOKABLE void abortEditing();
//!
//! \brief reset Resets the areas to the state before startEditing().
//!
//! Resets the areas to the state before startEditing(). Does nothing if
//! editinge() == false.
//!
Q_INVOKABLE void reset();
//!
//! \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 at least three vertices, returns false
//! either.
//!
Q_INVOKABLE bool initialized();
// Property getters // Property getters
const AreaData *areaData() const; const AreaData *areaData() const;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <QTimer> #include <QTimer>
#include "GenericSingelton.h"
#include "geometry/MeasurementArea.h" #include "geometry/MeasurementArea.h"
#include "geometry/snake.h" #include "geometry/snake.h"
#include "nemo_interface/QNemoHeartbeat.h" #include "nemo_interface/QNemoHeartbeat.h"
...@@ -426,8 +427,15 @@ bool NemoInterface::Impl::setStatus(NemoInterface::STATUS s) { ...@@ -426,8 +427,15 @@ bool NemoInterface::Impl::setStatus(NemoInterface::STATUS s) {
// =============================================================== // ===============================================================
// NemoInterface // NemoInterface
NemoInterface::NemoInterface(QObject *parent) NemoInterface::NemoInterface()
: QObject(parent), pImpl(std::make_unique<NemoInterface::Impl>(this)) {} : QObject(), pImpl(std::make_unique<NemoInterface::Impl>(this)) {}
NemoInterface *NemoInterface::createInstance() { return new NemoInterface(); }
NemoInterface *NemoInterface::instance() {
return GenericSingelton<NemoInterface>::instance(
NemoInterface::createInstance);
}
NemoInterface::~NemoInterface() {} NemoInterface::~NemoInterface() {}
...@@ -449,9 +457,7 @@ bool NemoInterface::hasTileData(const TileData &tileData) const { ...@@ -449,9 +457,7 @@ bool NemoInterface::hasTileData(const TileData &tileData) const {
return this->pImpl->hasTileData(tileData); return this->pImpl->hasTileData(tileData);
} }
int NemoInterface::status() const { return integral(this->pImpl->status()); } NemoInterface::STATUS NemoInterface::status() const {
NemoInterface::STATUS NemoInterface::statusEnum() const {
return this->pImpl->status(); return this->pImpl->status();
} }
......
...@@ -12,7 +12,14 @@ class NemoInterface : public QObject { ...@@ -12,7 +12,14 @@ class NemoInterface : public QObject {
class Impl; class Impl;
using PImpl = std::unique_ptr<Impl>; using PImpl = std::unique_ptr<Impl>;
NemoInterface();
NemoInterface(NemoInterface &other) = delete;
static NemoInterface *createInstance();
public: public:
~NemoInterface() override;
static NemoInterface *instance();
enum class STATUS { enum class STATUS {
NOT_CONNECTED = 0, NOT_CONNECTED = 0,
HEARTBEAT_DETECTED = 1, HEARTBEAT_DETECTED = 1,
...@@ -20,11 +27,9 @@ public: ...@@ -20,11 +27,9 @@ public:
TIMEOUT = -1, TIMEOUT = -1,
INVALID_HEARTBEAT = -2 INVALID_HEARTBEAT = -2
}; };
Q_ENUM(STATUS)
explicit NemoInterface(QObject *parent = nullptr); Q_PROPERTY(STATUS status READ status NOTIFY statusChanged)
~NemoInterface() override;
Q_PROPERTY(int status READ status NOTIFY statusChanged)
Q_PROPERTY(QString statusString READ statusString NOTIFY statusChanged) Q_PROPERTY(QString statusString READ statusString NOTIFY statusChanged)
Q_PROPERTY(QVector<int> progress READ progress NOTIFY progressChanged) Q_PROPERTY(QVector<int> progress READ progress NOTIFY progressChanged)
Q_PROPERTY(QString editorQml READ editorQml CONSTANT) Q_PROPERTY(QString editorQml READ editorQml CONSTANT)
...@@ -40,8 +45,7 @@ public: ...@@ -40,8 +45,7 @@ public:
void setAutoPublish(bool ap); void setAutoPublish(bool ap);
void setHoldProgress(bool hp); void setHoldProgress(bool hp);
int status() const; STATUS status() const;
STATUS statusEnum() const;
QString statusString() const; QString statusString() const;
QVector<int> progress() const; QVector<int> progress() const;
QString editorQml(); QString editorQml();
...@@ -55,3 +59,5 @@ signals: ...@@ -55,3 +59,5 @@ signals:
private: private:
PImpl pImpl; PImpl pImpl;
}; };
#define pNemoInterface NemoInterface::instance()
...@@ -56,8 +56,14 @@ private: ...@@ -56,8 +56,14 @@ private:
// Example usage: // Example usage:
// QmlObjecListModel list; // QmlObjecListModel list;
// .... add areas .... // .... add areas ....
// auto area = getArea<WimaMeasurementArea *>(list); // returns the first // auto area = getGeoArea<MeasurementArea *>(list); // returns the first
// WimaMeasurementArea or nullptr // MeasurementArea or nullptr
//! \example
//!
//! QmlObjecListModel list;
//! // .... add areas ....
//! auto area = getGeoArea<MeasurementArea *>(list); // returns the first
//! MeasurementArea or nullptr
template <class AreaPtr, class QObjectList> template <class AreaPtr, class QObjectList>
inline AreaPtr getGeoArea(QObjectList &list) { inline AreaPtr getGeoArea(QObjectList &list) {
static_assert(std::is_pointer<AreaPtr>::value, static_assert(std::is_pointer<AreaPtr>::value,
...@@ -72,5 +78,28 @@ inline AreaPtr getGeoArea(QObjectList &list) { ...@@ -72,5 +78,28 @@ inline AreaPtr getGeoArea(QObjectList &list) {
return nullptr; return nullptr;
} }
//! \example
//!
//! QmlObjecListModel list;
//! // .... add areas ....
//! auto areaArray = getGeoAreaArray<MeasurementArea *>(list); // returns a
//! QList<MeasurementArea*>
//! // containing all MeasurementArea's inside list
template <class AreaPtr, template <class> class Container = QList,
class QObjectList>
inline Container<AreaPtr> getGeoAreaList(QObjectList &list) {
static_assert(std::is_pointer<AreaPtr>::value,
"AreaPtr must be a pointer type.");
Container<AreaPtr> out;
for (int i = 0; i < list.count(); ++i) {
auto obj = list[i];
auto area = qobject_cast<AreaPtr>(obj);
if (area != nullptr) {
out.append(area);
}
}
return out;
}
bool copyAreaList(const QmlObjectListModel &from, QmlObjectListModel &to, bool copyAreaList(const QmlObjectListModel &from, QmlObjectListModel &to,
QObject *parent); QObject *parent);
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "QtConcurrentRun" #include "QtConcurrentRun"
#include "nemo_interface/SnakeTile.h" #include "nemo_interface/SnakeTile.h"
#include "snake.h" #include "snake.h"
#include <ctime>
#include <boost/units/systems/si.hpp> #include <boost/units/systems/si.hpp>
...@@ -170,7 +171,7 @@ MeasurementArea::MeasurementArea(QObject *parent) ...@@ -170,7 +171,7 @@ MeasurementArea::MeasurementArea(QObject *parent)
this /* QObject parent */)), this /* QObject parent */)),
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesKey], _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesKey],
this /* QObject parent */)), this /* QObject parent */)),
_state(STATE::IDLE) { _holdProgress(false), _state(STATE::IDLE) {
init(); init();
} }
...@@ -188,7 +189,7 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent) ...@@ -188,7 +189,7 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent)
this /* QObject parent */)), this /* QObject parent */)),
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesKey], _showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesKey],
this /* QObject parent */)), this /* QObject parent */)),
_state(STATE::IDLE) { _holdProgress(false), _state(STATE::IDLE) {
init(); init();
disableUpdate(); disableUpdate();
...@@ -272,6 +273,19 @@ int MeasurementArea::maxTiles() const { return SNAKE_MAX_TILES; } ...@@ -272,6 +273,19 @@ int MeasurementArea::maxTiles() const { return SNAKE_MAX_TILES; }
bool MeasurementArea::ready() const { return this->_state == STATE::IDLE; } bool MeasurementArea::ready() const { return this->_state == STATE::IDLE; }
bool MeasurementArea::measurementCompleted() const {
if (ready()) {
for (const auto &p : _progress) {
if (p != 100) {
return false;
}
}
return true;
} else {
return false;
}
}
bool MeasurementArea::saveToJson(QJsonObject &json) { bool MeasurementArea::saveToJson(QJsonObject &json) {
if (ready()) { if (ready()) {
if (this->GeoArea::saveToJson(json)) { if (this->GeoArea::saveToJson(json)) {
...@@ -406,15 +420,41 @@ bool MeasurementArea::isCorrect() { ...@@ -406,15 +420,41 @@ bool MeasurementArea::isCorrect() {
bool MeasurementArea::setProgress(const QVector<int> &p) { bool MeasurementArea::setProgress(const QVector<int> &p) {
if (ready()) { if (ready()) {
if (p.size() == this->tiles()->count() && this->_progress != p) { if (!_holdProgress && p.size() == this->tiles()->count() &&
this->_progress != p) {
this->_progress = p; this->_progress = p;
emit progressChanged(); emit progressChanged();
emit progressAccepted(); emit progressAccepted();
return true; return true;
} }
} }
emit progressNotAccepted();
return false; return false;
} }
void MeasurementArea::randomProgress() {
if (ready()) {
std::srand(std::time(nullptr));
for (auto &p : _progress) {
p += std::rand() % 100;
if (p > 100) {
p = 100;
}
}
emit progressChanged();
}
}
void MeasurementArea::resetProgress() {
if (ready()) {
for (auto &p : _progress) {
p = 0;
}
emit progressChanged();
}
}
//! //!
//! \brief MeasurementArea::doUpdate //! \brief MeasurementArea::doUpdate
//! \pre MeasurementArea::deferUpdate must be called first, don't call //! \pre MeasurementArea::deferUpdate must be called first, don't call
...@@ -576,3 +616,12 @@ void MeasurementArea::setState(MeasurementArea::STATE s) { ...@@ -576,3 +616,12 @@ void MeasurementArea::setState(MeasurementArea::STATE s) {
} }
} }
} }