From 4ab4a8825b43b05c3e7703865eb2bc426046c003 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Wed, 19 Mar 2025 12:41:01 -0400 Subject: [PATCH] Check for product availability on radar site change. --- .../scwx/qt/manager/radar_product_manager.cpp | 8 ++ scwx-qt/source/scwx/qt/map/map_widget.cpp | 112 +++++++++++++++++- 2 files changed, 116 insertions(+), 4 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp index edafecf5..48584a2d 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -230,6 +230,7 @@ public: const std::string radarId_; bool initialized_; bool level3ProductsInitialized_; + bool level3AvailabilityReady_ {false}; std::shared_ptr radarSite_; std::size_t cacheLimit_ {6u}; @@ -1585,6 +1586,12 @@ void RadarProductManager::UpdateAvailableProducts() if (p->level3ProductsInitialized_) { + if (p->level3AvailabilityReady_) + { + // Multiple maps may use the same manager, so this ensures that all get + // notified of the change + Q_EMIT Level3ProductsChanged(); + } return; } @@ -1660,6 +1667,7 @@ void RadarProductManagerImpl::UpdateAvailableProductsSync() } } + level3AvailabilityReady_ = true; Q_EMIT self_->Level3ProductsChanged(); } diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index f2599579..b4882345 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -178,9 +179,11 @@ public: void SelectNearestRadarSite(double latitude, double longitude, std::optional type); - void SetRadarSite(const std::string& radarSite); + void SetRadarSite(const std::string& radarSite, + bool checkProductAvailability = false); void UpdateLoadedStyle(); bool UpdateStoredMapParameters(); + void CheckLevel3Availability(); std::string FindMapSymbologyLayer(); @@ -268,6 +271,10 @@ public: std::set activeHotkeys_ {}; std::chrono::system_clock::time_point prevHotkeyTime_ {}; + bool productAvailabilityCheckNeeded_ {false}; + bool productAvailabilityUpdated_ {false}; + bool productAvailabilityProductSelected_ {false}; + public slots: void Update(); }; @@ -429,6 +436,14 @@ void MapWidgetImpl::ConnectSignals() &manager::HotkeyManager::HotkeyReleased, this, &MapWidgetImpl::HandleHotkeyReleased); + connect(widget_, + &MapWidget::RadarSiteUpdated, + widget_, + [this](const std::shared_ptr&) + { + productAvailabilityProductSelected_ = true; + CheckLevel3Availability(); + }); } void MapWidgetImpl::HandleHotkeyPressed(types::Hotkey hotkey, bool isAutoRepeat) @@ -913,7 +928,7 @@ void MapWidget::SelectRadarSite(std::shared_ptr radarSite, p->map_->setCoordinate( {radarSite->latitude(), radarSite->longitude()}); } - p->SetRadarSite(radarSite->id()); + p->SetRadarSite(radarSite->id(), true); p->Update(); // Select products from new site @@ -1772,7 +1787,12 @@ void MapWidgetImpl::RadarProductManagerConnect() connect(radarProductManager_.get(), &manager::RadarProductManager::Level3ProductsChanged, this, - [this]() { Q_EMIT widget_->Level3ProductsChanged(); }); + [this]() + { + productAvailabilityUpdated_ = true; + CheckLevel3Availability(); + Q_EMIT widget_->Level3ProductsChanged(); + }); connect( radarProductManager_.get(), @@ -1990,7 +2010,8 @@ void MapWidgetImpl::SelectNearestRadarSite(double latitude, } } -void MapWidgetImpl::SetRadarSite(const std::string& radarSite) +void MapWidgetImpl::SetRadarSite(const std::string& radarSite, + bool checkProductAvailability) { // Check if radar site has changed if (radarProductManager_ == nullptr || @@ -2009,6 +2030,12 @@ void MapWidgetImpl::SetRadarSite(const std::string& radarSite) // Connect signals to new RadarProductManager RadarProductManagerConnect(); + // Once the available products are loaded, check to make sure the current + // one is available + productAvailabilityCheckNeeded_ = checkProductAvailability; + productAvailabilityUpdated_ = false; + productAvailabilityProductSelected_ = false; + radarProductManager_->UpdateAvailableProducts(); } } @@ -2053,6 +2080,83 @@ bool MapWidgetImpl::UpdateStoredMapParameters() return changed; } +void MapWidgetImpl::CheckLevel3Availability() +{ + /* + * productAvailabilityCheckNeeded_ Only do this when it is indicated that it + * is needed (mostly on radar site change). This is mainly to avoid potential + * recursion with SelectRadarProduct calls. + * + * productAvailabilityUpdated_ Only update once the product availability + * has been updated + * + * productAvailabilityProductSelected_ Only update once the radar site is + * fully selected, including the current product + */ + if (!(productAvailabilityCheckNeeded_ && productAvailabilityUpdated_ && + productAvailabilityProductSelected_)) + { + return; + } + productAvailabilityCheckNeeded_ = false; + + // Only do this for level3 products + if (widget_->GetRadarProductGroup() != common::RadarProductGroup::Level3) + { + return; + } + + const common::Level3ProductCategoryMap& categoryMap = + widget_->GetAvailableLevel3Categories(); + + const std::string& productTilt = context_->radar_product(); + const std::string& productName = + common::GetLevel3ProductByAwipsId(productTilt); + const common::Level3ProductCategory productCategory = + common::GetLevel3CategoryByProduct(productName); + if (productCategory == common::Level3ProductCategory::Unknown) + { + return; + } + + const auto& availableProductsIt = categoryMap.find(productCategory); + // Has no products in this category, do not change categories + if (availableProductsIt == categoryMap.cend()) + { + return; + } + + const auto& availableProducts = availableProductsIt->second; + const auto& availableTiltsIt = availableProducts.find(productName); + // Does not have the same product, but has others in the same category. + // Switch to the default product and tilt in this category. + if (availableTiltsIt == availableProducts.cend()) + { + widget_->SelectRadarProduct( + common::RadarProductGroup::Level3, + common::GetLevel3CategoryDefaultProduct(productCategory, categoryMap), + 0, + widget_->GetSelectedTime()); + return; + } + + const auto& availableTilts = availableTiltsIt->second; + const auto& tilt = std::ranges::find_if( + availableTilts, + [productTilt](const std::string& tilt) { return productTilt == tilt; }); + // Tilt is not available, set it to first tilt + if (tilt == availableTilts.cend() && availableTilts.size() > 0) + { + widget_->SelectRadarProduct(common::RadarProductGroup::Level3, + availableTilts[0], + 0, + widget_->GetSelectedTime()); + return; + } + + // Tilt is available, no change needed +} + } // namespace map } // namespace qt } // namespace scwx