Add available products to Radar Product Manager

This commit is contained in:
Dan Paulat 2022-09-06 08:05:51 -05:00
parent 0ca1ec2269
commit c2e56b8e32
4 changed files with 157 additions and 20 deletions

View file

@ -45,6 +45,8 @@ static constexpr uint32_t NUM_COORIDNATES_0_5_DEGREE =
static constexpr uint32_t NUM_COORIDNATES_1_DEGREE =
NUM_RADIAL_GATES_1_DEGREE * 2;
static const std::string kDefaultLevel3Product_ {"N0B"};
static constexpr std::chrono::seconds kRetryInterval_ {15};
// TODO: Find a way to garbage collect this
@ -97,6 +99,7 @@ public:
self_ {self},
radarId_ {radarId},
initialized_ {false},
level3ProductsInitialized_ {false},
radarSite_ {config::RadarSite::Get(radarId)},
coordinates0_5Degree_ {},
coordinates1Degree_ {},
@ -109,8 +112,11 @@ public:
level3ProviderManagerMap_ {},
level3ProviderManagerMutex_ {},
initializeMutex_ {},
level3ProductsInitializeMutex_ {},
loadLevel2DataMutex_ {},
loadLevel3DataMutex_ {}
loadLevel3DataMutex_ {},
availableCategoryMap_ {},
availableCategoryMutex_ {}
{
if (radarSite_ == nullptr)
{
@ -138,6 +144,9 @@ public:
RadarProductManager* self_;
std::shared_ptr<ProviderManager>
GetLevel3ProviderManager(const std::string& product);
void EnableRefresh(
std::shared_ptr<RadarProductManagerImpl::ProviderManager> providerManager,
bool enabled);
@ -165,6 +174,7 @@ public:
std::string radarId_;
bool initialized_;
bool level3ProductsInitialized_;
std::shared_ptr<config::RadarSite> radarSite_;
@ -184,8 +194,12 @@ public:
std::shared_mutex level3ProviderManagerMutex_;
std::mutex initializeMutex_;
std::mutex level3ProductsInitializeMutex_;
std::mutex loadLevel2DataMutex_;
std::mutex loadLevel3DataMutex_;
common::Level3ProductCategoryMap availableCategoryMap_;
std::shared_mutex availableCategoryMutex_;
};
RadarProductManager::RadarProductManager(const std::string& radarId) :
@ -353,6 +367,30 @@ void RadarProductManager::Initialize()
p->initialized_ = true;
}
std::shared_ptr<RadarProductManagerImpl::ProviderManager>
RadarProductManagerImpl::GetLevel3ProviderManager(const std::string& product)
{
std::unique_lock lock(level3ProviderManagerMutex_);
if (!level3ProviderManagerMap_.contains(product))
{
level3ProviderManagerMap_.emplace(
std::piecewise_construct,
std::forward_as_tuple(product),
std::forward_as_tuple(
std::make_shared<RadarProductManagerImpl::ProviderManager>(
common::RadarProductGroup::Level3, product)));
level3ProviderManagerMap_.at(product)->provider_ =
provider::NexradDataProviderFactory::CreateLevel3DataProvider(radarId_,
product);
}
std::shared_ptr<RadarProductManagerImpl::ProviderManager> providerManager =
level3ProviderManagerMap_.at(product);
return providerManager;
}
void RadarProductManager::EnableRefresh(common::RadarProductGroup group,
const std::string& product,
bool enabled)
@ -363,27 +401,25 @@ void RadarProductManager::EnableRefresh(common::RadarProductGroup group,
}
else
{
std::unique_lock lock(p->level3ProviderManagerMutex_);
if (!p->level3ProviderManagerMap_.contains(product))
{
p->level3ProviderManagerMap_.emplace(
std::piecewise_construct,
std::forward_as_tuple(product),
std::forward_as_tuple(
std::make_shared<RadarProductManagerImpl::ProviderManager>(
common::RadarProductGroup::Level3, product)));
p->level3ProviderManagerMap_.at(product)->provider_ =
provider::NexradDataProviderFactory::CreateLevel3DataProvider(
p->radarId_, product);
}
std::shared_ptr<RadarProductManagerImpl::ProviderManager>
providerManager = p->level3ProviderManagerMap_.at(product);
providerManager = p->GetLevel3ProviderManager(product);
lock.unlock();
// Only enable refresh on available products
util::async(
[=]()
{
providerManager->provider_->RequestAvailableProducts();
auto availableProducts =
providerManager->provider_->GetAvailableProducts();
p->EnableRefresh(providerManager, enabled);
if (std::find(std::execution::par_unseq,
availableProducts.cbegin(),
availableProducts.cend(),
product) != availableProducts.cend())
{
p->EnableRefresh(providerManager, enabled);
}
});
}
}
@ -809,6 +845,95 @@ RadarProductManager::GetLevel3Data(const std::string& product,
return message;
}
common::Level3ProductCategoryMap
RadarProductManager::GetAvailableLevel3Categories()
{
std::shared_lock lock {p->availableCategoryMutex_};
return p->availableCategoryMap_;
}
std::vector<std::string> RadarProductManager::GetLevel3Products()
{
auto level3ProviderManager =
p->GetLevel3ProviderManager(kDefaultLevel3Product_);
return level3ProviderManager->provider_->GetAvailableProducts();
}
void RadarProductManager::UpdateAvailableProducts()
{
std::lock_guard<std::mutex> guard(p->level3ProductsInitializeMutex_);
if (p->level3ProductsInitialized_)
{
return;
}
// Although not complete here, only initialize once. Signal will be emitted
// once complete.
p->level3ProductsInitialized_ = true;
logger_->debug("UpdateAvailableProducts()");
util::async(
[=]()
{
auto level3ProviderManager =
p->GetLevel3ProviderManager(kDefaultLevel3Product_);
level3ProviderManager->provider_->RequestAvailableProducts();
auto updatedAwipsIdList =
level3ProviderManager->provider_->GetAvailableProducts();
std::unique_lock lock {p->availableCategoryMutex_};
for (common::Level3ProductCategory category :
common::Level3ProductCategoryIterator())
{
const auto& products =
common::GetLevel3ProductsByCategory(category);
std::unordered_map<std::string, std::vector<std::string>>
availableProducts;
for (const auto& product : products)
{
const auto& awipsIds =
common::GetLevel3AwipsIdsByProduct(product);
std::vector<std::string> availableAwipsIds;
for (const auto& awipsId : awipsIds)
{
if (std::find(updatedAwipsIdList.cbegin(),
updatedAwipsIdList.cend(),
awipsId) != updatedAwipsIdList.cend())
{
availableAwipsIds.push_back(awipsId);
}
}
if (!availableAwipsIds.empty())
{
availableProducts.insert_or_assign(
product, std::move(availableAwipsIds));
}
}
if (!availableProducts.empty())
{
p->availableCategoryMap_.insert_or_assign(
category, std::move(availableProducts));
}
else
{
p->availableCategoryMap_.erase(category);
}
}
emit Level3ProductsChanged();
});
}
std::shared_ptr<RadarProductManager>
RadarProductManager::Instance(const std::string& radarSite)
{

View file

@ -1,5 +1,6 @@
#pragma once
#include <scwx/common/products.hpp>
#include <scwx/common/types.hpp>
#include <scwx/qt/config/radar_site.hpp>
#include <scwx/qt/request/nexrad_file_request.hpp>
@ -8,6 +9,7 @@
#include <scwx/wsr88d/level3_file.hpp>
#include <memory>
#include <unordered_map>
#include <vector>
#include <QObject>
@ -69,7 +71,12 @@ public:
LoadFile(const std::string& filename,
std::shared_ptr<request::NexradFileRequest> request = nullptr);
common::Level3ProductCategoryMap GetAvailableLevel3Categories();
std::vector<std::string> GetLevel3Products();
void UpdateAvailableProducts();
signals:
void Level3ProductsChanged();
void NewDataAvailable(common::RadarProductGroup group,
const std::string& product,
std::chrono::system_clock::time_point latestTime);