mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 09:10:04 +00:00 
			
		
		
		
	Add available products to Radar Product Manager
This commit is contained in:
		
							parent
							
								
									0ca1ec2269
								
							
						
					
					
						commit
						c2e56b8e32
					
				
					 4 changed files with 157 additions and 20 deletions
				
			
		|  | @ -45,6 +45,8 @@ static constexpr uint32_t NUM_COORIDNATES_0_5_DEGREE = | ||||||
| static constexpr uint32_t NUM_COORIDNATES_1_DEGREE = | static constexpr uint32_t NUM_COORIDNATES_1_DEGREE = | ||||||
|    NUM_RADIAL_GATES_1_DEGREE * 2; |    NUM_RADIAL_GATES_1_DEGREE * 2; | ||||||
| 
 | 
 | ||||||
|  | static const std::string kDefaultLevel3Product_ {"N0B"}; | ||||||
|  | 
 | ||||||
| static constexpr std::chrono::seconds kRetryInterval_ {15}; | static constexpr std::chrono::seconds kRetryInterval_ {15}; | ||||||
| 
 | 
 | ||||||
| // TODO: Find a way to garbage collect this
 | // TODO: Find a way to garbage collect this
 | ||||||
|  | @ -97,6 +99,7 @@ public: | ||||||
|        self_ {self}, |        self_ {self}, | ||||||
|        radarId_ {radarId}, |        radarId_ {radarId}, | ||||||
|        initialized_ {false}, |        initialized_ {false}, | ||||||
|  |        level3ProductsInitialized_ {false}, | ||||||
|        radarSite_ {config::RadarSite::Get(radarId)}, |        radarSite_ {config::RadarSite::Get(radarId)}, | ||||||
|        coordinates0_5Degree_ {}, |        coordinates0_5Degree_ {}, | ||||||
|        coordinates1Degree_ {}, |        coordinates1Degree_ {}, | ||||||
|  | @ -109,8 +112,11 @@ public: | ||||||
|        level3ProviderManagerMap_ {}, |        level3ProviderManagerMap_ {}, | ||||||
|        level3ProviderManagerMutex_ {}, |        level3ProviderManagerMutex_ {}, | ||||||
|        initializeMutex_ {}, |        initializeMutex_ {}, | ||||||
|  |        level3ProductsInitializeMutex_ {}, | ||||||
|        loadLevel2DataMutex_ {}, |        loadLevel2DataMutex_ {}, | ||||||
|        loadLevel3DataMutex_ {} |        loadLevel3DataMutex_ {}, | ||||||
|  |        availableCategoryMap_ {}, | ||||||
|  |        availableCategoryMutex_ {} | ||||||
|    { |    { | ||||||
|       if (radarSite_ == nullptr) |       if (radarSite_ == nullptr) | ||||||
|       { |       { | ||||||
|  | @ -138,6 +144,9 @@ public: | ||||||
| 
 | 
 | ||||||
|    RadarProductManager* self_; |    RadarProductManager* self_; | ||||||
| 
 | 
 | ||||||
|  |    std::shared_ptr<ProviderManager> | ||||||
|  |    GetLevel3ProviderManager(const std::string& product); | ||||||
|  | 
 | ||||||
|    void EnableRefresh( |    void EnableRefresh( | ||||||
|       std::shared_ptr<RadarProductManagerImpl::ProviderManager> providerManager, |       std::shared_ptr<RadarProductManagerImpl::ProviderManager> providerManager, | ||||||
|       bool                                                      enabled); |       bool                                                      enabled); | ||||||
|  | @ -165,6 +174,7 @@ public: | ||||||
| 
 | 
 | ||||||
|    std::string radarId_; |    std::string radarId_; | ||||||
|    bool        initialized_; |    bool        initialized_; | ||||||
|  |    bool        level3ProductsInitialized_; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<config::RadarSite> radarSite_; |    std::shared_ptr<config::RadarSite> radarSite_; | ||||||
| 
 | 
 | ||||||
|  | @ -184,8 +194,12 @@ public: | ||||||
|    std::shared_mutex level3ProviderManagerMutex_; |    std::shared_mutex level3ProviderManagerMutex_; | ||||||
| 
 | 
 | ||||||
|    std::mutex initializeMutex_; |    std::mutex initializeMutex_; | ||||||
|  |    std::mutex level3ProductsInitializeMutex_; | ||||||
|    std::mutex loadLevel2DataMutex_; |    std::mutex loadLevel2DataMutex_; | ||||||
|    std::mutex loadLevel3DataMutex_; |    std::mutex loadLevel3DataMutex_; | ||||||
|  | 
 | ||||||
|  |    common::Level3ProductCategoryMap availableCategoryMap_; | ||||||
|  |    std::shared_mutex                availableCategoryMutex_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| RadarProductManager::RadarProductManager(const std::string& radarId) : | RadarProductManager::RadarProductManager(const std::string& radarId) : | ||||||
|  | @ -353,6 +367,30 @@ void RadarProductManager::Initialize() | ||||||
|    p->initialized_ = true; |    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, | void RadarProductManager::EnableRefresh(common::RadarProductGroup group, | ||||||
|                                         const std::string&        product, |                                         const std::string&        product, | ||||||
|                                         bool                      enabled) |                                         bool                      enabled) | ||||||
|  | @ -363,28 +401,26 @@ void RadarProductManager::EnableRefresh(common::RadarProductGroup group, | ||||||
|    } |    } | ||||||
|    else |    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> |       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(); | ||||||
| 
 | 
 | ||||||
|  |             if (std::find(std::execution::par_unseq, | ||||||
|  |                           availableProducts.cbegin(), | ||||||
|  |                           availableProducts.cend(), | ||||||
|  |                           product) != availableProducts.cend()) | ||||||
|  |             { | ||||||
|                p->EnableRefresh(providerManager, enabled); |                p->EnableRefresh(providerManager, enabled); | ||||||
|             } |             } | ||||||
|  |          }); | ||||||
|  |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RadarProductManagerImpl::EnableRefresh( | void RadarProductManagerImpl::EnableRefresh( | ||||||
|  | @ -809,6 +845,95 @@ RadarProductManager::GetLevel3Data(const std::string& product, | ||||||
|    return message; |    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> | std::shared_ptr<RadarProductManager> | ||||||
| RadarProductManager::Instance(const std::string& radarSite) | RadarProductManager::Instance(const std::string& radarSite) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <scwx/common/products.hpp> | ||||||
| #include <scwx/common/types.hpp> | #include <scwx/common/types.hpp> | ||||||
| #include <scwx/qt/config/radar_site.hpp> | #include <scwx/qt/config/radar_site.hpp> | ||||||
| #include <scwx/qt/request/nexrad_file_request.hpp> | #include <scwx/qt/request/nexrad_file_request.hpp> | ||||||
|  | @ -8,6 +9,7 @@ | ||||||
| #include <scwx/wsr88d/level3_file.hpp> | #include <scwx/wsr88d/level3_file.hpp> | ||||||
| 
 | 
 | ||||||
| #include <memory> | #include <memory> | ||||||
|  | #include <unordered_map> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| #include <QObject> | #include <QObject> | ||||||
|  | @ -69,7 +71,12 @@ public: | ||||||
|    LoadFile(const std::string&                          filename, |    LoadFile(const std::string&                          filename, | ||||||
|             std::shared_ptr<request::NexradFileRequest> request = nullptr); |             std::shared_ptr<request::NexradFileRequest> request = nullptr); | ||||||
| 
 | 
 | ||||||
|  |    common::Level3ProductCategoryMap GetAvailableLevel3Categories(); | ||||||
|  |    std::vector<std::string>         GetLevel3Products(); | ||||||
|  |    void                             UpdateAvailableProducts(); | ||||||
|  | 
 | ||||||
| signals: | signals: | ||||||
|  |    void Level3ProductsChanged(); | ||||||
|    void NewDataAvailable(common::RadarProductGroup             group, |    void NewDataAvailable(common::RadarProductGroup             group, | ||||||
|                          const std::string&                    product, |                          const std::string&                    product, | ||||||
|                          std::chrono::system_clock::time_point latestTime); |                          std::chrono::system_clock::time_point latestTime); | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include <scwx/util/iterator.hpp> | #include <scwx/util/iterator.hpp> | ||||||
| 
 | 
 | ||||||
| #include <string> | #include <string> | ||||||
|  | #include <unordered_map> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
|  | @ -53,6 +54,11 @@ typedef util::Iterator<Level3ProductCategory, | ||||||
|                        Level3ProductCategory::CorrelationCoefficient> |                        Level3ProductCategory::CorrelationCoefficient> | ||||||
|    Level3ProductCategoryIterator; |    Level3ProductCategoryIterator; | ||||||
| 
 | 
 | ||||||
|  | typedef std::unordered_map< | ||||||
|  |    common::Level3ProductCategory, | ||||||
|  |    std::unordered_map<std::string, std::vector<std::string>>> | ||||||
|  |    Level3ProductCategoryMap; | ||||||
|  | 
 | ||||||
| const std::string& GetRadarProductGroupName(RadarProductGroup group); | const std::string& GetRadarProductGroupName(RadarProductGroup group); | ||||||
| RadarProductGroup  GetRadarProductGroup(const std::string& name); | RadarProductGroup  GetRadarProductGroup(const std::string& name); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| #include <scwx/common/products.hpp> | #include <scwx/common/products.hpp> | ||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <unordered_map> |  | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat