Initial implementation for overlay product view, currently only handling NST

This commit is contained in:
Dan Paulat 2024-02-17 00:08:45 -06:00
parent e41e35bfc4
commit 3ca99ca023
3 changed files with 273 additions and 0 deletions

View file

@ -302,12 +302,14 @@ set(HDR_VIEW source/scwx/qt/view/level2_product_view.hpp
source/scwx/qt/view/level3_product_view.hpp
source/scwx/qt/view/level3_radial_view.hpp
source/scwx/qt/view/level3_raster_view.hpp
source/scwx/qt/view/overlay_product_view.hpp
source/scwx/qt/view/radar_product_view.hpp
source/scwx/qt/view/radar_product_view_factory.hpp)
set(SRC_VIEW source/scwx/qt/view/level2_product_view.cpp
source/scwx/qt/view/level3_product_view.cpp
source/scwx/qt/view/level3_radial_view.cpp
source/scwx/qt/view/level3_raster_view.cpp
source/scwx/qt/view/overlay_product_view.cpp
source/scwx/qt/view/radar_product_view.cpp
source/scwx/qt/view/radar_product_view_factory.cpp)

View file

@ -0,0 +1,217 @@
#include <scwx/qt/view/overlay_product_view.hpp>
#include <scwx/qt/manager/radar_product_manager.hpp>
#include <scwx/util/logger.hpp>
#include <scwx/util/time.hpp>
#include <mutex>
#include <boost/asio.hpp>
#include <boost/uuid/random_generator.hpp>
namespace scwx
{
namespace qt
{
namespace view
{
static const std::string logPrefix_ = "scwx::qt::view::overlay_product_view";
static const auto logger_ = util::Logger::Create(logPrefix_);
static const std::string kNst_ = "NST";
class OverlayProductView::Impl
{
public:
explicit Impl(OverlayProductView* self) : self_ {self} {}
~Impl() { threadPool_.join(); }
void ConnectRadarProductManager();
void DisconnectRadarProductManager();
void LoadProduct(const std::string& product,
std::chrono::system_clock::time_point time,
bool autoUpdate);
void ResetProducts();
void UpdateAutoRefresh(bool enabled) const;
OverlayProductView* self_;
boost::uuids::uuid uuid_ {boost::uuids::random_generator()()};
boost::asio::thread_pool threadPool_ {1u};
bool autoRefreshEnabled_ {false};
bool autoUpdateEnabled_ {false};
std::chrono::system_clock::time_point selectedTime_ {};
std::shared_ptr<manager::RadarProductManager> radarProductManager_ {nullptr};
std::unordered_map<std::string, std::shared_ptr<types::RadarProductRecord>>
recordMap_ {};
std::mutex recordMutex_ {};
};
OverlayProductView::OverlayProductView() : p(std::make_unique<Impl>(this)) {};
OverlayProductView::~OverlayProductView() = default;
std::shared_ptr<manager::RadarProductManager>
OverlayProductView::radar_product_manager() const
{
return p->radarProductManager_;
}
std::shared_ptr<types::RadarProductRecord>
OverlayProductView::radar_product_record(const std::string& product) const
{
std::unique_lock lock {p->recordMutex_};
auto it = p->recordMap_.find(product);
if (it != p->recordMap_.cend())
{
return it->second;
}
return nullptr;
}
std::chrono::system_clock::time_point OverlayProductView::selected_time() const
{
return p->selectedTime_;
}
void OverlayProductView::set_radar_product_manager(
const std::shared_ptr<manager::RadarProductManager>& radarProductManager)
{
p->UpdateAutoRefresh(false);
p->DisconnectRadarProductManager();
p->ResetProducts();
p->radarProductManager_ = radarProductManager;
p->ConnectRadarProductManager();
p->UpdateAutoRefresh(p->autoRefreshEnabled_);
}
void OverlayProductView::Impl::ConnectRadarProductManager()
{
connect(
radarProductManager_.get(),
&manager::RadarProductManager::NewDataAvailable,
self_,
[this](common::RadarProductGroup group,
const std::string& product,
std::chrono::system_clock::time_point latestTime)
{
if (autoRefreshEnabled_ &&
group == common::RadarProductGroup::Level3 && product == kNst_)
{
LoadProduct(product, latestTime, autoUpdateEnabled_);
}
},
Qt::QueuedConnection);
}
void OverlayProductView::Impl::DisconnectRadarProductManager()
{
if (radarProductManager_ != nullptr)
{
disconnect(radarProductManager_.get(),
&manager::RadarProductManager::NewDataAvailable,
self_,
nullptr);
}
}
void OverlayProductView::Impl::LoadProduct(
const std::string& product,
std::chrono::system_clock::time_point time,
bool autoUpdate)
{
logger_->debug(
"Load Product: {}, {}, {}", product, util::TimeString(time), autoUpdate);
// Create file request
std::shared_ptr<request::NexradFileRequest> request =
std::make_shared<request::NexradFileRequest>(
radarProductManager_->radar_id());
if (autoUpdate)
{
connect(request.get(),
&request::NexradFileRequest::RequestComplete,
self_,
[=, this](std::shared_ptr<request::NexradFileRequest> request)
{
// Select loaded record
const auto& record = request->radar_product_record();
// Validate record
if (record != nullptr)
{
// Store loaded record
std::unique_lock lock {recordMutex_};
auto it = recordMap_.find(product);
if (it == recordMap_.cend() || it->second != record)
{
recordMap_.insert_or_assign(product, record);
lock.unlock();
Q_EMIT self_->ProductUpdated(product);
}
}
});
}
// Load file
boost::asio::post(
threadPool_,
[=, this]()
{ radarProductManager_->LoadLevel3Data(product, time, request); });
}
void OverlayProductView::Impl::ResetProducts()
{
std::unique_lock lock {recordMutex_};
recordMap_.clear();
lock.unlock();
Q_EMIT self_->ProductUpdated(kNst_);
}
void OverlayProductView::SelectTime(std::chrono::system_clock::time_point time)
{
if (time != p->selectedTime_)
{
p->selectedTime_ = time;
p->LoadProduct(kNst_, time, true);
}
}
void OverlayProductView::SetAutoRefresh(bool enabled)
{
if (p->autoRefreshEnabled_ != enabled)
{
p->autoRefreshEnabled_ = enabled;
p->UpdateAutoRefresh(enabled);
}
}
void OverlayProductView::Impl::UpdateAutoRefresh(bool enabled) const
{
if (radarProductManager_ != nullptr)
{
radarProductManager_->EnableRefresh(
common::RadarProductGroup::Level3, kNst_, enabled, uuid_);
}
}
void OverlayProductView::SetAutoUpdate(bool enabled)
{
p->autoUpdateEnabled_ = enabled;
}
} // namespace view
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,54 @@
#pragma once
#include <scwx/qt/types/radar_product_record.hpp>
#include <chrono>
#include <memory>
#include <QObject>
namespace scwx
{
namespace qt
{
namespace manager
{
class RadarProductManager;
} // namespace manager
namespace view
{
class OverlayProductView : public QObject
{
Q_OBJECT
public:
explicit OverlayProductView();
virtual ~OverlayProductView();
std::shared_ptr<manager::RadarProductManager> radar_product_manager() const;
std::shared_ptr<types::RadarProductRecord>
radar_product_record(const std::string& product) const;
std::chrono::system_clock::time_point selected_time() const;
void set_radar_product_manager(
const std::shared_ptr<manager::RadarProductManager>& radarProductManager);
void SelectTime(std::chrono::system_clock::time_point time);
void SetAutoRefresh(bool enabled);
void SetAutoUpdate(bool enabled);
signals:
void ProductUpdated(std::string product);
private:
class Impl;
std::unique_ptr<Impl> p;
};
} // namespace view
} // namespace qt
} // namespace scwx