From 5b9df2b61a75297d2517c233b48e1a81c79720d3 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 24 Feb 2024 22:50:12 -0600 Subject: [PATCH] Fix loading and updating of NST data, consistent with other level 3 data --- .../scwx/qt/map/overlay_product_layer.cpp | 11 +- .../scwx/qt/view/overlay_product_view.cpp | 110 +++++++++++++----- .../scwx/qt/view/overlay_product_view.hpp | 16 ++- .../storm_tracking_information_message.cpp | 2 +- 4 files changed, 98 insertions(+), 41 deletions(-) diff --git a/scwx-qt/source/scwx/qt/map/overlay_product_layer.cpp b/scwx-qt/source/scwx/qt/map/overlay_product_layer.cpp index 6cc6fbb6..da580228 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_product_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/overlay_product_layer.cpp @@ -131,22 +131,17 @@ void OverlayProductLayer::Impl::UpdateStormTrackingInformation() auto overlayProductView = self_->context()->overlay_product_view(); auto radarProductManager = overlayProductView->radar_product_manager(); - auto record = overlayProductView->radar_product_record("NST"); + auto message = overlayProductView->radar_product_message("NST"); float latitude = 0.0f; float longitude = 0.0f; - std::shared_ptr l3File = nullptr; std::shared_ptr sti = nullptr; std::shared_ptr psb = nullptr; - if (record != nullptr) - { - l3File = record->level3_file(); - } - if (l3File != nullptr) + if (message != nullptr) { sti = std::dynamic_pointer_cast< - wsr88d::rpg::StormTrackingInformationMessage>(l3File->message()); + wsr88d::rpg::StormTrackingInformationMessage>(message); } if (sti != nullptr) { diff --git a/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp b/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp index c57e7010..2ad6fa22 100644 --- a/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp @@ -32,6 +32,7 @@ public: std::chrono::system_clock::time_point time, bool autoUpdate); void ResetProducts(); + void Update(const std::string& product); void UpdateAutoRefresh(bool enabled) const; OverlayProductView* self_; @@ -46,9 +47,9 @@ public: std::shared_ptr radarProductManager_ {nullptr}; - std::unordered_map> - recordMap_ {}; - std::mutex recordMutex_ {}; + std::unordered_map> + messageMap_ {}; + std::mutex messageMutex_ {}; }; OverlayProductView::OverlayProductView() : p(std::make_unique(this)) {}; @@ -60,13 +61,13 @@ OverlayProductView::radar_product_manager() const return p->radarProductManager_; } -std::shared_ptr -OverlayProductView::radar_product_record(const std::string& product) const +std::shared_ptr +OverlayProductView::radar_product_message(const std::string& product) const { - std::unique_lock lock {p->recordMutex_}; + std::unique_lock lock {p->messageMutex_}; - auto it = p->recordMap_.find(product); - if (it != p->recordMap_.cend()) + auto it = p->messageMap_.find(product); + if (it != p->messageMap_.cend()) { return it->second; } @@ -94,6 +95,23 @@ void OverlayProductView::set_radar_product_manager( void OverlayProductView::Impl::ConnectRadarProductManager() { + connect(radarProductManager_.get(), + &manager::RadarProductManager::DataReloaded, + self_, + [this](std::shared_ptr record) + { + if (record->radar_product_group() == + common::RadarProductGroup::Level3 && + record->radar_product() == kNst_ && + std::chrono::floor(record->time()) == + selectedTime_) + { + // If the data associated with the currently selected time is + // reloaded, update the view + Update(record->radar_product()); + } + }); + connect( radarProductManager_.get(), &manager::RadarProductManager::NewDataAvailable, @@ -148,17 +166,24 @@ void OverlayProductView::Impl::LoadProduct( // Select loaded record const auto& record = request->radar_product_record(); - // Validate record + std::shared_ptr level3File = nullptr; + std::shared_ptr message = nullptr; + if (record != nullptr) { - auto productTime = record->time(); - auto level3File = record->level3_file(); - if (level3File != nullptr) - { - const auto& header = level3File->message()->header(); - productTime = util::TimePoint( - header.date_of_message(), header.time_of_message() * 1000); - } + level3File = record->level3_file(); + } + if (level3File != nullptr) + { + message = level3File->message(); + } + + // Validate record + if (message != nullptr) + { + const auto& header = message->header(); + auto productTime = util::TimePoint( + header.date_of_message(), header.time_of_message() * 1000); // If the record is from the last 30 minutes if (productTime + 30min >= std::chrono::system_clock::now() || @@ -166,12 +191,12 @@ void OverlayProductView::Impl::LoadProduct( productTime + 30min >= selectedTime_)) { // Store loaded record - std::unique_lock lock {recordMutex_}; + std::unique_lock lock {messageMutex_}; - auto it = recordMap_.find(product); - if (it == recordMap_.cend() || it->second != record) + auto it = messageMap_.find(product); + if (it == messageMap_.cend() || it->second != message) { - recordMap_.insert_or_assign(product, record); + messageMap_.insert_or_assign(product, message); lock.unlock(); @@ -181,8 +206,8 @@ void OverlayProductView::Impl::LoadProduct( else { // If product is more than 30 minutes old, discard - std::unique_lock lock {recordMutex_}; - std::size_t elementsRemoved = recordMap_.erase(product); + std::unique_lock lock {messageMutex_}; + std::size_t elementsRemoved = messageMap_.erase(product); lock.unlock(); if (elementsRemoved > 0) @@ -197,8 +222,8 @@ void OverlayProductView::Impl::LoadProduct( else { // If the product doesn't exist, erase the stale product - std::unique_lock lock {recordMutex_}; - std::size_t elementsRemoved = recordMap_.erase(product); + std::unique_lock lock {messageMutex_}; + std::size_t elementsRemoved = messageMap_.erase(product); lock.unlock(); if (elementsRemoved > 0) @@ -220,8 +245,8 @@ void OverlayProductView::Impl::LoadProduct( void OverlayProductView::Impl::ResetProducts() { - std::unique_lock lock {recordMutex_}; - recordMap_.clear(); + std::unique_lock lock {messageMutex_}; + messageMap_.clear(); lock.unlock(); Q_EMIT self_->ProductUpdated(kNst_); @@ -232,7 +257,7 @@ void OverlayProductView::SelectTime(std::chrono::system_clock::time_point time) if (time != p->selectedTime_) { p->selectedTime_ = time; - p->LoadProduct(kNst_, time, true); + p->Update(kNst_); } } @@ -245,6 +270,35 @@ void OverlayProductView::SetAutoRefresh(bool enabled) } } +void OverlayProductView::Impl::Update(const std::string& product) +{ + // Retrieve message from Radar Product Manager + std::shared_ptr message; + std::chrono::system_clock::time_point requestedTime {selectedTime_}; + std::chrono::system_clock::time_point foundTime; + std::tie(message, foundTime) = + radarProductManager_->GetLevel3Data(product, requestedTime); + + if (message == nullptr) + { + logger_->debug("{} data not found", product); + return; + } + + std::unique_lock lock {messageMutex_}; + + // Update message in map + auto it = messageMap_.find(product); + if (it == messageMap_.cend() || it->second != message) + { + messageMap_.insert_or_assign(product, message); + + lock.unlock(); + + Q_EMIT self_->ProductUpdated(product); + } +} + void OverlayProductView::Impl::UpdateAutoRefresh(bool enabled) const { if (radarProductManager_ != nullptr) diff --git a/scwx-qt/source/scwx/qt/view/overlay_product_view.hpp b/scwx-qt/source/scwx/qt/view/overlay_product_view.hpp index 31e1cec0..e0083aaf 100644 --- a/scwx-qt/source/scwx/qt/view/overlay_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/overlay_product_view.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include #include @@ -9,6 +7,16 @@ namespace scwx { +namespace wsr88d +{ +namespace rpg +{ + +class Level3Message; + +} // namespace rpg +} // namespace wsr88d + namespace qt { namespace manager @@ -30,8 +38,8 @@ public: virtual ~OverlayProductView(); std::shared_ptr radar_product_manager() const; - std::shared_ptr - radar_product_record(const std::string& product) const; + std::shared_ptr + radar_product_message(const std::string& product) const; std::chrono::system_clock::time_point selected_time() const; void set_radar_product_manager( diff --git a/wxdata/source/scwx/wsr88d/rpg/storm_tracking_information_message.cpp b/wxdata/source/scwx/wsr88d/rpg/storm_tracking_information_message.cpp index b61b05c8..1e920f4b 100644 --- a/wxdata/source/scwx/wsr88d/rpg/storm_tracking_information_message.cpp +++ b/wxdata/source/scwx/wsr88d/rpg/storm_tracking_information_message.cpp @@ -433,7 +433,7 @@ void StormTrackingInformationMessage::Impl::HandleTextUniformPacket( } else { - logger_->warn("Invalid Text Uniform Packet"); + logger_->debug("No storm text present"); } }