Support selecting level 2 files for display

This commit is contained in:
Dan Paulat 2022-04-03 14:20:19 -05:00
parent 1655a7c571
commit 95de37cab4
8 changed files with 125 additions and 78 deletions

View file

@ -63,6 +63,8 @@ public:
}
~RadarProductManagerImpl() = default;
std::shared_ptr<types::RadarProductRecord>
GetLevel2ProductRecord(std::chrono::system_clock::time_point time);
std::shared_ptr<types::RadarProductRecord>
StoreRadarProductRecord(std::shared_ptr<types::RadarProductRecord> record);
@ -85,10 +87,6 @@ public:
std::map<std::chrono::system_clock::time_point,
std::shared_ptr<types::RadarProductRecord>>>
level3ProductRecords_;
std::map<std::chrono::system_clock::time_point,
std::shared_ptr<wsr88d::Ar2vFile>>
level2VolumeScans_;
};
RadarProductManager::RadarProductManager(const std::string& radarId) :
@ -114,18 +112,6 @@ std::shared_ptr<config::RadarSite> RadarProductManager::radar_site() const
return p->radarSite_;
}
std::shared_ptr<const wsr88d::Ar2vFile> RadarProductManager::level2_data() const
{
std::shared_ptr<const wsr88d::Ar2vFile> 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<types::RadarProductRecord>
RadarProductManagerImpl::GetLevel2ProductRecord(
std::chrono::system_clock::time_point time)
{
std::shared_ptr<wsr88d::Ar2vFile> ar2vFile =
std::make_shared<wsr88d::Ar2vFile>();
std::shared_ptr<types::RadarProductRecord> 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<types::RadarProductRecord>
@ -393,30 +404,15 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
float elevationCut = 0.0f;
std::vector<float> elevationCuts;
if (p->level2VolumeScans_.size() > 0)
std::shared_ptr<types::RadarProductRecord> 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);
}

View file

@ -32,11 +32,7 @@ public:
const std::vector<float>& coordinates(common::RadialSize radialSize) const;
std::shared_ptr<config::RadarSite> radar_site() const;
// TODO: Improve this interface
std::shared_ptr<const wsr88d::Ar2vFile> level2_data() const;
void Initialize();
void LoadLevel2Data(const std::string& filename);
std::tuple<std::shared_ptr<wsr88d::rda::ElevationScan>,
float,
@ -55,9 +51,6 @@ public:
LoadFile(const std::string& filename,
std::shared_ptr<request::NexradFileRequest> request = nullptr);
signals:
void Level2DataLoaded();
private:
std::unique_ptr<RadarProductManagerImpl> p;

View file

@ -8,6 +8,7 @@
#include <scwx/qt/map/radar_product_layer.hpp>
#include <scwx/qt/map/radar_range_layer.hpp>
#include <scwx/qt/view/radar_product_view_factory.hpp>
#include <scwx/util/threads.hpp>
#include <scwx/util/time.hpp>
#include <QApplication>
@ -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<MapContext> context_;
MapWidget* widget_;
@ -92,6 +97,8 @@ public:
std::shared_ptr<OverlayLayer> overlayLayer_;
std::shared_ptr<ColorTableLayer> colorTableLayer_;
std::chrono::system_clock::time_point selectedTime_;
QPointF lastPos_;
uint8_t currentStyleIndex_;
@ -144,6 +151,28 @@ std::vector<float> 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<common::ColorTable> 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<common::ColorTable> 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)

View file

@ -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<manager::RadarProductManager> radarProductManager_;
float selectedElevation_;
float selectedElevation_;
std::chrono::system_clock::time_point selectedTime_;
std::shared_ptr<wsr88d::rda::ElevationScan> elevationScan_;
std::shared_ptr<wsr88d::rda::MomentDataBlock> momentDataBlock0_;
@ -116,10 +118,6 @@ Level2ProductView::Level2ProductView(
p(std::make_unique<Level2ProductViewImpl>(
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<wsr88d::rda::ElevationScan> 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;

View file

@ -40,6 +40,8 @@ public:
void LoadColorTable(std::shared_ptr<common::ColorTable> 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;

View file

@ -39,6 +39,8 @@ public:
virtual void
LoadColorTable(std::shared_ptr<common::ColorTable> 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;

View file

@ -19,14 +19,14 @@ typedef std::function<std::shared_ptr<RadarProductView>(
CreateRadarProductFunction;
std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
const std::string& productGroup,
common::RadarProductGroup productGroup,
const std::string& productName,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager)
{
std::shared_ptr<RadarProductView> view = nullptr;
if (productGroup == "L2")
if (productGroup == common::RadarProductGroup::Level2)
{
common::Level2Product product = common::GetLevel2Product(productName);
@ -43,7 +43,8 @@ std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
else
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Unknown radar product group: " << productGroup;
<< logPrefix_ << "Unknown radar product group: "
<< common::GetRadarProductGroupName(productGroup);
}
return view;

View file

@ -28,7 +28,7 @@ private:
public:
static std::shared_ptr<RadarProductView>
Create(const std::string& productGroup,
Create(common::RadarProductGroup productGroup,
const std::string& productName,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager);