#include "SafeArea.h" #include "QGCLoggingCategory.h" #include "QGCQGeoCoordinate.h" #include QGC_LOGGING_CATEGORY(SafeAreaLog, "SafeAreaLog") const char *SafeArea::safeAreaName = "Safe Area"; const char *SafeArea::depotLatitudeName = "DepotLatitude"; const char *SafeArea::depotLongitudeName = "DepotLongitude"; const char *SafeArea::depotAltitudeName = "DepotAltitude"; SafeArea::SafeArea(QObject *parent) : GeoArea(parent) { init(); } SafeArea::SafeArea(const SafeArea &other, QObject *parent) : GeoArea(other, parent), _depot(other.depot()) { init(); } SafeArea &SafeArea::operator=(const SafeArea &other) { GeoArea::operator=(other); this->setDepot(other.depot()); return *this; } QString SafeArea::mapVisualQML() const { return "SafeAreaMapVisual.qml"; } QString SafeArea::editorQML() const { return "SafeAreaEditor.qml"; } SafeArea *SafeArea::clone(QObject *parent) const { return new SafeArea(*this, parent); } const QGeoCoordinate &SafeArea::depot() const { return _depot; } QGeoCoordinate SafeArea::depotQml() const { return _depot; } bool SafeArea::setDepot(const QGeoCoordinate &coordinate) { if (_depot.latitude() != coordinate.latitude() || _depot.longitude() != coordinate.longitude()) { if (this->containsCoordinate(coordinate)) { _depot = coordinate; _depot.setAltitude(0); emit depotChanged(); return true; } } return false; } void SafeArea::saveToJson(QJsonObject &json) { this->GeoArea::saveToJson(json); json[areaTypeName] = safeAreaName; json[depotLatitudeName] = _depot.latitude(); json[depotLongitudeName] = _depot.longitude(); json[depotAltitudeName] = _depot.altitude(); } bool SafeArea::loadFromJson(const QJsonObject &json, QString &errorString) { bool retVal = false; if (this->GeoArea::loadFromJson(json, errorString)) { double lat = 0; if (json.contains(depotLatitudeName) && json[depotLatitudeName].isDouble()) { lat = json[depotLatitudeName].toDouble(); double lon = 0; if (json.contains(depotLongitudeName) && json[depotLongitudeName].isDouble()) { lon = json[depotLongitudeName].toDouble(); double alt = 0; if (json.contains(depotAltitudeName) && json[depotAltitudeName].isDouble()) { alt = json[depotAltitudeName].toDouble(); this->setDepot(QGeoCoordinate(lat, lon, alt)); retVal = true; } else { errorString = "Not able to load depot altitude."; } } else { errorString = "Not able to load depot longitude."; } } else { errorString = "Not able to load depot latitude."; } retVal = true; } return retVal; } void SafeArea::init() { this->setObjectName(safeAreaName); connect(this, &GeoArea::pathChanged, [this] { if (!this->_depot.isValid() || !this->containsCoordinate(this->_depot)) { if (this->containsCoordinate(this->center())) { // Use center. this->setDepot(this->center()); } else if (this->_depot.isValid()) { // Use nearest coordinate. auto minDist = std::numeric_limits::infinity(); int minIndex = 0; for (int idx = 0; idx < this->pathModel().count(); ++idx) { const QObject *obj = this->pathModel()[idx]; const auto *vertex = qobject_cast(obj); if (vertex != nullptr) { auto d = vertex->coordinate().distanceTo(this->_depot); if (d < minDist) { minDist = d; minIndex = idx; } } else { qCCritical(SafeAreaLog) << "init(): nullptr catched!"; } } this->setDepot(this->pathModel() .value(minIndex) ->coordinate()); } else if (this->pathModel().count() > 0) { // Use first coordinate. this->setDepot( this->pathModel().value(0)->coordinate()); } } }); }