mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:50:06 +00:00 
			
		
		
		
	AWS Level 3 Data Provider
This commit is contained in:
		
							parent
							
								
									c5c54fbfa2
								
							
						
					
					
						commit
						70b8f78eb5
					
				
					 7 changed files with 259 additions and 1 deletions
				
			
		
							
								
								
									
										91
									
								
								test/source/scwx/provider/aws_level3_data_provider.test.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								test/source/scwx/provider/aws_level3_data_provider.test.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,91 @@ | |||
| #include <scwx/provider/aws_level3_data_provider.hpp> | ||||
| 
 | ||||
| #include <gtest/gtest.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace provider | ||||
| { | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, FindKeyFixed) | ||||
| { | ||||
|    using namespace std::chrono; | ||||
|    using sys_days = time_point<system_clock, days>; | ||||
| 
 | ||||
|    const auto date = sys_days {2021y / May / 27d}; | ||||
|    const auto time = date + 17h + 59min; | ||||
| 
 | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0Q"); | ||||
| 
 | ||||
|    provider.ListObjects(date); | ||||
|    std::string key = provider.FindKey(time); | ||||
| 
 | ||||
|    EXPECT_EQ(key, "LSX_N0Q_2021_05_27_17_57_17"); | ||||
| } | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, FindKeyNow) | ||||
| { | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0B"); | ||||
| 
 | ||||
|    provider.Refresh(); | ||||
|    std::string key = provider.FindKey(std::chrono::system_clock::now()); | ||||
| 
 | ||||
|    EXPECT_GT(key.size(), 0); | ||||
| } | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, LoadObjectByKey) | ||||
| { | ||||
|    const std::string key = "LSX_N0Q_2021_05_27_17_57_17"; | ||||
| 
 | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0Q"); | ||||
| 
 | ||||
|    auto file = provider.LoadObjectByKey(key); | ||||
| 
 | ||||
|    EXPECT_NE(file, nullptr); | ||||
| } | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, Refresh) | ||||
| { | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0B"); | ||||
| 
 | ||||
|    size_t newObjects = provider.Refresh(); | ||||
| 
 | ||||
|    EXPECT_GT(newObjects, 0); | ||||
|    EXPECT_GT(provider.cache_size(), 0); | ||||
| } | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, TimePointValid) | ||||
| { | ||||
|    using namespace std::chrono; | ||||
|    using sys_days = time_point<system_clock, days>; | ||||
| 
 | ||||
|    constexpr auto expectedTime = | ||||
|       sys_days {2022y / April / 30d} + 17h + 27min + 34s; | ||||
| 
 | ||||
|    auto time = | ||||
|       AwsLevel3DataProvider::GetTimePointFromKey("LSX_N0Q_2022_04_30_17_27_34"); | ||||
| 
 | ||||
|    EXPECT_EQ(time, expectedTime); | ||||
| } | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, TimePointInvalid) | ||||
| { | ||||
|    constexpr std::chrono::system_clock::time_point expectedTime {}; | ||||
| 
 | ||||
|    auto time = AwsLevel3DataProvider::GetTimePointFromKey( | ||||
|       "LSX_N0Q_2022-04-30_17-27-34"); | ||||
| 
 | ||||
|    EXPECT_EQ(time, expectedTime); | ||||
| } | ||||
| 
 | ||||
| TEST(AwsLevel3DataProvider, TimePointBadKey) | ||||
| { | ||||
|    constexpr std::chrono::system_clock::time_point expectedTime {}; | ||||
| 
 | ||||
|    auto time = AwsLevel3DataProvider::GetTimePointFromKey("???"); | ||||
| 
 | ||||
|    EXPECT_EQ(time, expectedTime); | ||||
| } | ||||
| 
 | ||||
| } // namespace provider
 | ||||
| } // namespace scwx
 | ||||
|  | @ -13,7 +13,8 @@ set(SRC_AWIPS_TESTS source/scwx/awips/coded_location.test.cpp | |||
|                     source/scwx/awips/pvtec.test.cpp | ||||
|                     source/scwx/awips/text_product_file.test.cpp) | ||||
| set(SRC_COMMON_TESTS source/scwx/common/color_table.test.cpp) | ||||
| set(SRC_PROVIDER_TESTS source/scwx/provider/aws_level2_data_provider.test.cpp) | ||||
| set(SRC_PROVIDER_TESTS source/scwx/provider/aws_level2_data_provider.test.cpp | ||||
|                        source/scwx/provider/aws_level3_data_provider.test.cpp) | ||||
| set(SRC_QT_CONFIG_TESTS source/scwx/qt/config/radar_site.test.cpp) | ||||
| set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp) | ||||
| set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp | ||||
|  |  | |||
							
								
								
									
										45
									
								
								wxdata/include/scwx/provider/aws_level3_data_provider.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								wxdata/include/scwx/provider/aws_level3_data_provider.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/provider/aws_nexrad_data_provider.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace provider | ||||
| { | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief AWS Level 3 Data Provider | ||||
|  */ | ||||
| class AwsLevel3DataProvider : public AwsNexradDataProvider | ||||
| { | ||||
| public: | ||||
|    explicit AwsLevel3DataProvider(const std::string& radarSite, | ||||
|                                   const std::string& product); | ||||
|    explicit AwsLevel3DataProvider(const std::string& radarSite, | ||||
|                                   const std::string& product, | ||||
|                                   const std::string& bucketName, | ||||
|                                   const std::string& region); | ||||
|    ~AwsLevel3DataProvider(); | ||||
| 
 | ||||
|    AwsLevel3DataProvider(const AwsLevel3DataProvider&) = delete; | ||||
|    AwsLevel3DataProvider& operator=(const AwsLevel3DataProvider&) = delete; | ||||
| 
 | ||||
|    AwsLevel3DataProvider(AwsLevel3DataProvider&&) noexcept; | ||||
|    AwsLevel3DataProvider& operator=(AwsLevel3DataProvider&&) noexcept; | ||||
| 
 | ||||
|    std::chrono::system_clock::time_point | ||||
|    GetTimePointByKey(const std::string& key) const; | ||||
| 
 | ||||
|    static std::chrono::system_clock::time_point | ||||
|    GetTimePointFromKey(const std::string& key); | ||||
| 
 | ||||
| protected: | ||||
|    std::string GetPrefix(std::chrono::system_clock::time_point date); | ||||
| 
 | ||||
| private: | ||||
|    class Impl; | ||||
|    std::unique_ptr<Impl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace provider
 | ||||
| } // namespace scwx
 | ||||
|  | @ -26,6 +26,10 @@ private: | |||
| public: | ||||
|    static std::shared_ptr<NexradDataProvider> | ||||
|    CreateLevel2DataProvider(const std::string& radarSite); | ||||
| 
 | ||||
|    static std::shared_ptr<NexradDataProvider> | ||||
|    CreateLevel3DataProvider(const std::string& radarSite, | ||||
|                             const std::string& product); | ||||
| }; | ||||
| 
 | ||||
| } // namespace provider
 | ||||
|  |  | |||
							
								
								
									
										107
									
								
								wxdata/source/scwx/provider/aws_level3_data_provider.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								wxdata/source/scwx/provider/aws_level3_data_provider.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,107 @@ | |||
| #include <scwx/provider/aws_level3_data_provider.hpp> | ||||
| #include <scwx/common/sites.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| #include <scwx/util/time.hpp> | ||||
| 
 | ||||
| #include <fmt/chrono.h> | ||||
| #include <fmt/format.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace provider | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = | ||||
|    "scwx::provider::aws_level3_data_provider"; | ||||
| static const auto logger_ = util::Logger::Create(logPrefix_); | ||||
| 
 | ||||
| static const std::string kDefaultBucketName_ = "unidata-nexrad-level3"; | ||||
| static const std::string kDefaultRegion_     = "us-east-1"; | ||||
| 
 | ||||
| class AwsLevel3DataProvider::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl(const std::string& radarSite, const std::string& product) : | ||||
|        radarSite_ {radarSite}, | ||||
|        siteId_ {common::GetSiteId(radarSite_)}, | ||||
|        product_ {product} | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    std::string radarSite_; | ||||
|    std::string siteId_; | ||||
|    std::string product_; | ||||
| }; | ||||
| 
 | ||||
| AwsLevel3DataProvider::AwsLevel3DataProvider(const std::string& radarSite, | ||||
|                                              const std::string& product) : | ||||
|     AwsLevel3DataProvider( | ||||
|        radarSite, product, kDefaultBucketName_, kDefaultRegion_) | ||||
| { | ||||
| } | ||||
| AwsLevel3DataProvider::AwsLevel3DataProvider(const std::string& radarSite, | ||||
|                                              const std::string& product, | ||||
|                                              const std::string& bucketName, | ||||
|                                              const std::string& region) : | ||||
|     AwsNexradDataProvider(radarSite, bucketName, region), | ||||
|     p(std::make_unique<Impl>(radarSite, product)) | ||||
| { | ||||
| } | ||||
| AwsLevel3DataProvider::~AwsLevel3DataProvider() = default; | ||||
| 
 | ||||
| AwsLevel3DataProvider::AwsLevel3DataProvider(AwsLevel3DataProvider&&) noexcept = | ||||
|    default; | ||||
| AwsLevel3DataProvider& | ||||
| AwsLevel3DataProvider::operator=(AwsLevel3DataProvider&&) noexcept = default; | ||||
| 
 | ||||
| std::string | ||||
| AwsLevel3DataProvider::GetPrefix(std::chrono::system_clock::time_point date) | ||||
| { | ||||
|    return fmt::format( | ||||
|       "{0}_{1}_{2:%Y_%m_%d}_", p->siteId_, p->product_, fmt::gmtime(date)); | ||||
| } | ||||
| 
 | ||||
| std::chrono::system_clock::time_point | ||||
| AwsLevel3DataProvider::GetTimePointByKey(const std::string& key) const | ||||
| { | ||||
|    return GetTimePointFromKey(key); | ||||
| } | ||||
| 
 | ||||
| std::chrono::system_clock::time_point | ||||
| AwsLevel3DataProvider::GetTimePointFromKey(const std::string& key) | ||||
| { | ||||
|    std::chrono::system_clock::time_point time {}; | ||||
| 
 | ||||
|    constexpr size_t offset = 8; | ||||
| 
 | ||||
|    // Filename format is GGG_PPP_YYYY_MM_DD_HH_MM_SS
 | ||||
|    static constexpr size_t formatSize = | ||||
|       std::string("YYYY_MM_DD_HH_MM_SS").size(); | ||||
| 
 | ||||
|    if (key.size() >= offset + formatSize) | ||||
|    { | ||||
|       using namespace std::chrono; | ||||
| 
 | ||||
|       static const std::string timeFormat {"%Y_%m_%d_%H_%M_%S"}; | ||||
| 
 | ||||
|       std::string        timeStr {key.substr(offset, formatSize)}; | ||||
|       std::istringstream in {timeStr}; | ||||
|       in >> parse(timeFormat, time); | ||||
| 
 | ||||
|       if (in.fail()) | ||||
|       { | ||||
|          logger_->warn("Invalid time: \"{}\"", timeStr); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       logger_->warn("Time not parsable from key: \"{}\"", key); | ||||
|    } | ||||
| 
 | ||||
|    return time; | ||||
| } | ||||
| 
 | ||||
| } // namespace provider
 | ||||
| } // namespace scwx
 | ||||
|  | @ -1,5 +1,6 @@ | |||
| #include <scwx/provider/nexrad_data_provider_factory.hpp> | ||||
| #include <scwx/provider/aws_level2_data_provider.hpp> | ||||
| #include <scwx/provider/aws_level3_data_provider.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -16,5 +17,12 @@ NexradDataProviderFactory::CreateLevel2DataProvider( | |||
|    return std::make_unique<AwsLevel2DataProvider>(radarSite); | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<NexradDataProvider> | ||||
| NexradDataProviderFactory::CreateLevel3DataProvider( | ||||
|    const std::string& radarSite, const std::string& product) | ||||
| { | ||||
|    return std::make_unique<AwsLevel3DataProvider>(radarSite, product); | ||||
| } | ||||
| 
 | ||||
| } // namespace provider
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -35,10 +35,12 @@ set(SRC_COMMON source/scwx/common/color_table.cpp | |||
|                source/scwx/common/sites.cpp | ||||
|                source/scwx/common/vcp.cpp) | ||||
| set(HDR_PROVIDER include/scwx/provider/aws_level2_data_provider.hpp | ||||
|                  include/scwx/provider/aws_level3_data_provider.hpp | ||||
|                  include/scwx/provider/aws_nexrad_data_provider.hpp | ||||
|                  include/scwx/provider/nexrad_data_provider.hpp | ||||
|                  include/scwx/provider/nexrad_data_provider_factory.hpp) | ||||
| set(SRC_PROVIDER source/scwx/provider/aws_level2_data_provider.cpp | ||||
|                  source/scwx/provider/aws_level3_data_provider.cpp | ||||
|                  source/scwx/provider/aws_nexrad_data_provider.cpp | ||||
|                  source/scwx/provider/nexrad_data_provider.cpp | ||||
|                  source/scwx/provider/nexrad_data_provider_factory.cpp) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat