mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 03:00: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/pvtec.test.cpp | ||||||
|                     source/scwx/awips/text_product_file.test.cpp) |                     source/scwx/awips/text_product_file.test.cpp) | ||||||
| set(SRC_COMMON_TESTS source/scwx/common/color_table.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_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_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp) | ||||||
| set(SRC_UTIL_TESTS source/scwx/util/float.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: | public: | ||||||
|    static std::shared_ptr<NexradDataProvider> |    static std::shared_ptr<NexradDataProvider> | ||||||
|    CreateLevel2DataProvider(const std::string& radarSite); |    CreateLevel2DataProvider(const std::string& radarSite); | ||||||
|  | 
 | ||||||
|  |    static std::shared_ptr<NexradDataProvider> | ||||||
|  |    CreateLevel3DataProvider(const std::string& radarSite, | ||||||
|  |                             const std::string& product); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace provider
 | } // 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/nexrad_data_provider_factory.hpp> | ||||||
| #include <scwx/provider/aws_level2_data_provider.hpp> | #include <scwx/provider/aws_level2_data_provider.hpp> | ||||||
|  | #include <scwx/provider/aws_level3_data_provider.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -16,5 +17,12 @@ NexradDataProviderFactory::CreateLevel2DataProvider( | ||||||
|    return std::make_unique<AwsLevel2DataProvider>(radarSite); |    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 provider
 | ||||||
| } // namespace scwx
 | } // namespace scwx
 | ||||||
|  |  | ||||||
|  | @ -35,10 +35,12 @@ set(SRC_COMMON source/scwx/common/color_table.cpp | ||||||
|                source/scwx/common/sites.cpp |                source/scwx/common/sites.cpp | ||||||
|                source/scwx/common/vcp.cpp) |                source/scwx/common/vcp.cpp) | ||||||
| set(HDR_PROVIDER include/scwx/provider/aws_level2_data_provider.hpp | 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/aws_nexrad_data_provider.hpp | ||||||
|                  include/scwx/provider/nexrad_data_provider.hpp |                  include/scwx/provider/nexrad_data_provider.hpp | ||||||
|                  include/scwx/provider/nexrad_data_provider_factory.hpp) |                  include/scwx/provider/nexrad_data_provider_factory.hpp) | ||||||
| set(SRC_PROVIDER source/scwx/provider/aws_level2_data_provider.cpp | 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/aws_nexrad_data_provider.cpp | ||||||
|                  source/scwx/provider/nexrad_data_provider.cpp |                  source/scwx/provider/nexrad_data_provider.cpp | ||||||
|                  source/scwx/provider/nexrad_data_provider_factory.cpp) |                  source/scwx/provider/nexrad_data_provider_factory.cpp) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat