#include "AreaData.h" #include "geometry/MeasurementArea.h" #include "geometry/SafeArea.h" #include "QGCLoggingCategory.h" #include "QGCQGeoCoordinate.h" QGC_LOGGING_CATEGORY(AreaDataLog, "AreaDataLog") AreaData::AreaData(QObject *parent) : QObject(parent) {} AreaData::~AreaData() {} AreaData::AreaData(const AreaData &other, QObject *parent) : QObject(parent) { if (!copyAreaList(other._areaList, _areaList, this)) { qCWarning(AreaDataLog) << "AreaData(): not able to copy other._areaList"; } else { _origin = other._origin; } } AreaData &AreaData::operator=(const AreaData &other) { if (!copyAreaList(other._areaList, _areaList, this)) { qCWarning(AreaDataLog) << "operator=(): not able to copy other._areaList"; } else { _origin = other._origin; } return *this; } bool AreaData::insert(GeoArea *areaData) { if (areaData != nullptr) { if (Q_LIKELY(!this->_areaList.contains(areaData))) { _areaList.append(areaData); emit areaList(); return true; } } return false; } void AreaData::remove(GeoArea *areaData) { int index = _areaList.indexOf(areaData); if (index >= 0) { QObject *obj = _areaList.removeAt(index); _setOrigin(_newOrigin()); if (obj->parent() == nullptr) { obj->deleteLater(); } emit areaListChanged(); } } void AreaData::clear() { if (_areaList.count() > 0) { for (int i = 0; i < _areaList.count(); ++i) { remove(_areaList.value(i)); } emit areaListChanged(); } } QmlObjectListModel *AreaData::areaList() { return &_areaList; } const QmlObjectListModel *AreaData::areaList() const { return &_areaList; } const QGeoCoordinate &AreaData::origin() const { return _origin; } bool AreaData::isValid() const { qWarning("AreaData::isValid(): impl. incomplete."); auto *measurementArea = getGeoArea(_areaList); auto *safeArea = getGeoArea(_areaList); return measurementArea != nullptr && safeArea != nullptr && measurementArea->count() >= 3 && safeArea->count() >= 3 && _origin.isValid(); } bool AreaData::tryMakeValid() { qWarning("AreaData::tryMakeValid(): impl. missing."); return true; } bool AreaData::initialize(const QGeoCoordinate &bottomLeft, const QGeoCoordinate &topRight) { // bottomLeft and topRight define the bounding box. if (bottomLeft.isValid() && topRight.isValid() && bottomLeft != topRight) { auto *measurementArea = getGeoArea(_areaList); auto *safeArea = getGeoArea(_areaList); if (safeArea == nullptr) { safeArea = new SafeArea(this); if (!insert(safeArea)) { safeArea->deleteLater(); qCCritical(AreaDataLog) << "initialize(): safeArea == nullptr, but insert() failed."; return false; } } if (measurementArea == nullptr) { measurementArea = new MeasurementArea(this); if (!insert(measurementArea)) { measurementArea->deleteLater(); qCCritical(AreaDataLog) << "initialize(): measurementArea == nullptr, " "but insert() failed."; return false; } } // Fit safe area to bounding box. safeArea->clear(); safeArea->appendVertex(bottomLeft); safeArea->appendVertex( QGeoCoordinate(topRight.latitude(), bottomLeft.longitude())); safeArea->appendVertex(topRight); safeArea->appendVertex( QGeoCoordinate(bottomLeft.latitude(), topRight.longitude())); // Put measurement area inside safeArea; measurementArea->clear(); measurementArea->appendVertex(QGeoCoordinate( 0.8 * bottomLeft.latitude() + 0.2 * topRight.latitude(), 0.8 * bottomLeft.longitude() + 0.2 * topRight.longitude())); measurementArea->appendVertex(QGeoCoordinate( 0.2 * bottomLeft.latitude() + 0.8 * topRight.latitude(), 0.8 * bottomLeft.longitude() + 0.2 * topRight.longitude())); measurementArea->appendVertex(QGeoCoordinate( 0.2 * bottomLeft.latitude() + 0.8 * topRight.latitude(), 0.2 * bottomLeft.longitude() + 0.8 * topRight.longitude())); measurementArea->appendVertex(QGeoCoordinate( 0.8 * bottomLeft.latitude() + 0.2 * topRight.latitude(), 0.2 * bottomLeft.longitude() + 0.8 * topRight.longitude())); return true; } else { qCWarning(AreaDataLog) << "initialize(): bounding box invaldid (bottomLeft, topRight) " << bottomLeft << "," << topRight; return false; } } bool AreaData::initialized() { auto *measurementArea = getGeoArea(_areaList); auto *safeArea = getGeoArea(_areaList); return measurementArea != nullptr && safeArea != nullptr && measurementArea->count() >= 3 && safeArea->count() >= 3; } bool AreaData::operator==(const AreaData &other) const { if (_areaList.count() == other._areaList.count()) { for (int i = 0; i < _areaList.count(); ++i) { if (_areaList[i] != other._areaList[i]) { return false; } } return true; } else { return false; } } bool AreaData::operator!=(const AreaData &other) const { return !(*this == other); } void AreaData::_setOrigin(const QGeoCoordinate &origin) { if (this->_origin != origin) { this->_origin = origin; emit originChanged(); } } QGeoCoordinate AreaData::_newOrigin() { auto *measurementArea = getGeoArea(_areaList); auto *safeArea = getGeoArea(_areaList); if (measurementArea != nullptr && measurementArea->pathModel().count() > 0) { QGCQGeoCoordinate *ori = measurementArea->pathModel().value(0); if (ori != nullptr && ori->coordinate().isValid()) { return ori->coordinate(); } } if (safeArea != nullptr && safeArea->pathModel().count() > 0) { QGCQGeoCoordinate *ori = measurementArea->pathModel().value(0); if (ori != nullptr && ori->coordinate().isValid()) { return ori->coordinate(); } } return QGeoCoordinate(); }