From 95de37cab4e9e62752b5300efb59f201d5e697f9 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 3 Apr 2022 14:20:19 -0500 Subject: [PATCH] Support selecting level 2 files for display --- .../scwx/qt/manager/radar_product_manager.cpp | 96 +++++++++---------- .../scwx/qt/manager/radar_product_manager.hpp | 7 -- scwx-qt/source/scwx/qt/map/map_widget.cpp | 66 +++++++++++-- .../scwx/qt/view/level2_product_view.cpp | 21 ++-- .../scwx/qt/view/level2_product_view.hpp | 2 + .../scwx/qt/view/radar_product_view.hpp | 2 + .../qt/view/radar_product_view_factory.cpp | 7 +- .../qt/view/radar_product_view_factory.hpp | 2 +- 8 files changed, 125 insertions(+), 78 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 7f227817..50677406 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -63,6 +63,8 @@ public: } ~RadarProductManagerImpl() = default; + std::shared_ptr + GetLevel2ProductRecord(std::chrono::system_clock::time_point time); std::shared_ptr StoreRadarProductRecord(std::shared_ptr record); @@ -85,10 +87,6 @@ public: std::map>> level3ProductRecords_; - - std::map> - level2VolumeScans_; }; RadarProductManager::RadarProductManager(const std::string& radarId) : @@ -114,18 +112,6 @@ std::shared_ptr RadarProductManager::radar_site() const return p->radarSite_; } -std::shared_ptr RadarProductManager::level2_data() const -{ - std::shared_ptr level2Data = nullptr; - - if (p->level2VolumeScans_.size() > 0) - { - level2Data = p->level2VolumeScans_.crbegin()->second; - } - - return level2Data; -} - void RadarProductManager::Initialize() { if (p->initialized_) @@ -315,25 +301,50 @@ void RadarProductManagerImpl::LoadNexradFile( }); } -void RadarProductManager::LoadLevel2Data(const std::string& filename) +std::shared_ptr +RadarProductManagerImpl::GetLevel2ProductRecord( + std::chrono::system_clock::time_point time) { - std::shared_ptr ar2vFile = - std::make_shared(); + std::shared_ptr record = nullptr; - if (!p->initialized_) + // TODO: Round to minutes + + // Find the first product record greater than the time requested + auto it = level2ProductRecords_.upper_bound(time); + + // A product record with a time greater was found + if (it != level2ProductRecords_.cend()) { - Initialize(); + // Are there product records prior to this record? + if (it != level2ProductRecords_.cbegin()) + { + // Get the product record immediately preceding, this the record we are + // looking for + --it; + + // Does the record contain the time we are looking for? + if (it->second->level2_file()->start_time() <= time && + time <= it->second->level2_file()->end_time()) + { + record = it->second; + } + } + } + else if (level2ProductRecords_.size() > 0) + { + // A product record with a time greater was not found. If it exists, it + // must be the last record. + auto rit = level2ProductRecords_.rbegin(); + + // Does the record contain the time we are looking for? + if (rit->second->level2_file()->start_time() <= time && + time <= rit->second->level2_file()->end_time()) + { + record = rit->second; + } } - bool success = ar2vFile->LoadFile(filename); - if (!success) - { - return; - } - - p->level2VolumeScans_[ar2vFile->start_time()] = ar2vFile; - - emit Level2DataLoaded(); + return record; } std::shared_ptr @@ -393,30 +404,15 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, float elevationCut = 0.0f; std::vector elevationCuts; - if (p->level2VolumeScans_.size() > 0) + std::shared_ptr record = + p->GetLevel2ProductRecord(time); + + if (record != nullptr) { std::tie(radarData, elevationCut, elevationCuts) = - p->level2VolumeScans_.crbegin()->second->GetElevationScan( + record->level2_file()->GetElevationScan( dataBlockType, elevation, time); } - else - { - scwx::util::async( - [&]() - { - std::unique_lock lock(fileLoadMutex_); - - BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Start load"; - - QString filename = qgetenv("AR2V_FILE"); - if (!filename.isEmpty() && p->level2VolumeScans_.size() == 0) - { - LoadLevel2Data(filename.toUtf8().constData()); - } - - BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "End load"; - }); - } return std::tie(radarData, elevationCut, elevationCuts); } diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp index 120ff673..79774dea 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp @@ -32,11 +32,7 @@ public: const std::vector& coordinates(common::RadialSize radialSize) const; std::shared_ptr radar_site() const; - // TODO: Improve this interface - std::shared_ptr level2_data() const; - void Initialize(); - void LoadLevel2Data(const std::string& filename); std::tuple, float, @@ -55,9 +51,6 @@ public: LoadFile(const std::string& filename, std::shared_ptr request = nullptr); -signals: - void Level2DataLoaded(); - private: std::unique_ptr p; diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 79cea908..9c0deac0 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,7 @@ public: radarProductLayer_ {nullptr}, overlayLayer_ {nullptr}, colorTableLayer_ {nullptr}, + selectedTime_ {}, lastPos_(), currentStyleIndex_ {0}, frameDraws_(0), @@ -77,6 +79,9 @@ public: const std::string& before = {}); bool UpdateStoredMapParameters(); + common::Level2Product + GetLevel2ProductOrDefault(const std::string& productName) const; + std::shared_ptr context_; MapWidget* widget_; @@ -92,6 +97,8 @@ public: std::shared_ptr overlayLayer_; std::shared_ptr colorTableLayer_; + std::chrono::system_clock::time_point selectedTime_; + QPointF lastPos_; uint8_t currentStyleIndex_; @@ -144,6 +151,28 @@ std::vector MapWidget::GetElevationCuts() const } } +common::Level2Product +MapWidgetImpl::GetLevel2ProductOrDefault(const std::string& productName) const +{ + common::Level2Product level2Product = common::GetLevel2Product(productName); + + if (level2Product == common::Level2Product::Unknown) + { + if (context_->radarProductView_ != nullptr) + { + common::Level2Product level2Product = common::GetLevel2Product( + context_->radarProductView_->GetRadarProductName()); + } + } + + if (level2Product == common::Level2Product::Unknown) + { + level2Product = common::Level2Product::Reflectivity; + } + + return level2Product; +} + common::RadarProductGroup MapWidget::GetRadarProductGroup() const { if (p->context_->radarProductView_ != nullptr) @@ -187,6 +216,7 @@ void MapWidget::SelectElevation(float elevation) if (p->context_->radarProductView_ != nullptr) { p->context_->radarProductView_->SelectElevation(elevation); + p->context_->radarProductView_->Update(); } } @@ -204,6 +234,7 @@ void MapWidget::SelectRadarProduct(common::Level2Product product) radarProductView = view::RadarProductViewFactory::Create( product, currentElevation, p->radarProductManager_); + radarProductView->SelectTime(p->selectedTime_); connect( radarProductView.get(), @@ -229,17 +260,21 @@ void MapWidget::SelectRadarProduct(common::Level2Product product) }, Qt::QueuedConnection); - radarProductView->Initialize(); + util::async( + [=]() + { + radarProductView->Initialize(); - std::string colorTableFile = - manager::SettingsManager::palette_settings()->palette( - common::GetLevel2Palette(product)); - if (!colorTableFile.empty()) - { - std::shared_ptr colorTable = - common::ColorTable::Load(colorTableFile); - radarProductView->LoadColorTable(colorTable); - } + std::string colorTableFile = + manager::SettingsManager::palette_settings()->palette( + common::GetLevel2Palette(product)); + if (!colorTableFile.empty()) + { + std::shared_ptr colorTable = + common::ColorTable::Load(colorTableFile); + radarProductView->LoadColorTable(colorTable); + } + }); if (p->map_ != nullptr) { @@ -256,6 +291,17 @@ void MapWidget::SelectRadarProduct(const std::string& radarId, << logPrefix_ << "SelectRadarProduct(" << radarId << ", " << common::GetRadarProductGroupName(group) << ", " << product << ", " << util::TimeString(time) << ")"; + + p->radarProductManager_ = manager::RadarProductManager::Instance(radarId); + p->selectedTime_ = time; + + if (group == common::RadarProductGroup::Level2) + { + common::Level2Product level2Product = + p->GetLevel2ProductOrDefault(product); + + SelectRadarProduct(level2Product); + } } void MapWidget::SetActive(bool isActive) 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 18d08c98..81615b73 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp @@ -47,6 +47,7 @@ public: product_ {product}, radarProductManager_ {radarProductManager}, selectedElevation_ {elevation}, + selectedTime_ {}, elevationScan_ {nullptr}, momentDataBlock0_ {nullptr}, latitude_ {}, @@ -80,7 +81,8 @@ public: wsr88d::rda::DataBlockType dataBlockType_; std::shared_ptr radarProductManager_; - float selectedElevation_; + float selectedElevation_; + std::chrono::system_clock::time_point selectedTime_; std::shared_ptr elevationScan_; std::shared_ptr momentDataBlock0_; @@ -116,10 +118,6 @@ Level2ProductView::Level2ProductView( p(std::make_unique( product, elevation, radarProductManager)) { - connect(radarProductManager.get(), - &manager::RadarProductManager::Level2DataLoaded, - this, - &Level2ProductView::ComputeSweep); } Level2ProductView::~Level2ProductView() = default; @@ -248,6 +246,15 @@ void Level2ProductView::LoadColorTable( void Level2ProductView::SelectElevation(float elevation) { p->selectedElevation_ = elevation; +} + +void Level2ProductView::SelectTime(std::chrono::system_clock::time_point time) +{ + p->selectedTime_ = time; +} + +void Level2ProductView::Update() +{ util::async([=]() { ComputeSweep(); }); } @@ -348,8 +355,8 @@ void Level2ProductView::ComputeSweep() std::shared_ptr radarData; std::tie(radarData, p->elevationCut_, p->elevationCuts_) = - p->radarProductManager_->GetLevel2Data(p->dataBlockType_, - p->selectedElevation_); + p->radarProductManager_->GetLevel2Data( + p->dataBlockType_, p->selectedElevation_, p->selectedTime_); if (radarData == nullptr || radarData == p->elevationScan_) { return; diff --git a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp index b7f65f87..50de666e 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp @@ -40,6 +40,8 @@ public: void LoadColorTable(std::shared_ptr colorTable) override; void SelectElevation(float elevation) override; + void SelectTime(std::chrono::system_clock::time_point time) override; + void Update() override; common::RadarProductGroup GetRadarProductGroup() const override; std::string GetRadarProductName() const override; 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 20bb0df6..bb3658a8 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -39,6 +39,8 @@ public: virtual void LoadColorTable(std::shared_ptr colorTable) = 0; virtual void SelectElevation(float elevation); + virtual void SelectTime(std::chrono::system_clock::time_point time) = 0; + virtual void Update() = 0; virtual common::RadarProductGroup GetRadarProductGroup() const = 0; virtual std::string GetRadarProductName() const = 0; diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view_factory.cpp b/scwx-qt/source/scwx/qt/view/radar_product_view_factory.cpp index cabd2ace..43830828 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view_factory.cpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view_factory.cpp @@ -19,14 +19,14 @@ typedef std::function( CreateRadarProductFunction; std::shared_ptr RadarProductViewFactory::Create( - const std::string& productGroup, + common::RadarProductGroup productGroup, const std::string& productName, float elevation, std::shared_ptr radarProductManager) { std::shared_ptr view = nullptr; - if (productGroup == "L2") + if (productGroup == common::RadarProductGroup::Level2) { common::Level2Product product = common::GetLevel2Product(productName); @@ -43,7 +43,8 @@ std::shared_ptr RadarProductViewFactory::Create( else { BOOST_LOG_TRIVIAL(warning) - << logPrefix_ << "Unknown radar product group: " << productGroup; + << logPrefix_ << "Unknown radar product group: " + << common::GetRadarProductGroupName(productGroup); } return view; diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view_factory.hpp b/scwx-qt/source/scwx/qt/view/radar_product_view_factory.hpp index aa85000d..752b988a 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view_factory.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view_factory.hpp @@ -28,7 +28,7 @@ private: public: static std::shared_ptr - Create(const std::string& productGroup, + Create(common::RadarProductGroup productGroup, const std::string& productName, float elevation, std::shared_ptr radarProductManager);