Commit 5f9f30c2 authored by Valentin Platzgummer's avatar Valentin Platzgummer

generators fixed, _isIncomplete stuff added to MeasurementComplexItem

parent 8da5e19a
......@@ -39,7 +39,7 @@ bool AreaData::insert(GeoArea *areaData) {
if (areaData != nullptr) {
if (Q_LIKELY(!this->_areaList.contains(areaData))) {
_areaList.append(areaData);
emit areaList();
emit areaListChanged();
auto *measurementArea = qobject_cast<MeasurementArea *>(areaData);
if (measurementArea != nullptr) {
......@@ -88,7 +88,7 @@ QmlObjectListModel *AreaData::areaList() { return &_areaList; }
const QmlObjectListModel *AreaData::areaList() const { return &_areaList; }
const QGeoCoordinate &AreaData::origin() const { return _origin; }
QGeoCoordinate AreaData::origin() const { return _origin; }
bool AreaData::isCorrect() {
if (!initialized()) {
......
......@@ -47,7 +47,7 @@ public:
//! \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;
QGeoCoordinate origin() const;
Q_INVOKABLE bool isCorrect();
//!
......
......@@ -37,13 +37,21 @@ CircularGenerator::CircularGenerator(QObject *parent)
: CircularGenerator(nullptr, parent) {}
CircularGenerator::CircularGenerator(GeneratorBase::Data d, QObject *parent)
: GeneratorBase(d, parent), _connectionsEstablished(false),
: GeneratorBase(d, parent),
_metaDataMap(FactMetaData::createMapFromJsonFile(
QStringLiteral(":/json/CircularGenerator.SettingsGroup.json"), this)),
_distance(settingsGroup, _metaDataMap[distanceName]),
_deltaAlpha(settingsGroup, _metaDataMap[deltaAlphaName]),
_minLength(settingsGroup, _metaDataMap[minLengthName]) {
establishConnections();
_minLength(settingsGroup, _metaDataMap[minLengthName]),
_measurementArea(nullptr) {
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);
}
QString CircularGenerator::editorQml() {
......@@ -199,77 +207,47 @@ void CircularGenerator::resetReference() {
}
}
void CircularGenerator::establishConnections() {
if (this->_d != nullptr && !this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
if (measurementArea != nullptr && serviceArea != nullptr) {
GeneratorBase::establishConnections();
Fact *CircularGenerator::distance() { return &_distance; }
connect(this->_d, &AreaData::originChanged, this,
&GeneratorBase::generatorChanged);
connect(measurementArea, &MeasurementArea::progressChanged, this,
&GeneratorBase::generatorChanged);
connect(measurementArea, &MeasurementArea::tilesChanged, this,
&GeneratorBase::generatorChanged);
connect(measurementArea, &MeasurementArea::centerChanged, this,
&CircularGenerator::resetReferenceIfInvalid);
connect(measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
connect(serviceArea, &SafeArea::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;
}
}
Fact *CircularGenerator::deltaAlpha() { return &_deltaAlpha; }
Fact *CircularGenerator::minLength() { return &_minLength; }
void CircularGenerator::onAreaListChanged() {
auto *measurementArea = getGeoArea<MeasurementArea *>(*this->_d->areaList());
setMeasurementArea(measurementArea);
}
void CircularGenerator::deleteConnections() {
if (this->_d != nullptr && this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
if (measurementArea != nullptr && serviceArea != nullptr) {
GeneratorBase::deleteConnections();
void CircularGenerator::setMeasurementArea(MeasurementArea *area) {
if (_measurementArea != area) {
disconnect(this->_d, &AreaData::originChanged, this,
&GeneratorBase::generatorChanged);
disconnect(measurementArea, &MeasurementArea::progressChanged, this,
if (_measurementArea != nullptr) {
disconnect(_measurementArea, &MeasurementArea::progressChanged, this,
&GeneratorBase::generatorChanged);
disconnect(measurementArea, &MeasurementArea::tilesChanged, this,
disconnect(_measurementArea, &MeasurementArea::tilesChanged, this,
&GeneratorBase::generatorChanged);
disconnect(measurementArea, &MeasurementArea::centerChanged, this,
disconnect(_measurementArea, &MeasurementArea::centerChanged, this,
&CircularGenerator::resetReferenceIfInvalid);
disconnect(measurementArea, &MeasurementArea::pathChanged, this,
disconnect(_measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
disconnect(serviceArea, &SafeArea::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 = true;
}
}
}
Fact *CircularGenerator::distance() { return &_distance; }
_measurementArea = area;
Fact *CircularGenerator::deltaAlpha() { return &_deltaAlpha; }
if (_measurementArea != nullptr) {
connect(_measurementArea, &MeasurementArea::progressChanged, this,
&GeneratorBase::generatorChanged);
connect(_measurementArea, &MeasurementArea::tilesChanged, this,
&GeneratorBase::generatorChanged);
connect(_measurementArea, &MeasurementArea::centerChanged, this,
&CircularGenerator::resetReferenceIfInvalid);
connect(_measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
}
Fact *CircularGenerator::minLength() { return &_minLength; }
emit generatorChanged();
}
}
bool circularTransects(const snake::FPoint &reference,
const snake::FPolygon &polygon,
......
......@@ -4,6 +4,8 @@
#include "SettingsFact.h"
class MeasurementArea;
namespace routing {
class CircularGenerator : public GeneratorBase {
......@@ -48,18 +50,16 @@ public slots:
Q_INVOKABLE void resetReferenceIfInvalid();
Q_INVOKABLE void resetReference();
protected:
virtual void establishConnections() override;
virtual void deleteConnections() override;
private:
bool _connectionsEstablished;
void onAreaListChanged();
void setMeasurementArea(MeasurementArea *area);
QGeoCoordinate _reference;
QMap<QString, FactMetaData *> _metaDataMap;
SettingsFact _distance;
SettingsFact _deltaAlpha;
SettingsFact _minLength;
MeasurementArea *_measurementArea;
};
} // namespace routing
......@@ -8,8 +8,6 @@ GeneratorBase::GeneratorBase(QObject *parent)
GeneratorBase::GeneratorBase(GeneratorBase::Data d, QObject *parent)
: QObject(parent), _d(d) {
establishConnections();
connect(_d, &AreaData::areaListChanged, this,
&GeneratorBase::_areaListChangedHandler);
}
GeneratorBase::~GeneratorBase() {}
......@@ -17,27 +15,15 @@ GeneratorBase::~GeneratorBase() {}
GeneratorBase::Data GeneratorBase::data() const { return _d; }
void GeneratorBase::setData(Data d) {
if (d != nullptr) {
if (_d != nullptr) {
disconnect(_d, &AreaData::areaListChanged, this,
&GeneratorBase::_areaListChangedHandler);
}
if (d != _d && d != nullptr) {
deleteConnections();
_d = d;
establishConnections();
connect(_d, &AreaData::areaListChanged, this,
&GeneratorBase::_areaListChangedHandler);
emit dataChanged();
}
}
void GeneratorBase::establishConnections() {}
void GeneratorBase::deleteConnections() {}
void GeneratorBase::_areaListChangedHandler() {
deleteConnections();
establishConnections();
emit generatorChanged();
}
} // namespace routing
......@@ -37,6 +37,7 @@ public:
signals:
void generatorChanged();
void dataChanged();
protected:
virtual void establishConnections();
......@@ -44,7 +45,6 @@ protected:
Data _d;
private:
void _areaListChangedHandler();
};
} // namespace routing
......@@ -32,8 +32,16 @@ LinearGenerator::LinearGenerator(GeneratorBase::Data d, QObject *parent)
QStringLiteral(":/json/LinearGenerator.SettingsGroup.json"), this)),
_distance(settingsGroup, _metaDataMap[distanceName]),
_alpha(settingsGroup, _metaDataMap[alphaName]),
_minLength(settingsGroup, _metaDataMap[minLengthName]) {
establishConnections();
_minLength(settingsGroup, _metaDataMap[minLengthName]),
_measurementArea(nullptr), _safeArea(nullptr) {
connect(this->distance(), &Fact::rawValueChanged, this,
&GeneratorBase::generatorChanged);
connect(this->alpha(), &Fact::rawValueChanged, this,
&GeneratorBase::generatorChanged);
connect(this->minLength(), &Fact::rawValueChanged, this,
&GeneratorBase::generatorChanged);
connect(this->_d, &AreaData::areaListChanged, this,
&LinearGenerator::onAreaListChanged);
}
QString LinearGenerator::editorQml() {
......@@ -147,63 +155,35 @@ Fact *LinearGenerator::alpha() { return &_alpha; }
Fact *LinearGenerator::minLength() { return &_minLength; }
void LinearGenerator::establishConnections() {
if (this->_d != nullptr && !this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
if (measurementArea != nullptr && serviceArea != nullptr) {
GeneratorBase::establishConnections();
connect(this->_d, &AreaData::originChanged, this,
&GeneratorBase::generatorChanged);
connect(measurementArea, &MeasurementArea::progressChanged, this,
&GeneratorBase::generatorChanged);
connect(measurementArea, &MeasurementArea::tilesChanged, this,
&GeneratorBase::generatorChanged);
connect(measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
connect(serviceArea, &SafeArea::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::onAreaListChanged() {
auto *measurementArea = getGeoArea<MeasurementArea *>(*this->_d->areaList());
setMeasurementArea(measurementArea);
}
void LinearGenerator::deleteConnections() {
if (this->_d != nullptr && this->_connectionsEstablished) {
auto measurementArea =
getGeoArea<const MeasurementArea *>(*this->_d->areaList());
auto serviceArea = getGeoArea<const SafeArea *>(*this->_d->areaList());
if (measurementArea != nullptr && serviceArea != nullptr) {
GeneratorBase::deleteConnections();
void LinearGenerator::setMeasurementArea(MeasurementArea *area) {
if (_measurementArea != area) {
disconnect(this->_d, &AreaData::originChanged, this,
if (_measurementArea != nullptr) {
disconnect(_measurementArea, &MeasurementArea::progressChanged, this,
&GeneratorBase::generatorChanged);
disconnect(measurementArea, &MeasurementArea::progressChanged, this,
disconnect(_measurementArea, &MeasurementArea::tilesChanged, this,
&GeneratorBase::generatorChanged);
disconnect(measurementArea, &MeasurementArea::tilesChanged, this,
disconnect(_measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
disconnect(measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
disconnect(serviceArea, &SafeArea::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 = true;
}
_measurementArea = area;
if (_measurementArea != nullptr) {
connect(_measurementArea, &MeasurementArea::progressChanged, this,
&GeneratorBase::generatorChanged);
connect(_measurementArea, &MeasurementArea::tilesChanged, this,
&GeneratorBase::generatorChanged);
connect(_measurementArea, &MeasurementArea::pathChanged, this,
&GeneratorBase::generatorChanged);
}
emit generatorChanged();
}
}
......
......@@ -4,6 +4,9 @@
#include "SettingsFact.h"
class MeasurementArea;
class SafeArea;
namespace routing {
class LinearGenerator : public GeneratorBase {
......@@ -33,17 +36,16 @@ public:
static const char *alphaName;
static const char *minLengthName;
protected:
virtual void establishConnections() override;
virtual void deleteConnections() override;
private:
bool _connectionsEstablished;
void onAreaListChanged();
void setMeasurementArea(MeasurementArea *area);
QMap<QString, FactMetaData *> _metaDataMap;
SettingsFact _distance;
SettingsFact _alpha;
SettingsFact _minLength;
MeasurementArea *_measurementArea;
SafeArea *_safeArea;
};
} // namespace routing
......@@ -72,15 +72,32 @@ MeasurementComplexItem::MeasurementComplexItem(
this->exitCoordinateSameAsEntry());
});
// Connect isIncomplete.
connect(this, &MeasurementComplexItem::idleChanged, [this] {
if (this->idle()) {
if (this->route().size() > 0 && this->_isIncomplete == true) {
this->_isIncomplete = false;
emit this->isIncompleteChanged();
}
} else {
if (this->_isIncomplete == false) {
this->_isIncomplete = true;
emit this->isIncompleteChanged();
}
}
});
connect(this, &MeasurementComplexItem::idleChanged, this,
&MeasurementComplexItem::readyForSaveStateChanged);
// Connect complexDistance.
connect(this, &MeasurementComplexItem::routeChanged,
[this] { emit this->complexDistanceChanged(); });
// Register Generators.
auto lg = new routing::LinearGenerator(this->_pAreaData, this);
registerGenerator(lg->name(), lg);
addGenerator(lg->name(), lg);
auto cg = new routing::CircularGenerator(this->_pAreaData, this);
registerGenerator(cg->name(), cg);
addGenerator(cg->name(), cg);
qCritical() << "ToDo: _altitude connections missing.";
qCritical() << "ToDo: add generator saveing.";
......@@ -192,7 +209,7 @@ void MeasurementComplexItem::save(QJsonArray &planItems) {
qWarning() << "MeasurementComplexItem::save(): area data save missing.";
qWarning() << "MeasurementComplexItem::save(): mission item save missing.";
if (ready()) {
if (idle()) {
QJsonObject saveObject;
saveObject[JsonHelper::jsonVersionKey] = 1;
......@@ -270,7 +287,7 @@ double MeasurementComplexItem::specifiedGimbalPitch() {
void MeasurementComplexItem::appendMissionItems(QList<MissionItem *> &items,
QObject *missionItemParent) {
if (ready()) {
if (idle()) {
qCDebug(MeasurementComplexItemLog) << "appendMissionItems()";
int seqNum = this->_sequenceNumber;
......@@ -350,8 +367,8 @@ void MeasurementComplexItem::_setState(MeasurementComplexItem::STATE state) {
emit editingChanged();
}
if (_ready(oldState) != _ready(state)) {
emit readyChanged();
if (_idle(oldState) != _idle(state)) {
emit idleChanged();
}
}
}
......@@ -364,7 +381,7 @@ bool MeasurementComplexItem::_editing(MeasurementComplexItem::STATE state) {
return state == STATE::EDITING;
}
bool MeasurementComplexItem::_ready(MeasurementComplexItem::STATE state) {
bool MeasurementComplexItem::_idle(MeasurementComplexItem::STATE state) {
return state == STATE::IDLE;
}
......@@ -380,6 +397,7 @@ void MeasurementComplexItem::_updateRoute() {
if (!editing()) {
// Reset data.
this->_route.clear();
emit routeChanged();
this->_variantVector.clear();
this->_variantNames.clear();
emit variantNamesChanged();
......@@ -443,14 +461,14 @@ void MeasurementComplexItem::_updateRoute() {
}
} else {
qCDebug(MeasurementComplexItemLog)
<< "_updateWorker(): plan data invalid.";
<< "_updateWorker(): area data invalid.";
return;
}
}
}
void MeasurementComplexItem::_changeVariant() {
if (ready()) {
if (idle()) {
auto variant = this->_variant.rawValue().toUInt();
// Find old variant and run. Old run corresponts with empty list.
......@@ -470,11 +488,11 @@ void MeasurementComplexItem::_changeVariant() {
if (old_variant != std::numeric_limits<std::size_t>::max()) {
// this->_route containes a route, swap it back to
// this->_solutionVector
auto &oldVariantCoordinates = this->_variantVector[old_variant];
oldVariantCoordinates.swap(this->_route);
auto &oldRoute = this->_variantVector[old_variant];
oldRoute.swap(this->_route);
}
auto &newVariantCoordinates = this->_variantVector[variant];
this->_route.swap(newVariantCoordinates);
auto &newRoute = this->_variantVector[variant];
this->_route.swap(newRoute);
emit routeChanged();
} else { // error
qCDebug(MeasurementComplexItemLog)
......@@ -496,7 +514,7 @@ void MeasurementComplexItem::_changeVariant() {
}
void MeasurementComplexItem::_reverseRoute() {
if (ready()) {
if (idle()) {
if (this->_route.size() > 0) {
auto &t = this->_route;
std::reverse(t.begin(), t.end());
......@@ -507,7 +525,7 @@ void MeasurementComplexItem::_reverseRoute() {
ComplexMissionItem::ReadyForSaveState
MeasurementComplexItem::readyForSaveState() const {
if (ready()) {
if (idle()) {
return ReadyForSaveState::ReadyForSave;
} else {
return ReadyForSaveState::NotReadyForSaveData;
......@@ -557,8 +575,8 @@ int MeasurementComplexItem::lastSequenceNumber() const {
return _sequenceNumber + std::max(0, this->_route.size() - 1);
}
bool MeasurementComplexItem::registerGenerator(const QString &name,
routing::GeneratorBase *g) {
bool MeasurementComplexItem::addGenerator(const QString &name,
routing::GeneratorBase *g) {
if (name.isEmpty()) {
qCDebug(MeasurementComplexItemLog)
<< "registerGenerator(): empty name string.";
......@@ -587,7 +605,7 @@ bool MeasurementComplexItem::registerGenerator(const QString &name,
}
}
bool MeasurementComplexItem::unregisterGenerator(const QString &name) {
bool MeasurementComplexItem::removeGenerator(const QString &name) {
auto index = this->_generatorNameList.indexOf(name);
if (index >= 0) {
// Is this the current generator?
......@@ -615,9 +633,9 @@ bool MeasurementComplexItem::unregisterGenerator(const QString &name) {
}
}
bool MeasurementComplexItem::unregisterGenerator(int index) {
bool MeasurementComplexItem::removeGenerator(int index) {
if (index > 0 && index < this->_generatorNameList.size()) {
return unregisterGenerator(this->_generatorNameList.at(index));
return removeGenerator(this->_generatorNameList.at(index));
} else {
qCDebug(MeasurementComplexItemLog)
<< "unregisterGenerator(): index (" << index
......@@ -701,7 +719,6 @@ void MeasurementComplexItem::_storeRoutingData(
// Store solutions.
auto ori = this->_pAreaData->origin();
ori.setAltitude(0);
const auto &transectsENU = pRoute->transects;
QVector<Variant> variantVector;
const auto nSolutions = pRoute->solutionVector.size();
......@@ -711,60 +728,13 @@ void MeasurementComplexItem::_storeRoutingData(
if (solution.size() > 0) {
const auto &route = solution.at(0);
const auto &path = route.path;
const auto &info = route.info;
if (info.size() > 1) {
// Find index of first waypoint.
std::size_t idxFirst = 0;
const auto &infoFirst = info.at(1);
const auto &firstTransect = transectsENU[infoFirst.index];
if (firstTransect.size() > 0) {
const auto &firstWaypoint = infoFirst.reversed
? firstTransect.back()
: firstTransect.front();
double th = 0.01;
for (std::size_t i = 0; i < path.size(); ++i) {
auto dist = bg::distance(path[i], firstWaypoint);
if (dist < th) {
idxFirst = i;
break;
}
}
// Find index of last waypoint.
std::size_t idxLast = path.size() - 1;
const auto &infoLast = info.at(info.size() - 2);
const auto &lastTransect = transectsENU[infoLast.index];
if (lastTransect.size() > 0) {
const auto &lastWaypoint = infoLast.reversed
? lastTransect.front()
: lastTransect.back();
for (long i = path.size() - 1; i >= 0; --i) {
auto dist = bg::distance(path[i], lastWaypoint);
if (dist < th) {
idxLast = i;
break;
}
}
// Convert to geo coordinates.
for (std::size_t i = idxFirst; i <= idxLast; ++i) {
auto &vertex = path[i];
QGeoCoordinate c;
snake::fromENU(ori, vertex, c);
var.append(QVariant::fromValue(c));
}
} else {
qCDebug(MeasurementComplexItemLog)
<< "_setTransects(): lastTransect.size() == 0";
}
} else {
qCDebug(MeasurementComplexItemLog)
<< "_setTransects(): firstTransect.size() == 0";
}
} else {
qCDebug(MeasurementComplexItemLog)
<< "_setTransects(): transectsInfo.size() <= 1";
// Convert to geo coordinates.
for (const auto &vertex : path) {
QGeoCoordinate c;
snake::fromENU(ori, vertex, c);
var.append(QVariant::fromValue(c));
}
} else {
qCDebug(MeasurementComplexItemLog)
......@@ -789,12 +759,14 @@ void MeasurementComplexItem::_storeRoutingData(
}
emit variantNamesChanged();
// Set variant to 0.
disconnect(&this->_variant, &Fact::rawValueChanged, this,
&MeasurementComplexItem::_changeVariant);
this->_variant.setCookedValue(QVariant(0));
connect(&this->_variant, &Fact::rawValueChanged, this,
&MeasurementComplexItem::_changeVariant);
// Select first variant as route.
this->_route.swap(this->_variantVector.first());
emit routeChanged();
......@@ -817,6 +789,6 @@ bool MeasurementComplexItem::calculating() const {
bool MeasurementComplexItem::editing() const { return _editing(this->_state); }
bool MeasurementComplexItem::ready() const { return _ready(this->_state); }
bool MeasurementComplexItem::idle() const { return _idle(this->_state); }
bool MeasurementComplexItem::followTerrain() const { return _followTerrain; }
......@@ -41,7 +41,7 @@ public:
generatorNameListChanged)
Q_PROPERTY(bool calculating READ calculating NOTIFY calculatingChanged)
Q_PROPERTY(bool editing READ editing NOTIFY editingChanged)
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
Q_PROPERTY(bool idle READ idle NOTIFY idleChanged)
Q_PROPERTY(
routing::GeneratorBase *generator READ generator NOTIFY generatorChanged)
Q_PROPERTY(int generatorIndex READ generatorIndex NOTIFY generatorChanged)
......@@ -94,9 +94,9 @@ public:
virtual QString abbreviation(void) const override final;
// Generator
bool registerGenerator(const QString &name, routing::GeneratorBase *g);
bool unregisterGenerator(const QString &name);
bool unregisterGenerator(int index);
bool addGenerator(const QString &name, routing::GeneratorBase *g);
bool removeGenerator(const QString &name);
bool removeGenerator(int index);
Q_INVOKABLE bool switchToGenerator(const QString &name);
Q_INVOKABLE bool switchToGenerator(int index);
QStringList generatorNameList();
......@@ -137,7 +137,7 @@ public:
bool calculating() const;
bool editing() const;
bool ready() const;
bool idle() const;
bool followTerrain() const;
static const char *settingsGroup;
......@@ -154,7 +154,7 @@ signals:
void calculatingChanged();
void editingChanged();
void readyChanged();
void idleChanged();
void areaDataChanged();
void routeChanged();
......@@ -173,7 +173,7 @@ private:
void _setAreaData(PtrAreaData data);
static bool _calculating(STATE state);
static bool _editing(STATE state);
static bool _ready(STATE state);
static bool _idle(STATE state);
// Hirarcical stuff.
PlanMasterController *_masterController;
......
......@@ -17,13 +17,16 @@ const char *GeoArea::settingsGroup = "GeoArea";
GeoArea::GeoArea(QObject *parent) : QGCMapPolygon(parent) { init(); }
GeoArea::GeoArea(const GeoArea &other, QObject *parent)
: QGCMapPolygon(other, parent), _errorString(other._errorString) {
: QGCMapPolygon(other, parent) {
init();
_errorString = other._errorString;
}
GeoArea &GeoArea::operator=(const GeoArea &other) {
QGCMapPolygon::operator=(other);
_errorString = other._errorString;
return *this;
}
......@@ -63,7 +66,33 @@ bool GeoArea::isCorrect() {
QString GeoArea::errorString() const { return this->_errorString; }
void GeoArea::init() { this->setObjectName(wimaAreaName); }
bool GeoArea::covers(const QGeoCoordinate &c) {
if (GeoArea::isCorrect()) {
auto origin = this->pathModel().value<QGCQGeoCoordinate *>(0)->coordinate();
snake::FPolygon polygonENU;
snake::areaToEnu(origin, this->pathModel(), polygonENU);
snake::FPoint cENU;
snake::toENU(origin, c, cENU);
return bg::covered_by(cENU, polygonENU);
} else {
return false;
}
}
void GeoArea::init() {
this->setObjectName(wimaAreaName);
// connect(this, &GeoArea::pathChanged, [this] {
// if (this->objectName() != "Tile") {
// qDebug() << this->objectName() << " path: " << this->path() << "\n";
// }
// });
// connect(this, &GeoArea::centerChanged, [this] {
// if (this->objectName() != "Tile") {
// qDebug() << this->objectName() << " center: " << this->center() <<
// "\n";
// }
// });
}
void GeoArea::setErrorString(const QString &str) {
this->_errorString = str;
......
......@@ -27,6 +27,13 @@ public:
Q_INVOKABLE virtual bool isCorrect();
Q_INVOKABLE QString errorString() const;
//!
//! \brief covers Checks if GeoArea covers c.
//! \param c
//! \return Returns true if c is inside, or on the border of GeoArea.
//!
Q_INVOKABLE bool covers(const QGeoCoordinate &c);
// static Members
static const char *wimaAreaName;
static const char *areaTypeName;
......
......@@ -23,7 +23,7 @@ TileData &TileData::operator=(const TileData &other) {
const auto *obj = other.tiles[i];
const auto *tile = qobject_cast<const SnakeTile *>(obj);
if (tile != nullptr) {
this->tiles.append(new SnakeTile(*tile, this));
this->tiles.append(tile->clone(this));
} else {
qCWarning(MeasurementAreaLog) << "TileData::operator=: nullptr";
}
......@@ -103,18 +103,41 @@ MeasurementArea::MeasurementArea(const MeasurementArea &other, QObject *parent)
_showTiles(SettingsFact(settingsGroup, _metaDataMap[showTilesName],
this /* QObject parent */)),
_state(STATE::IDLE) {
init();
disableUpdate();
_tileHeight = other._tileHeight;
_tileWidth = other._tileWidth;
_minTileAreaPercent = other._minTileAreaPercent;
_showTiles = other._showTiles;
_progress = other._progress;
_tileData = other._tileData;
init();
if (other.ready()) {
_progress = other._progress;
_tileData = other._tileData;
enableUpdate();
} else {
enableUpdate();
doUpdate();
}
}
MeasurementArea &MeasurementArea::operator=(const MeasurementArea &other) {
GeoArea::operator=(other);
disableUpdate();
_tileHeight = other._tileHeight;
_tileWidth = other._tileWidth;
_minTileAreaPercent = other._minTileAreaPercent;
_showTiles = other._showTiles;
if (other.ready()) {
_progress = other._progress;
_tileData = other._tileData;
enableUpdate();
} else {
enableUpdate();
doUpdate();
}
return *this;
}
......
......@@ -73,7 +73,7 @@ void SafeArea::putDepotInside() {
bool SafeArea::setDepot(const QGeoCoordinate &newDepot) {
if (_depot.latitude() != newDepot.latitude() ||
_depot.longitude() != newDepot.longitude()) {
if (this->containsCoordinate(newDepot)) {
if (this->covers(newDepot)) {
_depot = newDepot;
_depot.setAltitude(0);
emit depotChanged();
......@@ -125,7 +125,7 @@ bool SafeArea::loadFromJson(const QJsonObject &json, QString &errorString) {
bool SafeArea::isCorrect() {
if (GeoArea::isCorrect()) {
if (this->_depot.isValid()) {
if (this->containsCoordinate(this->_depot)) {
if (this->covers(this->_depot)) {
return true;
} else {
setErrorString(tr("Depot outside Safe Area"));
......
#include "SnakeTile.h"
SnakeTile::SnakeTile(QObject *parent) : GeoArea(parent) {}
SnakeTile::SnakeTile(QObject *parent) : GeoArea(parent) { init(); }
SnakeTile::SnakeTile(const SnakeTile &other, QObject *parent)
: GeoArea(parent) {
*this = other;
: GeoArea(other, parent) {
init();
}
SnakeTile::~SnakeTile() {}
......@@ -18,3 +18,5 @@ SnakeTile *SnakeTile::clone(QObject *parent) const {
}
void SnakeTile::push_back(const QGeoCoordinate &c) { this->appendVertex(c); }
void SnakeTile::init() { this->setObjectName("Tile"); }
......@@ -16,4 +16,7 @@ public:
virtual SnakeTile *clone(QObject *parent) const;
void push_back(const QGeoCoordinate &c);
private:
void init();
};
import QtQuick 2.0
import QGroundControl 1.0
import QtLocation 5.11
Item {
id: _root
......@@ -11,74 +12,53 @@ Item {
property var generator
property bool checked: false
property var _referenceComponent: undefined
signal clicked()
onVisibleChanged: {
if (visible){
_addRefPoint()
} else {
_destroyRefPoint()
}
}
Component.onCompleted: {
if (visible){
_addRefPoint()
}
}
Item {
id: refPointItem
Component.onDestruction: {
_destroyRefPoint()
}
property var reference: generator.reference
function _addRefPoint(){
if (!_referenceComponent){
_referenceComponent = refPointComponent.createObject(_root)
map.addMapItem(_referenceComponent)
onReferenceChanged: {
if (mapItem.coordinate !== reference){
mapItem.coordinate = reference
}
}
}
function _destroyRefPoint(){
if (_referenceComponent){
map.removeMapItem(_referenceComponent)
_referenceComponent.destroy()
_referenceComponent = undefined
}
}
MapQuickItem {
id: mapItem
// Ref. point (Base Station)
Component {
id: refPointComponent
DragCoordinate {
id: dragCoordinate
coordinate: _root.generator.reference
anchorPoint.x: sourceItem.anchorPointX
anchorPoint.y: sourceItem.anchorPointY
visible: refPointItem.visible
z: QGroundControl.zOrderMapItems
property var ref: _root.generator.reference
sourceItem:
MissionItemIndexLabel {
checked: true
label: qsTr("Reference")
highlightSelected: true
onClicked: _root.clicked(0)
visible: mapItem.visible
z: mapItem.z
}
}
map: _root.map
z: QGroundControl.zOrderMapItems
checked: _root.checked
coordinate: ref
ItemDragger {
anchor: mapItem
z: QGroundControl.zOrderMapItems+1
draggable: true
onDragReleased: {
syncAndBind()
}
Component.onCompleted: {
syncAndBind()
}
onClicked: {
_root.clicked()
onDragStop:{
_root.generator.reference = mapItem.coordinate
}
}
function syncAndBind(){
if (coordinate.latitude !== ref.latitude ||
coordinate.longitude !== ref.longitude){
_root.generator.reference = coordinate
}
coordinate = Qt.binding(function(){return _root.generator.reference})
}
Component.onCompleted: {
_root.map.addMapItem(mapItem)
}
}
}
......@@ -28,10 +28,12 @@ Item {
property bool _editing: _missionItem.editing
property var _generator: _missionItem.generator
property var _transectsComponent: undefined
property var _entryCoordinate: undefined
property var _exitCoordinate: undefined
property var _generatorVisuals: undefined
property var _routeObject: undefined
property var _entryCoordinateObject: undefined
property var _exitCoordinateObject: undefined
property var _generatorObject: undefined
property var _entryArrowObject: undefined
property var _exitArrowObject: undefined
property bool _isCurrentItem: _missionItem.isCurrentItem
......@@ -53,19 +55,23 @@ Item {
Component.onCompleted: {
console.assert(map != undefined, "please set the map property")
_addEntryCoordinate()
_addExitCoordinate()
_addTransectsComponent()
_addGeneratorVisuals()
var bbox = boundingBox()
_missionItem.areaData.initialize(bbox[0], bbox[1])
// _addEntryCoordinate()
// _addExitCoordinate()
_addTransects()
_addGeneratorVisuals()
_addEntryArrow()
_addExitArrow()
}
Component.onDestruction: {
_destroyEntryCoordinate()
_destroyExitCoordinate()
_destroyTransectsComponent()
// _destroyEntryCoordinate()
// _destroyExitCoordinate()
_destroyTransects()
_destroyGeneratorVisuals()
_destroyEntryArrow()
_destroyExitArrow()
}
on_GeneratorChanged: {
......@@ -78,11 +84,10 @@ Item {
id: visualTransectsComponent
MapPolyline {
visible: !_missionItem.editing
line.color: "white"
line.width: 2
path: _missionItem.route
onPathChanged: console.log("path:" + path)
}
}
......@@ -126,6 +131,37 @@ Item {
}
}
// Entry arrow
Component {
id: entryArrowComponent
MapLineArrow {
property int length: _missionItem.route.length
property var route: _missionItem.route
fromCoord: length > 1 ? route[0] : QtPositioning.coordinate()
toCoord: length > 1 ? route[1] : QtPositioning.coordinate()
arrowPosition: 2
visible: length > 1 && !_missionItem.editing
opacity: _root.opacity
}
}
// Exit arrow
Component {
id: exitArrowComponent
MapLineArrow {
property int length: _missionItem.route.length
property var route: _missionItem.route
fromCoord: length > 3 ? route[length-2] : QtPositioning.coordinate()
toCoord: length > 3 ? route[length-1] : QtPositioning.coordinate()
arrowPosition: 2
visible: length > 3 && !_missionItem.editing
opacity: _root.opacity
}
}
// GeoAreas
Repeater {
......@@ -138,76 +174,101 @@ Item {
// Generator visuals
function _addGeneratorVisuals(){
if (_generator.mapVisualQml && !_generatorVisuals) {
if (_generator.mapVisualQml && !_generatorObject) {
var component = Qt.createComponent(_generator.mapVisualQml)
if (component.status === Component.Error) {
console.log("Error loading Qml: ",
_generator.mapVisualQml, component.errorString())
} else {
_generatorVisuals =
component.createObject(_root, {
"map": _root.map,
"generator": _root._generator,
"checked": Qt.binding(
function(){
return _root._isCurrentItem
})
})
_generatorVisuals.clicked.connect(
_generatorObject = component.createObject(_root, {
"map": _root.map,
"generator": _root._generator,
"checked": Qt.binding(function(){return _root._isCurrentItem})
})
_generatorObject.clicked.connect(
function(){_root.clicked(_missionItem.sequenceNumber)})
}
}
}
function _destroyGeneratorVisuals(){
if(_generatorVisuals){
_generatorVisuals.destroy()
_generatorVisuals = undefined
if(_generatorObject){
_generatorObject.destroy()
_generatorObject = undefined
}
}
function _addTransectsComponent(){
if (!_transectsComponent){
_transectsComponent = visualTransectsComponent.createObject(_root)
map.addMapItem(_transectsComponent)
function _addTransects(){
if (!_routeObject){
_routeObject= visualTransectsComponent.createObject(_root)
map.addMapItem(_routeObject)
}
}
function _addExitCoordinate(){
if (!_exitCoordinate){
_exitCoordinate = exitPointComponent.createObject(_root)
map.addMapItem(_exitCoordinate)
if (!_exitCoordinateObject){
_exitCoordinateObject = exitPointComponent.createObject(_root)
map.addMapItem(_exitCoordinateObject)
}
}
function _addEntryCoordinate(){
if (!_entryCoordinate){
_entryCoordinate = entryPointComponent.createObject(_root)
map.addMapItem(_entryCoordinate)
if (!_entryCoordinateObject){
_entryCoordinateObject = entryPointComponent.createObject(_root)
map.addMapItem(_entryCoordinateObject)
}
}
function _addEntryArrow(){
if (!_entryArrowObject){
_entryArrowObject = entryArrowComponent.createObject(_root)
map.addMapItem(_entryArrowObject)
}
}
function _addExitArrow(){
if (!_exitArrowObject){
_exitArrowObject = exitArrowComponent.createObject(_root)
map.addMapItem(_exitArrowObject)
}
}
function _destroyEntryCoordinate(){
if (_entryCoordinate){
map.removeMapItem(_entryCoordinate)
_entryCoordinate.destroy()
_entryCoordinate = undefined
if (_entryCoordinateObject){
map.removeMapItem(_entryCoordinateObject)
_entryCoordinateObject.destroy()
_entryCoordinateObject = undefined
}
}
function _destroyExitCoordinate(){
if (_exitCoordinate){
map.removeMapItem(_exitCoordinate)
_exitCoordinate.destroy()
_exitCoordinate = undefined
if (_exitCoordinateObject){
map.removeMapItem(_exitCoordinateObject)
_exitCoordinateObject.destroy()
_exitCoordinateObject = undefined
}
}
function _destroyTransects(){
if (_routeObject){
map.removeMapItem(_routeObject)
_routeObject.destroy()
_routeObject= undefined
}
}
function _destroyEntryArrow(){
if (_entryArrowObject){
map.removeMapItem(_entryArrowObject)
_entryArrowObject.destroy()
_entryArrowObject = undefined
}
}
function _destroyTransectsComponent(){
if (_transectsComponent){
map.removeMapItem(_transectsComponent)
_transectsComponent.destroy()
_transectsComponent = undefined
function _destroyExitArrow(){
if (_exitArrowObject){
map.removeMapItem(_exitArrowObject)
_exitArrowObject.destroy()
_exitArrowObject = undefined
}
}
......
......@@ -68,29 +68,36 @@ ColumnLayout {
}
GridLayout{
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.maximumWidth: parent.width
columnSpacing: _margin
rowSpacing: _margin
columns: 6
ExclusiveGroup{id:variantGroup}
Repeater{
id: variantRepeater
property var fact: missionItem.variant
property int variant: fact.value
property var names: missionItem.variantNames
property int len: missionItem.variantNames.length
model: len
delegate: QGCRadioButton {
checked: index === variantRepeater.variant
checked: index === variant
text: variantRepeater.names[index] ? variantRepeater.names[index]: ""
property int variant: missionItem.variant.value
onVariantChanged: {
if (variant === index){
checked = true
}
}
onCheckedChanged: {
if (checked){
if (checked && variant !== index){
missionItem.variant.value = index
}
checked = Qt.binding(function(){ return index === variantRepeater.variant})
}
}
} // variant repeater
......@@ -135,6 +142,13 @@ ColumnLayout {
visible: generatorHeader.checked
}
QGCButton{
text:qsTr("Reverse")
onClicked: missionItem.reverseRoute()
Layout.columnSpan: 2
Layout.fillWidth: true
}
// bussy indicator
ColumnLayout{
Layout.fillWidth: true
......
......@@ -46,57 +46,47 @@ Item {
interiorOpacity: 0.3
}
Loader {
id:depotLoader
sourceComponent: depotComponent
}
// Depot Point.
Component {
id: depotComponent
Item {
id: depotMapItem
Item {
id: depotMapItem
MapQuickItem {
id: mapItem
MapQuickItem {
id: mapItem
coordinate: _root.geoArea.depot
anchorPoint.x: sourceItem.anchorPointX
anchorPoint.y: sourceItem.anchorPointY
visible: true
z: QGroundControl.zOrderMapItems
coordinate: _root.geoArea.depot
anchorPoint.x: sourceItem.anchorPointX
anchorPoint.y: sourceItem.anchorPointY
visible: depotMapItem.visible
z: QGroundControl.zOrderMapItems
Component.onCompleted: {
coordinate = Qt.binding(function(){return _root.geoArea.depot})
}
Component.onCompleted: {
coordinate = Qt.binding(function(){return _root.geoArea.depot})
}
sourceItem:
MissionItemIndexLabel {
checked: true
label: qsTr("Depot")
highlightSelected: true
onClicked: _root.clicked(0)
visible: mapItem.visible
z: mapItem.z
}
sourceItem:
MissionItemIndexLabel {
checked: true
label: qsTr("Depot")
highlightSelected: true
onClicked: _root.clicked(0)
visible: mapItem.visible
z: mapItem.z
}
}
ItemDragger {
anchor: mapItem
z: QGroundControl.zOrderMapItems+1
draggable: _root.geoArea.interactive
ItemDragger {
anchor: mapItem
z: QGroundControl.zOrderMapItems+1
draggable: _root.geoArea.interactive
onDragStop:{
_root.geoArea.depot = mapItem.coordinate
mapItem.coordinate = Qt.binding(function(){return _root.geoArea.depot})
}
onDragStop:{
_root.geoArea.depot = mapItem.coordinate
mapItem.coordinate = Qt.binding(function(){return _root.geoArea.depot})
}
}
Component.onCompleted: {
_root.map.addMapItem(mapItem)
}
Component.onCompleted: {
_root.map.addMapItem(mapItem)
}
}
}
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