diff --git a/src/Airmap/AirMapManager.cc b/src/Airmap/AirMapManager.cc index d75772ab375ca72b4c1038e96b34547c32662439..76e9d769a37983395ba857a763ecf0d1c529c4af 100644 --- a/src/Airmap/AirMapManager.cc +++ b/src/Airmap/AirMapManager.cc @@ -24,6 +24,7 @@ #include #include #include +#include using namespace airmap; @@ -979,3 +980,74 @@ AirspaceRestrictionProvider* AirMapManager::instantiateRestrictionProvider() return restrictionManager; } +AirspaceRulesetsProvider* AirMapManager::instantiateRulesetsProvider() +{ + AirMapRulesetsManager* rulesetsManager = new AirMapRulesetsManager(_shared); + connect(rulesetsManager, &AirMapRulesetsManager::error, this, &AirMapManager::_error); + return rulesetsManager; +} + +//----------------------------------------------------------------------------- +AirMapRulesetsManager::AirMapRulesetsManager(AirMapSharedState& shared) + : _shared(shared) +{ +} + +//----------------------------------------------------------------------------- +void AirMapRulesetsManager::setROI(const QGeoCoordinate& center) +{ + if (!_shared.client()) { + qCDebug(AirMapManagerLog) << "No AirMap client instance. Not updating Airspace"; + return; + } + if (_state != State::Idle) { + qCWarning(AirMapManagerLog) << "AirMapRestrictionManager::updateROI: state not idle"; + return; + } + qCDebug(AirMapManagerLog) << "Setting ROI for Rulesets"; + _state = State::RetrieveItems; + RuleSets::Search::Parameters params; + params.geometry = Geometry::point(center.latitude(), center.longitude()); + std::weak_ptr isAlive(_instance); + _shared.client()->rulesets().search(params, + [this, isAlive](const RuleSets::Search::Result& result) { + if (!isAlive.lock()) return; + if (_state != State::RetrieveItems) return; + if (result) { + const std::vector& rulesets = result.value(); + qCDebug(AirMapManagerLog)<<"Successful rulesets search. Items:" << rulesets.size(); + for (const auto& ruleset : rulesets) { + qDebug() << "------------------------------------------"; + qDebug() << "Jurisdiction:" << ruleset.jurisdiction.name.data() << (int)ruleset.jurisdiction.region; + qDebug() << "Name: " << ruleset.name.data(); + qDebug() << "Short Name: " << ruleset.short_name.data(); + qDebug() << "Description: " << ruleset.description.data(); + qDebug() << "Is default: " << ruleset.is_default; + qDebug() << "Applicable to these airspace types:"; + for (const auto& airspaceType : ruleset.airspace_types) { + qDebug() << airspaceType.data(); + } + qDebug() << "Rules:"; + for (const auto& rule : ruleset.rules) { + qDebug() << " --------------------------------------"; + qDebug() << " " << rule.short_text.data(); + qDebug() << " " << rule.description.data(); + qDebug() << " " << rule.display_order; + qDebug() << " " << (int)rule.status; + qDebug() << " Features:"; + for (const auto& feature : rule.features) { + qDebug() << " " << feature.name.data(); + qDebug() << " " << feature.description.data(); + qDebug() << " " << (int)feature.status; + } + } + } + } else { + QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : ""); + emit error("Failed to retrieve RuleSets", + QString::fromStdString(result.error().message()), description); + } + emit requestDone(true); + _state = State::Idle; + }); +} diff --git a/src/Airmap/AirMapManager.h b/src/Airmap/AirMapManager.h index 6b36b818114e9326ab72904d354e7b4df2464403..03a1feb17ed7c9b24f03a775123db7d84485f27d 100644 --- a/src/Airmap/AirMapManager.h +++ b/src/Airmap/AirMapManager.h @@ -136,6 +136,27 @@ private: AirMapSharedState& _shared; }; +/// class to download rulesets from AirMap +class AirMapRulesetsManager : public AirspaceRulesetsProvider, public LifetimeChecker +{ + Q_OBJECT +public: + AirMapRulesetsManager (AirMapSharedState& shared); + + void setROI (const QGeoCoordinate& center) override; + +signals: + void error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails); + +private: + enum class State { + Idle, + RetrieveItems, + }; + State _state = State::Idle; + AirMapSharedState& _shared; +}; + /// class to upload a flight class AirMapFlightManager : public QObject, public LifetimeChecker @@ -343,9 +364,9 @@ public: void setToolbox(QGCToolbox* toolbox) override; - AirspaceManagerPerVehicle* instantiateVehicle(const Vehicle& vehicle) override; - - AirspaceRestrictionProvider* instantiateRestrictionProvider() override; + AirspaceManagerPerVehicle* instantiateVehicle (const Vehicle& vehicle) override; + AirspaceRestrictionProvider* instantiateRestrictionProvider () override; + AirspaceRulesetsProvider* instantiateRulesetsProvider () override; QString name() const override { return "AirMap"; } diff --git a/src/Airmap/AirspaceManagement.cc b/src/Airmap/AirspaceManagement.cc index 6b0aa1d9d4e3631eac53367de1383ed4b09c6d00..340a939d676c48108f208631194ea41c113c0f29 100644 --- a/src/Airmap/AirspaceManagement.cc +++ b/src/Airmap/AirspaceManagement.cc @@ -50,6 +50,9 @@ AirspaceManager::~AirspaceManager() if (_restrictionsProvider) { delete _restrictionsProvider; } + if(_rulesetsProvider) { + delete _rulesetsProvider; + } _polygonRestrictions.clearAndDeleteContents(); _circleRestrictions.clearAndDeleteContents(); } @@ -64,6 +67,13 @@ void AirspaceManager::setToolbox(QGCToolbox* toolbox) connect(_restrictionsProvider, &AirspaceRestrictionProvider::requestDone, this, &AirspaceManager::_restrictionsUpdated); } + _rulesetsProvider = instantiateRulesetsProvider(); + /* + if (_rulesetsProvider) { + connect(_rulesetsProvider, &AirspaceRulesetsProvider::requestDone, this, + &AirspaceManager::_rulesetsUpdated); + } + */ } void AirspaceManager::setROI(const QGeoCoordinate& center, double radiusMeters) @@ -78,6 +88,11 @@ void AirspaceManager::_updateToROI() if (_restrictionsProvider) { _restrictionsProvider->setROI(_roiCenter, _roiRadius); } + //-- TODO: We may want to check the distance between this ROI and the last + // to see if we really need to update it. + if(_rulesetsProvider) { + _rulesetsProvider->setROI(_roiCenter); + } } void AirspaceManager::_restrictionsUpdated(bool success) diff --git a/src/Airmap/AirspaceManagement.h b/src/Airmap/AirspaceManagement.h index 5a49c69c4f7acd86d66be0fd5a967e15b23fb307..fe6573dab7462cdea6d8c3e399d2f9842638b120 100644 --- a/src/Airmap/AirspaceManagement.h +++ b/src/Airmap/AirspaceManagement.h @@ -120,6 +120,24 @@ protected: QList _circleList; }; +/** + * @class AirspaceRulesetsProvider + * Base class that queries for airspace rulesets + */ +class AirspaceRulesetsProvider : public QObject { + Q_OBJECT +public: + AirspaceRulesetsProvider () = default; + ~AirspaceRulesetsProvider () = default; + /** + * Set region of interest that should be queried. When finished, the requestDone() signal will be emmited. + * @param center Center coordinate for ROI + */ + virtual void setROI (const QGeoCoordinate& center) = 0; +signals: + void requestDone(bool success); +}; + class AirspaceManagerPerVehicle; class Vehicle; @@ -153,11 +171,15 @@ public: virtual AirspaceManagerPerVehicle* instantiateVehicle(const Vehicle& vehicle) = 0; /** - * * Factory method to create an AirspaceRestrictionProvider object */ virtual AirspaceRestrictionProvider* instantiateRestrictionProvider() = 0; + /** + * Factory method to create an AirspaceRulesetsProvider object + */ + virtual AirspaceRulesetsProvider* instantiateRulesetsProvider() = 0; + /** * Set the ROI for airspace information (restrictions shown in UI) * @param center Center coordinate for ROI @@ -190,10 +212,11 @@ private slots: private: void _updateToROI(); - AirspaceRestrictionProvider* _restrictionsProvider = nullptr; ///< restrictions that are shown in the UI + AirspaceRestrictionProvider* _restrictionsProvider = nullptr; ///< restrictions that are shown in the UI + AirspaceRulesetsProvider* _rulesetsProvider = nullptr; ///< restrictions that are shown in the UI - QmlObjectListModel _polygonRestrictions; ///< current polygon restrictions - QmlObjectListModel _circleRestrictions; ///< current circle restrictions + QmlObjectListModel _polygonRestrictions; ///< current polygon restrictions + QmlObjectListModel _circleRestrictions; ///< current circle restrictions QTimer _roiUpdateTimer; QGeoCoordinate _roiCenter;