From 1b49e317e40045eb8b02d001568311b893ca6b9f Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Tue, 30 May 2023 23:28:02 -0500 Subject: [PATCH] Fix level 2 display --- scwx-qt/source/scwx/qt/main/main_window.cpp | 3 +- .../scwx/qt/manager/radar_product_manager.cpp | 66 +++++++++++++++++-- scwx-qt/source/scwx/qt/map/map_widget.cpp | 15 +++++ scwx-qt/source/scwx/qt/map/map_widget.hpp | 19 +++--- .../scwx/qt/view/level2_product_view.cpp | 3 +- .../scwx/qt/view/radar_product_view.cpp | 5 ++ .../scwx/qt/view/radar_product_view.hpp | 3 +- 7 files changed, 96 insertions(+), 18 deletions(-) diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index e0b8254b..8b14dc85 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -849,7 +849,8 @@ void MainWindowImpl::SelectRadarProduct(map::MapWidget* mapWidget, UpdateRadarProductSettings(); } - mapWidget->SelectRadarProduct(group, productName, productCode); + mapWidget->SelectRadarProduct( + group, productName, productCode, mapWidget->GetSelectedTime()); } void MainWindowImpl::SetActiveMap(map::MapWidget* mapWidget) 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 a98a812f..24ba870d 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -205,6 +205,7 @@ public: std::shared_mutex& recordMutex, std::mutex& loadDataMutex, std::shared_ptr request); + void PopulateLevel2ProductTimes(std::chrono::system_clock::time_point time); static void LoadNexradFile(CreateNexradFileFunction load, @@ -944,6 +945,59 @@ void RadarProductManagerImpl::LoadNexradFile( }); } +void RadarProductManagerImpl::PopulateLevel2ProductTimes( + std::chrono::system_clock::time_point time) +{ + const auto today = std::chrono::floor(time); + const auto yesterday = today - std::chrono::days {1}; + const auto tomorrow = today + std::chrono::days {1}; + const auto dates = {yesterday, today, tomorrow}; + + std::set volumeTimes {}; + std::mutex volumeTimesMutex {}; + + // For yesterday, today and tomorrow (in parallel) + std::for_each(std::execution::par_unseq, + dates.begin(), + dates.end(), + [&, this](const auto& date) + { + // Don't query for a time point in the future + if (date > std::chrono::system_clock::now()) + { + return; + } + + // Query the provider for volume time points + auto timePoints = + level2ProviderManager_->provider_->GetTimePointsByDate( + date); + + // Lock the merged volume time list + std::unique_lock volumeTimesLock {volumeTimesMutex}; + + // Copy time points to the merged list + std::copy(timePoints.begin(), + timePoints.end(), + std::inserter(volumeTimes, volumeTimes.end())); + }); + + // Lock the level 2 product record map + std::unique_lock lock {level2ProductRecordMutex_}; + + // Merge volume times into map + std::transform( + volumeTimes.cbegin(), + volumeTimes.cend(), + std::inserter(level2ProductRecords_, level2ProductRecords_.begin()), + [](const std::chrono::system_clock::time_point& time) + { + return std::pair>( + time, std::weak_ptr {}); + }); +} + std::tuple, std::chrono::system_clock::time_point> RadarProductManagerImpl::GetLevel2ProductRecord( @@ -953,6 +1007,9 @@ RadarProductManagerImpl::GetLevel2ProductRecord( RadarProductRecordMap::const_pointer recordPtr {nullptr}; std::chrono::system_clock::time_point recordTime {time}; + // Ensure Level 2 product records are updated + PopulateLevel2ProductTimes(time); + if (!level2ProductRecords_.empty() && time == std::chrono::system_clock::time_point {}) { @@ -967,12 +1024,9 @@ RadarProductManagerImpl::GetLevel2ProductRecord( if (recordPtr != nullptr) { - if (time == std::chrono::system_clock::time_point {} || - time == recordPtr->first) - { - recordTime = recordPtr->first; - record = recordPtr->second.lock(); - } + // Don't check for an exact time match for level 2 products + recordTime = recordPtr->first; + record = recordPtr->second.lock(); } if (record == nullptr && diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 3be5f28e..c3aeebc7 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -316,6 +316,21 @@ std::shared_ptr MapWidget::GetRadarSite() const return radarSite; } +std::chrono::system_clock::time_point MapWidget::GetSelectedTime() const +{ + auto radarProductView = p->context_->radar_product_view(); + std::chrono::system_clock::time_point time; + + // If there is an active radar product view + if (radarProductView != nullptr) + { + // Select the time associated with the active radar product + time = radarProductView->GetSelectedTime(); + } + + return time; +} + std::uint16_t MapWidget::GetVcp() const { auto radarProductView = p->context_->radar_product_view(); diff --git a/scwx-qt/source/scwx/qt/map/map_widget.hpp b/scwx-qt/source/scwx/qt/map/map_widget.hpp index d6d0214b..51cfb230 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.hpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.hpp @@ -34,15 +34,16 @@ public: explicit MapWidget(const QMapLibreGL::Settings&); ~MapWidget(); - common::Level3ProductCategoryMap GetAvailableLevel3Categories(); - float GetElevation() const; - std::vector GetElevationCuts() const; - std::vector GetLevel3Products(); - std::string GetMapStyle() const; - common::RadarProductGroup GetRadarProductGroup() const; - std::string GetRadarProductName() const; - std::shared_ptr GetRadarSite() const; - std::uint16_t GetVcp() const; + common::Level3ProductCategoryMap GetAvailableLevel3Categories(); + float GetElevation() const; + std::vector GetElevationCuts() const; + std::vector GetLevel3Products(); + std::string GetMapStyle() const; + common::RadarProductGroup GetRadarProductGroup() const; + std::string GetRadarProductName() const; + std::shared_ptr GetRadarSite() const; + std::chrono::system_clock::time_point GetSelectedTime() const; + std::uint16_t GetVcp() const; void SelectElevation(float elevation); diff --git a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp index 53b9080c..ad4e6367 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp @@ -119,7 +119,8 @@ void Level2ProductView::ConnectRadarProductManager() { if (record->radar_product_group() == common::RadarProductGroup::Level2 && - record->time() == selected_time()) + std::chrono::floor(record->time()) == + selected_time()) { // If the data associated with the currently selected time is // reloaded, update the view diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp index a282e1f4..2f4c6f23 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp @@ -146,6 +146,11 @@ RadarProductView::GetCfpMomentData() const return std::tie(data, dataSize, componentSize); } +std::chrono::system_clock::time_point RadarProductView::GetSelectedTime() const +{ + return p->selectedTime_; +} + void RadarProductView::ComputeSweep() { logger_->debug("ComputeSweep()"); diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp index 8a589a48..16d23a80 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -61,7 +61,8 @@ public: virtual std::tuple GetMomentData() const = 0; virtual std::tuple - GetCfpMomentData() const; + GetCfpMomentData() const; + std::chrono::system_clock::time_point GetSelectedTime() const; protected: virtual void ConnectRadarProductManager() = 0;