diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6f5ed2a..e3033807 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,7 +127,7 @@ jobs: env: CC: ${{ matrix.env_cc }} CXX: ${{ matrix.env_cxx }} - SCWX_VERSION: v0.5.2 + SCWX_VERSION: v0.5.1 runs-on: ${{ matrix.os }} steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b33b070..e76cb8d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0) scwx_python_setup() project(${PROJECT_NAME} - VERSION 0.5.2 + VERSION 0.5.1 DESCRIPTION "Supercell Wx is a free, open source advanced weather radar viewer." HOMEPAGE_URL "https://github.com/dpaulat/supercell-wx" LANGUAGES C CXX) @@ -32,7 +32,7 @@ set_property(DIRECTORY set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_ALL_NO_LIB") set(SCWX_DIR ${PROJECT_SOURCE_DIR}) -set(SCWX_VERSION "0.5.2") +set(SCWX_VERSION "0.5.1") option(SCWX_ADDRESS_SANITIZER "Build with Address Sanitizer" OFF) diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 1a093200..ecd26ef9 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -234,7 +234,6 @@ set(HDR_TYPES source/scwx/qt/types/alert_types.hpp source/scwx/qt/types/media_types.hpp source/scwx/qt/types/qt_types.hpp source/scwx/qt/types/radar_product_record.hpp - source/scwx/qt/types/radar_product_types.hpp source/scwx/qt/types/text_event_key.hpp source/scwx/qt/types/text_types.hpp source/scwx/qt/types/texture_types.hpp diff --git a/scwx-qt/source/scwx/qt/main/main.cpp b/scwx-qt/source/scwx/qt/main/main.cpp index 68e7bbbc..a2416cec 100644 --- a/scwx-qt/source/scwx/qt/main/main.cpp +++ b/scwx-qt/source/scwx/qt/main/main.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -72,8 +71,6 @@ int main(int argc, char* argv[]) scwx::qt::main::kVersionString_, scwx::qt::main::kBuildNumber_, scwx::qt::main::kCommitString_); - logger_->info("Qt version {}", - QLibraryInfo::version().toString().toStdString()); InitializeOpenGL(); diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index 331f25e1..4fa2f28a 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -463,28 +463,18 @@ void MainWindow::keyReleaseEvent(QKeyEvent* ev) void MainWindow::showEvent(QShowEvent* event) { QMainWindow::showEvent(event); + auto& uiSettings = settings::UiSettings::Instance(); - static bool firstShowEvent = true; - bool restored = false; + // restore the geometry state + std::string uiGeometry = uiSettings.main_ui_geometry().GetValue(); + restoreGeometry( + QByteArray::fromBase64(QByteArray::fromStdString(uiGeometry))); - if (firstShowEvent) - { - auto& uiSettings = settings::UiSettings::Instance(); - - // restore the geometry state - const std::string uiGeometry = uiSettings.main_ui_geometry().GetValue(); - restoreGeometry( - QByteArray::fromBase64(QByteArray::fromStdString(uiGeometry))); - - // restore the UI state - const std::string uiState = uiSettings.main_ui_state().GetValue(); - - restored = restoreState( - QByteArray::fromBase64(QByteArray::fromStdString(uiState))); - - firstShowEvent = false; - } + // restore the UI state + std::string uiState = uiSettings.main_ui_state().GetValue(); + bool restored = + restoreState(QByteArray::fromBase64(QByteArray::fromStdString(uiState))); if (!restored) { resizeDocks({ui->radarToolboxDock}, {194}, Qt::Horizontal); diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp index 048e2542..bda6e232 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -37,7 +36,11 @@ # pragma warning(pop) #endif -namespace scwx::qt::manager +namespace scwx +{ +namespace qt +{ +namespace manager { static const std::string logPrefix_ = @@ -106,27 +109,21 @@ public: group, product, isChunks_, latestTime); }); } - ~ProviderManager() override - { - providerThreadPool_.stop(); - providerThreadPool_.join(); - }; + ~ProviderManager() { threadPool_.join(); }; std::string name() const; void Disable(); - void RefreshData(); - void RefreshDataSync(); - boost::asio::thread_pool providerThreadPool_ {2u}; + boost::asio::thread_pool threadPool_ {1u}; - const std::string radarId_; - const common::RadarProductGroup group_; - const std::string product_; - const bool isChunks_; - bool refreshEnabled_ {false}; - boost::asio::steady_timer refreshTimer_ {providerThreadPool_}; - std::mutex refreshTimerMutex_ {}; + const std::string radarId_; + const common::RadarProductGroup group_; + const std::string product_; + const bool isChunks_; + bool refreshEnabled_ {false}; + boost::asio::steady_timer refreshTimer_ {threadPool_}; + std::mutex refreshTimerMutex_ {}; std::shared_ptr provider_ {nullptr}; size_t refreshCount_ {0}; @@ -187,9 +184,11 @@ public: auto& [key, providerManager] = p; providerManager->Disable(); }); - lock.unlock(); - threadPool_.stop(); + // Lock other mutexes before destroying, ensure loading is complete + std::unique_lock loadLevel2DataLock {loadLevel2DataMutex_}; + std::unique_lock loadLevel3DataLock {loadLevel3DataMutex_}; + threadPool_.join(); } @@ -204,14 +203,14 @@ public: boost::uuids::uuid uuid, const std::set>& providerManagers, bool enabled); + void RefreshData(std::shared_ptr providerManager); + void RefreshDataSync(std::shared_ptr providerManager); - std::tuple>, - types::RadarProductLoadStatus> + std::map> GetLevel2ProductRecords(std::chrono::system_clock::time_point time); std::tuple, - std::chrono::system_clock::time_point, - types::RadarProductLoadStatus> + std::chrono::system_clock::time_point> GetLevel3ProductRecord(const std::string& product, std::chrono::system_clock::time_point time); std::shared_ptr @@ -225,24 +224,15 @@ public: std::mutex& mutex, std::chrono::system_clock::time_point time); void - LoadProviderData(std::chrono::system_clock::time_point time, - std::shared_ptr providerManager, - RadarProductRecordMap& recordMap, - std::shared_mutex& recordMutex, - std::mutex& loadDataMutex, - const std::shared_ptr& request); - - bool AreLevel2ProductTimesPopulated( - std::chrono::system_clock::time_point time) const; - bool - AreLevel3ProductTimesPopulated(const std::string& product, - std::chrono::system_clock::time_point time); - - void PopulateLevel2ProductTimes(std::chrono::system_clock::time_point time, - bool update = true); + LoadProviderData(std::chrono::system_clock::time_point time, + std::shared_ptr providerManager, + RadarProductRecordMap& recordMap, + std::shared_mutex& recordMutex, + std::mutex& loadDataMutex, + const std::shared_ptr& request); + void PopulateLevel2ProductTimes(std::chrono::system_clock::time_point time); void PopulateLevel3ProductTimes(const std::string& product, - std::chrono::system_clock::time_point time, - bool update = true); + std::chrono::system_clock::time_point time); void UpdateAvailableProductsSync(); @@ -253,16 +243,11 @@ public: const float gateRangeOffset, std::vector& outputCoordinates); - static bool AreProductTimesPopulated( - const std::shared_ptr& providerManager, - std::chrono::system_clock::time_point time); - static void PopulateProductTimes(std::shared_ptr providerManager, RadarProductRecordMap& productRecordMap, std::shared_mutex& productRecordMutex, - std::chrono::system_clock::time_point time, - bool update); + std::chrono::system_clock::time_point time); static void LoadNexradFile(CreateNexradFileFunction load, @@ -786,27 +771,28 @@ void RadarProductManagerImpl::EnableRefresh( if (providerManager->refreshEnabled_ != enabled) { providerManager->refreshEnabled_ = enabled; - providerManager->RefreshData(); + RefreshData(providerManager); } } } } -void ProviderManager::RefreshData() +void RadarProductManagerImpl::RefreshData( + std::shared_ptr providerManager) { - logger_->trace("RefreshData: {}", name()); + logger_->trace("RefreshData: {}", providerManager->name()); { - const std::unique_lock lock(refreshTimerMutex_); - refreshTimer_.cancel(); + std::unique_lock lock(providerManager->refreshTimerMutex_); + providerManager->refreshTimer_.cancel(); } - boost::asio::post(providerThreadPool_, - [this]() + boost::asio::post(threadPool_, + [=, this]() { try { - RefreshDataSync(); + RefreshDataSync(providerManager); } catch (const std::exception& ex) { @@ -815,24 +801,27 @@ void ProviderManager::RefreshData() }); } -void ProviderManager::RefreshDataSync() +void RadarProductManagerImpl::RefreshDataSync( + std::shared_ptr providerManager) { using namespace std::chrono_literals; - auto [newObjects, totalObjects] = provider_->Refresh(); + auto [newObjects, totalObjects] = providerManager->provider_->Refresh(); // Level2 chunked data is updated quickly and uses a faster interval const std::chrono::milliseconds fastRetryInterval = - isChunks_ ? kFastRetryIntervalChunks_ : kFastRetryInterval_; + providerManager->isChunks_ ? kFastRetryIntervalChunks_ : + kFastRetryInterval_; const std::chrono::milliseconds slowRetryInterval = - isChunks_ ? kSlowRetryIntervalChunks_ : kSlowRetryInterval_; + providerManager->isChunks_ ? kSlowRetryIntervalChunks_ : + kSlowRetryInterval_; std::chrono::milliseconds interval = fastRetryInterval; if (totalObjects > 0) { - auto latestTime = provider_->FindLatestTime(); - auto updatePeriod = provider_->update_period(); - auto lastModified = provider_->last_modified(); + auto latestTime = providerManager->provider_->FindLatestTime(); + auto updatePeriod = providerManager->provider_->update_period(); + auto lastModified = providerManager->provider_->last_modified(); auto sinceLastModified = scwx::util::time::now() - lastModified; // For the default interval, assume products are updated at a @@ -841,11 +830,7 @@ void ProviderManager::RefreshDataSync() interval = std::chrono::duration_cast( updatePeriod - sinceLastModified); - // Allow 5 update periods before considering the data stale - constexpr std::size_t kUpdatePeriodStaleCount = 5; - - if (updatePeriod > 0s && - sinceLastModified > updatePeriod * kUpdatePeriodStaleCount) + if (updatePeriod > 0s && sinceLastModified > updatePeriod * 5) { // If it has been at least 5 update periods since the file has // been last modified, slow the retry period @@ -859,43 +844,46 @@ void ProviderManager::RefreshDataSync() if (newObjects > 0) { - Q_EMIT NewDataAvailable(group_, product_, latestTime); + Q_EMIT providerManager->NewDataAvailable( + providerManager->group_, providerManager->product_, latestTime); } } - else if (refreshEnabled_) + else if (providerManager->refreshEnabled_) { - logger_->info("[{}] No data found", name()); + logger_->info("[{}] No data found", providerManager->name()); // If no data is found, retry at the slow retry interval interval = slowRetryInterval; } - std::unique_lock const lock(refreshTimerMutex_); + std::unique_lock const lock(providerManager->refreshTimerMutex_); - if (refreshEnabled_) + if (providerManager->refreshEnabled_) { logger_->trace( "[{}] Scheduled refresh in {:%M:%S}", - name(), + providerManager->name(), std::chrono::duration_cast(interval)); { - refreshTimer_.expires_after(interval); - refreshTimer_.async_wait( - [this](const boost::system::error_code& e) + providerManager->refreshTimer_.expires_after(interval); + providerManager->refreshTimer_.async_wait( + [=, this](const boost::system::error_code& e) { if (e == boost::system::errc::success) { - RefreshData(); + RefreshData(providerManager); } else if (e == boost::asio::error::operation_aborted) { - logger_->debug("[{}] Data refresh timer cancelled", name()); + logger_->debug("[{}] Data refresh timer cancelled", + providerManager->name()); } else { - logger_->warn( - "[{}] Data refresh timer error: {}", name(), e.message()); + logger_->warn("[{}] Data refresh timer error: {}", + providerManager->name(), + e.message()); } }); } @@ -946,32 +934,32 @@ RadarProductManager::GetActiveVolumeTimes( [&](const std::shared_ptr& provider) { // For yesterday, today and tomorrow (in parallel) - std::for_each( - std::execution::par, - dates.begin(), - dates.end(), - [&](const auto& date) - { - // Don't query for a time point in the future - if (date > scwx::util::time::now()) - { - return; - } + std::for_each(std::execution::par, + dates.begin(), + dates.end(), + [&](const auto& date) + { + // Don't query for a time point in the future + if (date > scwx::util::time::now()) + { + return; + } - // Query the provider for volume time points - auto timePoints = provider->GetTimePointsByDate(date, true); + // Query the provider for volume time points + auto timePoints = provider->GetTimePointsByDate(date); - // TODO: Note, this will miss volume times present in Level 2 - // products with a second scan + // TODO: Note, this will miss volume times present in + // Level 2 products with a second scan - // Lock the merged volume time list - const std::unique_lock volumeTimesLock {volumeTimesMutex}; + // Lock the merged volume time list + std::unique_lock volumeTimesLock {volumeTimesMutex}; - // Copy time points to the merged list - std::copy(timePoints.begin(), - timePoints.end(), - std::inserter(volumeTimes, volumeTimes.end())); - }); + // Copy time points to the merged list + std::copy( + timePoints.begin(), + timePoints.end(), + std::inserter(volumeTimes, volumeTimes.end())); + }); }); // Return merged volume times list @@ -1214,75 +1202,21 @@ void RadarProductManagerImpl::LoadNexradFile( } } -bool RadarProductManagerImpl::AreLevel2ProductTimesPopulated( - std::chrono::system_clock::time_point time) const -{ - return AreProductTimesPopulated(level2ProviderManager_, time); -} - -bool RadarProductManagerImpl::AreLevel3ProductTimesPopulated( - const std::string& product, std::chrono::system_clock::time_point time) -{ - // Get provider manager - const auto level3ProviderManager = GetLevel3ProviderManager(product); - - return AreProductTimesPopulated(level3ProviderManager, time); -} - -bool RadarProductManagerImpl::AreProductTimesPopulated( - const std::shared_ptr& providerManager, - std::chrono::system_clock::time_point time) -{ - auto today = std::chrono::floor(time); - - bool productTimesPopulated = true; - - // Assume a query for the epoch is a query for now - if (today == std::chrono::system_clock::time_point {}) - { - today = std::chrono::floor(scwx::util::time::now()); - } - - const auto yesterday = today - std::chrono::days {1}; - const auto tomorrow = today + std::chrono::days {1}; - const auto dates = {yesterday, today, tomorrow}; - - for (auto& date : dates) - { - // Don't query for a time point in the future - if (date > scwx::util::time::now()) - { - continue; - } - - if (!providerManager->provider_->IsDateCached(date)) - { - productTimesPopulated = false; - } - } - - return productTimesPopulated; -} - void RadarProductManagerImpl::PopulateLevel2ProductTimes( - std::chrono::system_clock::time_point time, bool update) + std::chrono::system_clock::time_point time) { PopulateProductTimes(level2ProviderManager_, level2ProductRecords_, level2ProductRecordMutex_, - time, - update); + time); PopulateProductTimes(level2ChunksProviderManager_, level2ProductRecords_, level2ProductRecordMutex_, - time, - update); + time); } void RadarProductManagerImpl::PopulateLevel3ProductTimes( - const std::string& product, - std::chrono::system_clock::time_point time, - bool update) + const std::string& product, std::chrono::system_clock::time_point time) { // Get provider manager auto level3ProviderManager = GetLevel3ProviderManager(product); @@ -1295,38 +1229,21 @@ void RadarProductManagerImpl::PopulateLevel3ProductTimes( PopulateProductTimes(level3ProviderManager, level3ProductRecords, level3ProductRecordMutex_, - time, - update); + time); } void RadarProductManagerImpl::PopulateProductTimes( std::shared_ptr providerManager, RadarProductRecordMap& productRecordMap, std::shared_mutex& productRecordMutex, - std::chrono::system_clock::time_point time, - bool update) + std::chrono::system_clock::time_point time) { - if (update) - { - logger_->debug("Populating product times: {}, {}, {}", - common::GetRadarProductGroupName(providerManager->group_), - providerManager->product_, - scwx::util::time::TimeString(time)); - } - else - { - logger_->trace("Populating cached product times: {}, {}, {}", - common::GetRadarProductGroupName(providerManager->group_), - providerManager->product_, - scwx::util::time::TimeString(time)); - } + const auto today = std::chrono::floor(time); - auto today = std::chrono::floor(time); - - // Assume a query for the epoch is a query for now + // Don't query for the epoch if (today == std::chrono::system_clock::time_point {}) { - today = std::chrono::floor(scwx::util::time::now()); + return; } const auto yesterday = today - std::chrono::days {1}; @@ -1350,8 +1267,7 @@ void RadarProductManagerImpl::PopulateProductTimes( // Query the provider for volume time points auto timePoints = - providerManager->provider_->GetTimePointsByDate(date, - update); + providerManager->provider_->GetTimePointsByDate(date); // Lock the merged volume time list std::unique_lock volumeTimesLock {volumeTimesMutex}; @@ -1377,9 +1293,8 @@ void RadarProductManagerImpl::PopulateProductTimes( }); } -std::tuple>, - types::RadarProductLoadStatus> +std::map> RadarProductManagerImpl::GetLevel2ProductRecords( std::chrono::system_clock::time_point time) { @@ -1387,40 +1302,9 @@ RadarProductManagerImpl::GetLevel2ProductRecords( std::shared_ptr> records {}; std::vector recordPtrs {}; - types::RadarProductLoadStatus status { - types::RadarProductLoadStatus::ListingProducts}; - - std::size_t recordPtrCount = 0u; - std::size_t recordCount = 0u; // Ensure Level 2 product records are updated - if (!AreLevel2ProductTimesPopulated(time)) - { - logger_->debug("Level 2 product times need populated: {}", - scwx::util::time::TimeString(time)); - - // Populate level 2 product times asynchronously - boost::asio::post(threadPool_, - [time, this]() - { - // Populate product times - PopulateLevel2ProductTimes(time); - - // Signal finished - Q_EMIT self_->ProductTimesPopulated( - common::RadarProductGroup::Level2, "", time); - }); - - // Return listing products status - return {records, status}; - } - else - { - PopulateLevel2ProductTimes(time, false); - } - - // Advance to loading product - status = types::RadarProductLoadStatus::LoadingProduct; + PopulateLevel2ProductTimes(time); { std::shared_lock lock {level2ProductRecordMutex_}; @@ -1459,29 +1343,9 @@ RadarProductManagerImpl::GetLevel2ProductRecords( if (recordPtr != nullptr) { - using namespace std::chrono_literals; - // Don't check for an exact time match for level 2 products recordTime = recordPtr->first; - - if ( - // For latest data, ensure it is from the last 24 hours - (time == std::chrono::system_clock::time_point {} && - (recordTime > scwx::util::time::now() - 24h || - recordTime == time)) || - // For time queries, ensure data is within 24 hours of the request - (time != std::chrono::system_clock::time_point {} && - std::chrono::abs(recordTime - time) < 24h)) - { - record = recordPtr->second.lock(); - ++recordPtrCount; - } - else - { - // Reset the record - recordPtr = nullptr; - recordTime = time; - } + record = recordPtr->second.lock(); } if (recordPtr != nullptr && record == nullptr && @@ -1504,73 +1368,29 @@ RadarProductManagerImpl::GetLevel2ProductRecords( }); self_->LoadLevel2Data(recordTime, request); - - // Status is already set to LoadingProduct } if (record != nullptr) { // Return valid records records.insert_or_assign(recordTime, record); - ++recordCount; } } - if (recordPtrCount == 0) - { - // If all records are empty, the product is not available - status = types::RadarProductLoadStatus::ProductNotAvailable; - } - else if (recordCount == recordPtrCount) - { - // If all records were populated, the product has been loaded - status = types::RadarProductLoadStatus::ProductLoaded; - } - - return {records, status}; + return records; } std::tuple, - std::chrono::system_clock::time_point, - types::RadarProductLoadStatus> + std::chrono::system_clock::time_point> RadarProductManagerImpl::GetLevel3ProductRecord( const std::string& product, std::chrono::system_clock::time_point time) { std::shared_ptr record {nullptr}; RadarProductRecordMap::const_pointer recordPtr {nullptr}; std::chrono::system_clock::time_point recordTime {time}; - types::RadarProductLoadStatus status { - types::RadarProductLoadStatus::ListingProducts}; // Ensure Level 3 product records are updated - if (!AreLevel3ProductTimesPopulated(product, time)) - { - logger_->debug("Level 3 product times need populated: {}, {}", - product, - scwx::util::time::TimeString(time)); - - // Populate level 3 product times asynchronously - boost::asio::post(threadPool_, - [product, time, this]() - { - // Populate product times - PopulateLevel3ProductTimes(product, time); - - // Signal finished - Q_EMIT self_->ProductTimesPopulated( - common::RadarProductGroup::Level3, product, time); - }); - - // Return listing products status - return {record, recordTime, status}; - } - else - { - PopulateLevel3ProductTimes(product, time, false); - } - - // Advance to loading product - status = types::RadarProductLoadStatus::LoadingProduct; + PopulateLevel3ProductTimes(product, time); std::unique_lock lock {level3ProductRecordMutex_}; @@ -1595,27 +1415,9 @@ RadarProductManagerImpl::GetLevel3ProductRecord( if (recordPtr != nullptr) { - using namespace std::chrono_literals; - // Don't check for an exact time match for level 3 products recordTime = recordPtr->first; - - if ( - // For latest data, ensure it is from the last 24 hours - (time == std::chrono::system_clock::time_point {} && - (recordTime > scwx::util::time::now() - 24h || recordTime == time)) || - // For time queries, ensure data is within 24 hours of the request - (time != std::chrono::system_clock::time_point {} && - std::chrono::abs(recordTime - time) < 24h)) - { - record = recordPtr->second.lock(); - } - else - { - // Reset the record - recordPtr = nullptr; - recordTime = time; - } + record = recordPtr->second.lock(); } if (recordPtr != nullptr && record == nullptr && @@ -1638,22 +1440,9 @@ RadarProductManagerImpl::GetLevel3ProductRecord( }); self_->LoadLevel3Data(product, recordTime, request); - - // Status is already set to LoadingProduct } - if (recordPtr == nullptr) - { - // If the record is empty, the product is not available - status = types::RadarProductLoadStatus::ProductNotAvailable; - } - else if (record != nullptr) - { - // If the record was populated, the product has been loaded - status = types::RadarProductLoadStatus::ProductLoaded; - } - - return {record, recordTime, status}; + return {record, recordTime}; } std::shared_ptr @@ -1754,8 +1543,7 @@ void RadarProductManagerImpl::UpdateRecentRecords( std::tuple, float, std::vector, - std::chrono::system_clock::time_point, - types::RadarProductLoadStatus> + std::chrono::system_clock::time_point> RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, float elevation, std::chrono::system_clock::time_point time) @@ -1764,8 +1552,6 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, float elevationCut = 0.0f; std::vector elevationCuts {}; std::chrono::system_clock::time_point foundTime {}; - types::RadarProductLoadStatus loadStatus { - types::RadarProductLoadStatus::ProductNotLoaded}; const bool isEpox = time == std::chrono::system_clock::time_point {}; bool needArchive = true; @@ -1801,7 +1587,6 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, if (foundTime >= firstValidChunkTime) { needArchive = false; - loadStatus = types::RadarProductLoadStatus::ProductLoaded; } } } @@ -1809,11 +1594,7 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, // It is not in the chunk provider, so get it from the archive if (needArchive) { - std::map> - records; - - std::tie(records, loadStatus) = p->GetLevel2ProductRecords(time); + auto records = p->GetLevel2ProductRecords(time); for (auto& recordPair : records) { auto& record = recordPair.second; @@ -1858,35 +1639,25 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, } } - if (loadStatus == types::RadarProductLoadStatus::ProductLoaded && - radarData == nullptr) - { - // If all data was available for the time point, but there is no matching - // radar data, consider this as no product available - loadStatus = types::RadarProductLoadStatus::ProductNotAvailable; - } - - return {radarData, elevationCut, elevationCuts, foundTime, loadStatus}; + return {radarData, elevationCut, elevationCuts, foundTime}; } std::tuple, - std::chrono::system_clock::time_point, - types::RadarProductLoadStatus> + std::chrono::system_clock::time_point> RadarProductManager::GetLevel3Data(const std::string& product, std::chrono::system_clock::time_point time) { std::shared_ptr message = nullptr; - types::RadarProductLoadStatus status {}; std::shared_ptr record; - std::tie(record, time, status) = p->GetLevel3ProductRecord(product, time); + std::tie(record, time) = p->GetLevel3ProductRecord(product, time); if (record != nullptr) { message = record->level3_file()->message(); } - return {message, time, status}; + return {message, time}; } common::Level3ProductCategoryMap @@ -2038,4 +1809,6 @@ RadarProductManager::Instance(const std::string& radarSite) #include "radar_product_manager.moc" -} // namespace scwx::qt::manager +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp index 87bd0484..e8c72193 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp @@ -5,19 +5,23 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include -namespace scwx::qt::manager +namespace scwx +{ +namespace qt +{ +namespace manager { class RadarProductManagerImpl; @@ -85,13 +89,12 @@ public: * @param [in] time Radar product time * * @return Level 2 radar data, selected elevation cut, available elevation - * cuts, selected time and product load status + * cuts and selected time */ std::tuple, float, std::vector, - std::chrono::system_clock::time_point, - types::RadarProductLoadStatus> + std::chrono::system_clock::time_point> GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, float elevation, std::chrono::system_clock::time_point time = {}); @@ -102,11 +105,10 @@ public: * @param [in] product Radar product name * @param [in] time Radar product time * - * @return Level 3 message data, selected time and product load status + * @return Level 3 message data and selected time */ std::tuple, - std::chrono::system_clock::time_point, - types::RadarProductLoadStatus> + std::chrono::system_clock::time_point> GetLevel3Data(const std::string& product, std::chrono::system_clock::time_point time = {}); @@ -149,9 +151,6 @@ signals: bool isChunks, std::chrono::system_clock::time_point latestTime); void IncomingLevel2ElevationChanged(std::optional incomingElevation); - void ProductTimesPopulated(common::RadarProductGroup group, - const std::string& product, - std::chrono::system_clock::time_point queryTime); private: std::unique_ptr p; @@ -159,4 +158,6 @@ private: friend class RadarProductManagerImpl; }; -} // namespace scwx::qt::manager +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp b/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp index c4b9f2e3..70c4b2ed 100644 --- a/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/timeline_manager.cpp @@ -53,13 +53,8 @@ public: // Lock mutexes before destroying std::unique_lock animationTimerLock {animationTimerMutex_}; animationTimer_.cancel(); - animationTimerLock.unlock(); - selectThreadPool_.stop(); - playThreadPool_.stop(); - - selectThreadPool_.join(); - playThreadPool_.join(); + std::unique_lock selectTimeLock {selectTimeMutex_}; } TimelineManager* self_; diff --git a/scwx-qt/source/scwx/qt/map/alert_layer.cpp b/scwx-qt/source/scwx/qt/map/alert_layer.cpp index b7529e5b..7bea5938 100644 --- a/scwx-qt/source/scwx/qt/map/alert_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/alert_layer.cpp @@ -6,8 +6,8 @@ #include #include #include +#include -#include #include #include #include @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include namespace scwx::qt::map { @@ -153,11 +153,9 @@ public: ~Impl() { std::unique_lock refreshLock(refreshMutex_); - refreshEnabled_ = false; refreshTimer_.cancel(); refreshLock.unlock(); - threadPool_.stop(); threadPool_.join(); receiver_ = nullptr; @@ -215,7 +213,6 @@ public: AlertLayer* self_; - std::atomic refreshEnabled_ {true}; boost::asio::system_timer refreshTimer_ {threadPool_}; std::mutex refreshMutex_; @@ -585,8 +582,7 @@ void AlertLayer::Impl::ScheduleRefresh() // Expires at the top of the next minute std::chrono::system_clock::time_point now = - std::chrono::floor( - std::chrono::system_clock::now()); + std::chrono::floor(scwx::util::time::now()); refreshTimer_.expires_at(now + 1min); refreshTimer_.async_wait( @@ -603,11 +599,7 @@ void AlertLayer::Impl::ScheduleRefresh() else { Q_EMIT self_->NeedsRendering(); - - if (refreshEnabled_) - { - ScheduleRefresh(); - } + ScheduleRefresh(); } }); } @@ -891,7 +883,7 @@ void AlertLayer::Impl::HandleGeoLinesEvent( switch (ev->type()) { - case QEvent::Type::MouseButtonRelease: + case QEvent::Type::MouseButtonPress: { auto it = segmentsByLine_.find(di); if (it != segmentsByLine_.cend()) diff --git a/scwx-qt/source/scwx/qt/map/map_provider.cpp b/scwx-qt/source/scwx/qt/map/map_provider.cpp index 81d21a66..b1b5979d 100644 --- a/scwx-qt/source/scwx/qt/map/map_provider.cpp +++ b/scwx-qt/source/scwx/qt/map/map_provider.cpp @@ -73,7 +73,7 @@ static const std::unordered_map mapProviderInfo_ { .drawBelow_ {mapboxDrawBelow_}}, {.name_ {"Mineral"}, .url_ {"mapbox://styles/mapbox/cjtep62gq54l21frr1whf27ak"}, - .drawBelow_ {"tunnel"}}, + .drawBelow_ {mapboxDrawBelow_}}, {.name_ {"Minimo"}, .url_ { "mapbox://styles/mapbox-map-design/cksjc2nsq1bg117pnekb655h1"}, diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp index 3c942b28..04b0890e 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp @@ -92,15 +92,8 @@ public: Impl(const Impl&&) = delete; Impl& operator=(const Impl&&) = delete; - void RenderProductName(const std::shared_ptr& mapContext); - void - RenderProductDetails(const std::shared_ptr& mapContext, - const QMapLibre::CustomLayerRenderParameters& params); - void RenderAttribution(const std::shared_ptr& mapContext, - const QMapLibre::CustomLayerRenderParameters& params); - void SetupGeoIcons(); - void SetCursorLocation(common::Coordinate coordinate); + void SetCusorLocation(common::Coordinate coordinate); OverlayLayer* self_; @@ -180,7 +173,7 @@ OverlayLayer::~OverlayLayer() p->cursorScaleConnection_.disconnect(); } -void OverlayLayer::Impl::SetCursorLocation(common::Coordinate coordinate) +void OverlayLayer::Impl::SetCusorLocation(common::Coordinate coordinate) { geoIcons_->SetIconLocation( cursorIcon_, coordinate.latitude_, coordinate.longitude_); @@ -395,7 +388,7 @@ void OverlayLayer::Render(const std::shared_ptr& mapContext, p->geoIcons_->SetIconVisible(p->cursorIcon_, cursorIconVisible); if (cursorIconVisible) { - p->SetCursorLocation(mapContext->mouse_coordinate()); + p->SetCusorLocation(mapContext->mouse_coordinate()); } // Location Icon @@ -432,58 +425,6 @@ void OverlayLayer::Render(const std::shared_ptr& mapContext, } } - p->RenderProductName(mapContext); - p->RenderProductDetails(mapContext, params); - - // Map Center Icon - if (params.width != p->lastWidth_ || params.height != p->lastHeight_) - { - static constexpr double xPosition = 0.5; - static constexpr double yPosition = 0.5; - - // Draw the icon in the center of the widget - p->icons_->SetIconLocation(p->mapCenterIcon_, - params.width * xPosition, - params.height * yPosition); - } - p->icons_->SetIconVisible(p->mapCenterIcon_, - generalSettings.show_map_center().GetValue()); - - const QMargins colorTableMargins = mapContext->color_table_margins(); - if (colorTableMargins != p->lastColorTableMargins_ || p->firstRender_) - { - static constexpr int xOffset = 10; - static constexpr int yOffset = 10; - - // Draw map logo with a 10x10 indent from the bottom left - p->icons_->SetIconLocation(p->mapLogoIcon_, - colorTableMargins.left() + xOffset, - colorTableMargins.bottom() + yOffset); - } - p->icons_->SetIconVisible(p->mapLogoIcon_, - generalSettings.show_map_logo().GetValue()); - - DrawLayer::RenderWithoutImGui(params); - - p->RenderAttribution(mapContext, params); - - p->firstRender_ = false; - p->lastWidth_ = params.width; - p->lastHeight_ = params.height; - p->lastBearing_ = params.bearing; - p->lastFontSize_ = ImGui::GetFontSize(); - p->lastColorTableMargins_ = colorTableMargins; - - ImGuiFrameEnd(); - - SCWX_GL_CHECK_ERROR(); -} - -void OverlayLayer::Impl::RenderProductName( - const std::shared_ptr& mapContext) -{ - auto radarProductView = mapContext->radar_product_view(); - if (radarProductView != nullptr) { // Render product name @@ -515,68 +456,14 @@ void OverlayLayer::Impl::RenderProductName( ImGui::End(); } } -} -void OverlayLayer::Impl::RenderProductDetails( - const std::shared_ptr& mapContext, - const QMapLibre::CustomLayerRenderParameters& params) -{ - auto radarProductView = mapContext->radar_product_view(); - - ImGui::SetNextWindowPos(ImVec2 {static_cast(params.width), 0.0f}, - ImGuiCond_Always, - ImVec2 {1.0f, 0.0f}); - - bool productNotAvailable = false; - types::RadarProductLoadStatus newLoadStatus = - types::RadarProductLoadStatus::ProductNotLoaded; - - if (radarProductView != nullptr) - { - newLoadStatus = radarProductView->load_status(); - - switch (newLoadStatus) - { - case types::RadarProductLoadStatus::ProductNotAvailable: - productNotAvailable = true; - break; - - default: - productNotAvailable = false; - } - } - - if (productNotAvailable) - { - ImGui::Begin("Product Not Available", - nullptr, - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_AlwaysAutoResize); - - ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); - ImGui::TextUnformatted("NO DATA AVAILABLE"); - ImGui::PopStyleColor(); - if (ImGui::BeginItemTooltip()) - { - static constexpr float kFontSizeFactor_ = 20.0f; - static constexpr double kMaxWidthPercent_ = 0.8; - - ImGui::PushTextWrapPos( - std::min(ImGui::GetFontSize() * kFontSizeFactor_, - static_cast(params.width * kMaxWidthPercent_))); - ImGui::TextUnformatted( - "No data found for the selected product and time. Please select a " - "different product, or update your time selection."); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - ImGui::End(); - } - else if (sweepTimeString_.length() > 0) + if (p->sweepTimeString_.length() > 0) { // Render time - ImGui::Begin("Product Details", + ImGui::SetNextWindowPos(ImVec2 {static_cast(params.width), 0.0f}, + ImGuiCond_Always, + ImVec2 {1.0f, 0.0f}); + ImGui::Begin("Sweep Time", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); @@ -584,12 +471,12 @@ void OverlayLayer::Impl::RenderProductDetails( if (radarProductView != nullptr && ImGui::IsWindowHovered()) { // Show a detailed product description when the sweep time is hovered - sweepTimePicked_ = true; + p->sweepTimePicked_ = true; auto fields = radarProductView->GetDescriptionFields(); if (fields.empty()) { - ImGui::TextUnformatted(sweepTimeString_.c_str()); + ImGui::TextUnformatted(p->sweepTimeString_.c_str()); } else { @@ -609,19 +496,34 @@ void OverlayLayer::Impl::RenderProductDetails( } else { - ImGui::TextUnformatted(sweepTimeString_.c_str()); + ImGui::TextUnformatted(p->sweepTimeString_.c_str()); } ImGui::End(); } -} -void OverlayLayer::Impl::RenderAttribution( - const std::shared_ptr& mapContext, - const QMapLibre::CustomLayerRenderParameters& params) -{ + // Map Center Icon + if (params.width != p->lastWidth_ || params.height != p->lastHeight_) + { + // Draw the icon in the center of the widget + p->icons_->SetIconLocation( + p->mapCenterIcon_, params.width / 2.0, params.height / 2.0); + } + p->icons_->SetIconVisible(p->mapCenterIcon_, + generalSettings.show_map_center().GetValue()); + const QMargins colorTableMargins = mapContext->color_table_margins(); - auto& generalSettings = settings::GeneralSettings::Instance(); + if (colorTableMargins != p->lastColorTableMargins_ || p->firstRender_) + { + // Draw map logo with a 10x10 indent from the bottom left + p->icons_->SetIconLocation(p->mapLogoIcon_, + 10 + colorTableMargins.left(), + 10 + colorTableMargins.bottom()); + } + p->icons_->SetIconVisible(p->mapLogoIcon_, + generalSettings.show_map_logo().GetValue()); + + DrawLayer::RenderWithoutImGui(params); auto mapCopyrights = mapContext->map_copyrights(); if (mapCopyrights.length() > 0 && @@ -630,19 +532,13 @@ void OverlayLayer::Impl::RenderAttribution( auto attributionFont = manager::FontManager::Instance().GetImGuiFont( types::FontCategory::Attribution); - static constexpr float kWindowBgAlpha_ = 0.5f; - static constexpr float kWindowPaddingX_ = 3.0f; - static constexpr float kWindowPaddingY_ = 2.0f; - - ImGui::SetNextWindowPos( - ImVec2 { - static_cast(params.width), - static_cast(params.height - colorTableMargins.bottom())}, - ImGuiCond_Always, - ImVec2 {1.0f, 1.0f}); - ImGui::SetNextWindowBgAlpha(kWindowBgAlpha_); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, - ImVec2 {kWindowPaddingX_, kWindowPaddingY_}); + ImGui::SetNextWindowPos(ImVec2 {static_cast(params.width), + static_cast(params.height) - + colorTableMargins.bottom()}, + ImGuiCond_Always, + ImVec2 {1.0f, 1.0f}); + ImGui::SetNextWindowBgAlpha(0.5f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2 {3.0f, 2.0f}); ImGui::PushFont(attributionFont.first->font(), attributionFont.second.value()); ImGui::Begin("Attribution", @@ -654,6 +550,17 @@ void OverlayLayer::Impl::RenderAttribution( ImGui::PopFont(); ImGui::PopStyleVar(); } + + p->firstRender_ = false; + p->lastWidth_ = params.width; + p->lastHeight_ = params.height; + p->lastBearing_ = params.bearing; + p->lastFontSize_ = ImGui::GetFontSize(); + p->lastColorTableMargins_ = colorTableMargins; + + ImGuiFrameEnd(); + + SCWX_GL_CHECK_ERROR(); } void OverlayLayer::Deinitialize() diff --git a/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp b/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp index 38eeff41..22b43a87 100644 --- a/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp @@ -63,9 +63,6 @@ public: bool colorTableNeedsUpdate_ {false}; bool sweepNeedsUpdate_ {false}; - - types::RadarProductLoadStatus latchedLoadStatus_ { - types::RadarProductLoadStatus::ProductNotAvailable}; }; RadarProductLayer::RadarProductLayer(std::shared_ptr glContext) : @@ -149,26 +146,6 @@ void RadarProductLayer::Initialize( &view::RadarProductView::SweepComputed, this, [this]() { p->sweepNeedsUpdate_ = true; }); - connect(radarProductView.get(), - &view::RadarProductView::SweepNotComputed, - this, - [this](types::NoUpdateReason reason) - { - if (reason == types::NoUpdateReason::NotAvailable) - { - // Ensure the radar product is hidden by re-rendering - Q_EMIT NeedsRendering(); - } - if (reason == types::NoUpdateReason::NoChange) - { - if (p->latchedLoadStatus_ == - types::RadarProductLoadStatus::ProductNotAvailable) - { - // Ensure the radar product is shown by re-rendering - Q_EMIT NeedsRendering(); - } - } - }); } void RadarProductLayer::UpdateSweep( @@ -212,10 +189,10 @@ void RadarProductLayer::UpdateSweep( glEnableVertexAttribArray(0); // Buffer data moments - const GLvoid* data {}; - GLsizeiptr dataSize {}; - size_t componentSize {}; - GLenum type {}; + const GLvoid* data; + GLsizeiptr dataSize; + size_t componentSize; + GLenum type; std::tie(data, dataSize, componentSize) = radarProductView->GetMomentData(); @@ -238,10 +215,10 @@ void RadarProductLayer::UpdateSweep( glEnableVertexAttribArray(1); // Buffer CFP data - const GLvoid* cfpData {}; - GLsizeiptr cfpDataSize {}; - size_t cfpComponentSize {}; - GLenum cfpType {}; + const GLvoid* cfpData; + GLsizeiptr cfpDataSize; + size_t cfpComponentSize; + GLenum cfpType; std::tie(cfpData, cfpDataSize, cfpComponentSize) = radarProductView->GetCfpMomentData(); @@ -281,6 +258,7 @@ void RadarProductLayer::Render( const std::shared_ptr& mapContext, const QMapLibre::CustomLayerRenderParameters& params) { + p->shaderProgram_->Use(); // Set OpenGL blend mode for transparency @@ -303,65 +281,34 @@ void RadarProductLayer::Render( UpdateSweep(mapContext); } - const std::shared_ptr radarProductView = - mapContext->radar_product_view(); + const float scale = std::pow(2.0, params.zoom) * 2.0f * + mbgl::util::tileSize_D / mbgl::util::DEGREES_MAX; + const float xScale = scale / params.width; + const float yScale = scale / params.height; - bool sweepVisible = false; - types::RadarProductLoadStatus newLoadStatus = - types::RadarProductLoadStatus::ProductNotLoaded; + glm::mat4 uMVPMatrix(1.0f); + uMVPMatrix = glm::scale(uMVPMatrix, glm::vec3(xScale, yScale, 1.0f)); + uMVPMatrix = glm::rotate(uMVPMatrix, + glm::radians(params.bearing), + glm::vec3(0.0f, 0.0f, 1.0f)); - if (radarProductView != nullptr) - { - newLoadStatus = radarProductView->load_status(); + glUniform2fv(p->uMapScreenCoordLocation_, + 1, + glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( + {params.latitude, params.longitude}))); - switch (newLoadStatus) - { - case types::RadarProductLoadStatus::ProductNotAvailable: - sweepVisible = false; - break; + glUniformMatrix4fv( + p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); - case types::RadarProductLoadStatus::ListingProducts: - sweepVisible = p->latchedLoadStatus_ != - types::RadarProductLoadStatus::ProductNotAvailable; - break; + glUniform1i(p->uCFPEnabledLocation_, p->cfpEnabled_ ? 1 : 0); - default: - sweepVisible = true; - } - } + glUniform1ui(p->uDataMomentOffsetLocation_, p->rangeMin_); + glUniform1f(p->uDataMomentScaleLocation_, p->scale_); - if (sweepVisible) - { - const double scale = std::pow(2.0, params.zoom) * 2.0 * - mbgl::util::tileSize_D / mbgl::util::DEGREES_MAX; - const auto xScale = static_cast(scale / params.width); - const auto yScale = static_cast(scale / params.height); - - glm::mat4 uMVPMatrix(1.0f); - uMVPMatrix = glm::scale(uMVPMatrix, glm::vec3(xScale, yScale, 1.0f)); - uMVPMatrix = glm::rotate(uMVPMatrix, - glm::radians(static_cast(params.bearing)), - glm::vec3(0.0f, 0.0f, 1.0f)); - - glUniform2fv(p->uMapScreenCoordLocation_, - 1, - glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( - {params.latitude, params.longitude}))); - - glUniformMatrix4fv( - p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); - - glUniform1i(p->uCFPEnabledLocation_, p->cfpEnabled_ ? 1 : 0); - - glUniform1ui(p->uDataMomentOffsetLocation_, p->rangeMin_); - glUniform1f(p->uDataMomentScaleLocation_, p->scale_); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_1D, p->texture_); - glBindVertexArray(p->vao_); - - glDrawArrays(GL_TRIANGLES, 0, static_cast(p->numVertices_)); - } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_1D, p->texture_); + glBindVertexArray(p->vao_); + glDrawArrays(GL_TRIANGLES, 0, static_cast(p->numVertices_)); if (wireframeEnabled) { @@ -369,16 +316,6 @@ void RadarProductLayer::Render( glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - if (radarProductView != nullptr && - // Don't latch a transition from Not Available to Listing Products - !(p->latchedLoadStatus_ == - types::RadarProductLoadStatus::ProductNotAvailable && - newLoadStatus == types::RadarProductLoadStatus::ListingProducts)) - { - // Latch last load status - p->latchedLoadStatus_ = newLoadStatus; - } - SCWX_GL_CHECK_ERROR(); } @@ -606,7 +543,7 @@ void RadarProductLayer::UpdateColorTable( const uint16_t rangeMin = radarProductView->color_table_min(); const uint16_t rangeMax = radarProductView->color_table_max(); - const auto scale = static_cast(rangeMax - rangeMin); + const float scale = rangeMax - rangeMin; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_1D, p->texture_); diff --git a/scwx-qt/source/scwx/qt/settings/map_settings.cpp b/scwx-qt/source/scwx/qt/settings/map_settings.cpp index 74b156b5..76c09d30 100644 --- a/scwx-qt/source/scwx/qt/settings/map_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/map_settings.cpp @@ -86,10 +86,8 @@ public: } else { - // Validate level 3 product - const auto level3Product = - common::GetLevel3ProductByAwipsId(value); - return !level3Product.empty() && level3Product != "?"; + // TODO: Validate level 3 product + return true; } }); diff --git a/scwx-qt/source/scwx/qt/types/map_types.hpp b/scwx-qt/source/scwx/qt/types/map_types.hpp index e8c2a24f..5853a188 100644 --- a/scwx-qt/source/scwx/qt/types/map_types.hpp +++ b/scwx-qt/source/scwx/qt/types/map_types.hpp @@ -25,7 +25,6 @@ enum class NoUpdateReason { NoChange, NotLoaded, - NotAvailable, InvalidProduct, InvalidData }; diff --git a/scwx-qt/source/scwx/qt/types/radar_product_types.hpp b/scwx-qt/source/scwx/qt/types/radar_product_types.hpp deleted file mode 100644 index 7e9fd70c..00000000 --- a/scwx-qt/source/scwx/qt/types/radar_product_types.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -namespace scwx::qt::types -{ - -enum class RadarProductLoadStatus : std::uint8_t -{ - ProductNotLoaded, - ProductLoaded, - ListingProducts, - LoadingProduct, - ProductNotAvailable -}; - -} diff --git a/scwx-qt/source/scwx/qt/ui/update_dialog.cpp b/scwx-qt/source/scwx/qt/ui/update_dialog.cpp index f3ccb2d8..edb0396e 100644 --- a/scwx-qt/source/scwx/qt/ui/update_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/update_dialog.cpp @@ -93,9 +93,9 @@ void UpdateDialog::Impl::HandleAsset(const types::gh::ReleaseAsset& asset) #if defined(_WIN32) # if defined(_M_AMD64) - static const std::string assetSuffix = "-x64.msi"; + static constexpr std::string assetSuffix = "-x64.msi"; # else - static const std::string assetSuffix = "-arm64.msi"; + static constexpr std::string assetSuffix = "-arm64.msi"; # endif if (asset.name_.ends_with(assetSuffix)) diff --git a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp index a0805bc7..9ead358b 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp @@ -8,13 +8,14 @@ #include #include -#include -#include - #include #include -namespace scwx::qt::view +namespace scwx +{ +namespace qt +{ +namespace view { static const std::string logPrefix_ = "scwx::qt::view::level2_product_view"; @@ -163,13 +164,11 @@ public: float latitude_; float longitude_; - std::atomic elevationCut_; + float elevationCut_; std::vector elevationCuts_; units::kilometers range_; uint16_t vcp_; - std::mutex elevationCutsMutex_ {}; - std::chrono::system_clock::time_point sweepTime_; std::shared_ptr colorTable_; @@ -215,22 +214,6 @@ void Level2ProductView::ConnectRadarProductManager() Update(); } }); - - connect(radar_product_manager().get(), - &manager::RadarProductManager::ProductTimesPopulated, - this, - [this](common::RadarProductGroup group, - const std::string& /* product */, - std::chrono::system_clock::time_point queryTime) - { - if (group == common::RadarProductGroup::Level2 && - queryTime == selected_time()) - { - // If the data associated with the currently selected time is - // reloaded, update the view - Update(); - } - }); } void Level2ProductView::DisconnectRadarProductManager() @@ -373,7 +356,6 @@ std::string Level2ProductView::GetRadarProductName() const std::vector Level2ProductView::GetElevationCuts() const { - const std::unique_lock lock {p->elevationCutsMutex_}; return p->elevationCuts_; } @@ -570,26 +552,13 @@ void Level2ProductView::ComputeSweep() std::shared_ptr radarData; std::chrono::system_clock::time_point requestedTime {selected_time()}; - types::RadarProductLoadStatus loadStatus {}; - - std::vector newElevationCuts {}; - std::tie( - radarData, p->elevationCut_, newElevationCuts, std::ignore, loadStatus) = + std::tie(radarData, p->elevationCut_, p->elevationCuts_, std::ignore) = radarProductManager->GetLevel2Data( p->dataBlockType_, p->selectedElevation_, requestedTime); - std::unique_lock elevationCutsLock {p->elevationCutsMutex_}; - p->elevationCuts_ = newElevationCuts; - elevationCutsLock.unlock(); - - set_load_status(loadStatus); - if (radarData == nullptr) { - Q_EMIT SweepNotComputed( - loadStatus == types::RadarProductLoadStatus::ProductNotAvailable ? - types::NoUpdateReason::NotAvailable : - types::NoUpdateReason::NotLoaded); + Q_EMIT SweepNotComputed(types::NoUpdateReason::NotLoaded); return; } if ((radarData == p->elevationScan_) && @@ -1400,7 +1369,7 @@ Level2ProductView::GetBinLevel(const common::Coordinate& coordinate) const auto nextRadial = radarData->find((i + 1) % numRadials); if (nextRadial != radarData->cend()) { - nextAngle = nextRadial->second->azimuth_angle(); + nextAngle = nextRadial->second->azimuth_angle(); // Level 2 angles are the center of the bins. const units::degrees deltaAngle = @@ -1595,4 +1564,6 @@ std::shared_ptr Level2ProductView::Create( return std::make_shared(product, radarProductManager); } -} // namespace scwx::qt::view +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp index 6abe7556..97985a39 100644 --- a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp @@ -11,12 +11,17 @@ #include #include +#include #include #include #include -namespace scwx::qt::view +namespace scwx +{ +namespace qt +{ +namespace view { static const std::string logPrefix_ = "scwx::qt::view::level3_product_view"; @@ -146,22 +151,6 @@ void Level3ProductView::ConnectRadarProductManager() Update(); } }); - - connect(radar_product_manager().get(), - &manager::RadarProductManager::ProductTimesPopulated, - this, - [this](common::RadarProductGroup group, - const std::string& product, - std::chrono::system_clock::time_point queryTime) - { - if (group == common::RadarProductGroup::Level3 && - product == p->product_ && queryTime == selected_time()) - { - // If the data associated with the currently selected time is - // reloaded, update the view - Update(); - } - }); } void Level3ProductView::DisconnectRadarProductManager() @@ -607,4 +596,6 @@ bool Level3ProductView::IgnoreUnits() const return false; } -} // namespace scwx::qt::view +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp b/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp index b8fe539b..c01e0cd4 100644 --- a/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp @@ -10,7 +10,11 @@ #include #include -namespace scwx::qt::view +namespace scwx +{ +namespace qt +{ +namespace view { static const std::string logPrefix_ = "scwx::qt::view::level3_radial_view"; @@ -27,7 +31,15 @@ static constexpr std::uint32_t VALUES_PER_VERTEX = 2u; class Level3RadialView::Impl { public: - explicit Impl(Level3RadialView* self) : self_ {self} {} + explicit Impl(Level3RadialView* self) : + self_ {self}, + latitude_ {}, + longitude_ {}, + range_ {}, + vcp_ {}, + sweepTime_ {} + { + } ~Impl() { threadPool_.join(); }; void ComputeCoordinates( @@ -53,13 +65,13 @@ public: bool lastShowSmoothedRangeFolding_ {false}; bool lastSmoothingEnabled_ {false}; - float latitude_ {}; - float longitude_ {}; + float latitude_; + float longitude_; std::optional elevation_ {}; - float range_ {}; - std::uint16_t vcp_ {}; + float range_; + std::uint16_t vcp_; - std::chrono::system_clock::time_point sweepTime_ {}; + std::chrono::system_clock::time_point sweepTime_; }; Level3RadialView::Level3RadialView( @@ -136,12 +148,9 @@ void Level3RadialView::ComputeSweep() std::shared_ptr message; std::chrono::system_clock::time_point requestedTime {selected_time()}; std::chrono::system_clock::time_point foundTime; - types::RadarProductLoadStatus loadStatus {}; - std::tie(message, foundTime, loadStatus) = + std::tie(message, foundTime) = radarProductManager->GetLevel3Data(GetRadarProductName(), requestedTime); - set_load_status(loadStatus); - // If a different time was found than what was requested, update it if (requestedTime != foundTime) { @@ -151,10 +160,7 @@ void Level3RadialView::ComputeSweep() if (message == nullptr) { logger_->debug("Level 3 data not found"); - Q_EMIT SweepNotComputed( - loadStatus == types::RadarProductLoadStatus::ProductNotAvailable ? - types::NoUpdateReason::NotAvailable : - types::NoUpdateReason::NotLoaded); + Q_EMIT SweepNotComputed(types::NoUpdateReason::NotLoaded); return; } @@ -746,4 +752,6 @@ std::shared_ptr Level3RadialView::Create( return std::make_shared(product, radarProductManager); } -} // namespace scwx::qt::view +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp b/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp index 92ecbb9f..3056cc03 100644 --- a/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp @@ -10,7 +10,11 @@ #include #include -namespace scwx::qt::view +namespace scwx +{ +namespace qt +{ +namespace view { static const std::string logPrefix_ = "scwx::qt::view::level3_raster_view"; @@ -121,12 +125,9 @@ void Level3RasterView::ComputeSweep() std::shared_ptr message; std::chrono::system_clock::time_point requestedTime {selected_time()}; std::chrono::system_clock::time_point foundTime; - types::RadarProductLoadStatus loadStatus {}; - std::tie(message, foundTime, loadStatus) = + std::tie(message, foundTime) = radarProductManager->GetLevel3Data(GetRadarProductName(), requestedTime); - set_load_status(loadStatus); - // If a different time was found than what was requested, update it if (requestedTime != foundTime) { @@ -136,10 +137,7 @@ void Level3RasterView::ComputeSweep() if (message == nullptr) { logger_->debug("Level 3 data not found"); - Q_EMIT SweepNotComputed( - loadStatus == types::RadarProductLoadStatus::ProductNotAvailable ? - types::NoUpdateReason::NotAvailable : - types::NoUpdateReason::NotLoaded); + Q_EMIT SweepNotComputed(types::NoUpdateReason::NotLoaded); return; } @@ -540,4 +538,6 @@ std::shared_ptr Level3RasterView::Create( return std::make_shared(product, radarProductManager); } -} // namespace scwx::qt::view +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp b/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp index 95f1af09..ccc41b9d 100644 --- a/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/overlay_product_view.cpp @@ -8,7 +8,11 @@ #include #include -namespace scwx::qt::view +namespace scwx +{ +namespace qt +{ +namespace view { static const std::string logPrefix_ = "scwx::qt::view::overlay_product_view"; @@ -124,22 +128,6 @@ void OverlayProductView::Impl::ConnectRadarProductManager() } }, Qt::QueuedConnection); - - connect(radarProductManager_.get(), - &manager::RadarProductManager::ProductTimesPopulated, - self_, - [this](common::RadarProductGroup group, - const std::string& product, - std::chrono::system_clock::time_point queryTime) - { - if (group == common::RadarProductGroup::Level3 && - product == kNst_ && queryTime == selectedTime_) - { - // If the data associated with the currently selected time is - // reloaded, update the view - Update(product); - } - }); } void OverlayProductView::Impl::DisconnectRadarProductManager() @@ -298,7 +286,7 @@ void OverlayProductView::Impl::Update(const std::string& product) std::shared_ptr message; std::chrono::system_clock::time_point requestedTime {selectedTime_}; std::chrono::system_clock::time_point foundTime; - std::tie(message, foundTime, std::ignore) = + std::tie(message, foundTime) = radarProductManager_->GetLevel3Data(product, requestedTime); // If a different time was found than what was requested, update it @@ -341,4 +329,6 @@ void OverlayProductView::SetAutoUpdate(bool enabled) p->autoUpdateEnabled_ = enabled; } -} // namespace scwx::qt::view +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp index 00e261eb..dc50383c 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp @@ -58,8 +58,6 @@ public: std::chrono::system_clock::time_point selectedTime_; bool showSmoothedRangeFolding_ {false}; bool smoothingEnabled_ {false}; - types::RadarProductLoadStatus loadStatus_ { - types::RadarProductLoadStatus::ProductNotLoaded}; std::shared_ptr radarProductManager_; @@ -92,11 +90,6 @@ std::optional RadarProductView::elevation() const return {}; } -types::RadarProductLoadStatus RadarProductView::load_status() const -{ - return p->loadStatus_; -} - std::shared_ptr RadarProductView::radar_product_manager() const { @@ -133,11 +126,6 @@ std::mutex& RadarProductView::sweep_mutex() return p->sweepMutex_; } -void RadarProductView::set_load_status(types::RadarProductLoadStatus loadStatus) -{ - p->loadStatus_ = loadStatus; -} - void RadarProductView::set_radar_product_manager( std::shared_ptr radarProductManager) { diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp index 267afe0a..2801b74e 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -38,12 +38,11 @@ public: [[nodiscard]] virtual std::shared_ptr color_table() const = 0; [[nodiscard]] virtual const std::vector& - color_table_lut() const; - [[nodiscard]] virtual std::uint16_t color_table_min() const; - [[nodiscard]] virtual std::uint16_t color_table_max() const; - [[nodiscard]] virtual std::optional elevation() const; - [[nodiscard]] types::RadarProductLoadStatus load_status() const; - [[nodiscard]] virtual float range() const; + color_table_lut() const; + [[nodiscard]] virtual std::uint16_t color_table_min() const; + [[nodiscard]] virtual std::uint16_t color_table_max() const; + [[nodiscard]] virtual std::optional elevation() const; + [[nodiscard]] virtual float range() const; [[nodiscard]] virtual std::chrono::system_clock::time_point sweep_time() const; [[nodiscard]] virtual float unit_scale() const = 0; @@ -99,8 +98,6 @@ protected: virtual void DisconnectRadarProductManager() = 0; virtual void UpdateColorTableLut() = 0; - void set_load_status(types::RadarProductLoadStatus loadStatus); - protected slots: virtual void ComputeSweep(); diff --git a/test/data b/test/data index fd8bc8bf..c68bee74 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit fd8bc8bf1d07474886ce6773abffab4d315d0cd0 +Subproject commit c68bee74549963e9a02e0fa998efad0f10f8256b diff --git a/test/source/scwx/provider/aws_level3_data_provider.test.cpp b/test/source/scwx/provider/aws_level3_data_provider.test.cpp index 6e9f3bb2..31ea50ec 100644 --- a/test/source/scwx/provider/aws_level3_data_provider.test.cpp +++ b/test/source/scwx/provider/aws_level3_data_provider.test.cpp @@ -76,7 +76,7 @@ TEST(AwsLevel3DataProvider, GetTimePointsByDate) AwsLevel3DataProvider provider("KLSX", "N0Q"); - auto timePoints = provider.GetTimePointsByDate(date, true); + auto timePoints = provider.GetTimePointsByDate(date); EXPECT_GT(timePoints.size(), 0); for (auto timePoint : timePoints) diff --git a/tools/net.supercellwx.app.yml b/tools/net.supercellwx.app.yml index 9c1119ce..762edf28 100644 --- a/tools/net.supercellwx.app.yml +++ b/tools/net.supercellwx.app.yml @@ -1,5 +1,5 @@ id: net.supercellwx.app -version: '0.5.2' +version: '0.5.1' runtime: "org.freedesktop.Platform" runtime-version: "23.08" sdk: "org.freedesktop.Sdk" diff --git a/wxdata/include/scwx/provider/aws_level2_chunks_data_provider.hpp b/wxdata/include/scwx/provider/aws_level2_chunks_data_provider.hpp index 1c8a1ca9..abd70787 100644 --- a/wxdata/include/scwx/provider/aws_level2_chunks_data_provider.hpp +++ b/wxdata/include/scwx/provider/aws_level2_chunks_data_provider.hpp @@ -46,9 +46,7 @@ public: std::string FindLatestKey() override; std::chrono::system_clock::time_point FindLatestTime() override; std::vector - GetTimePointsByDate(std::chrono::system_clock::time_point date, - bool update) override; - bool IsDateCached(std::chrono::system_clock::time_point date) override; + GetTimePointsByDate(std::chrono::system_clock::time_point date) override; std::tuple ListObjects(std::chrono::system_clock::time_point date) override; std::shared_ptr diff --git a/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp b/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp index 3db8c273..d6ddcd7c 100644 --- a/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp +++ b/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp @@ -2,12 +2,17 @@ #include -namespace Aws::S3 +namespace Aws +{ +namespace S3 { class S3Client; -} // namespace Aws::S3 +} // namespace S3 +} // namespace Aws -namespace scwx::provider +namespace scwx +{ +namespace provider { /** @@ -27,23 +32,20 @@ public: AwsNexradDataProvider(AwsNexradDataProvider&&) noexcept; AwsNexradDataProvider& operator=(AwsNexradDataProvider&&) noexcept; - [[nodiscard]] std::size_t cache_size() const override; + size_t cache_size() const override; - [[nodiscard]] std::chrono::system_clock::time_point - last_modified() const override; - [[nodiscard]] std::chrono::seconds update_period() const override; + std::chrono::system_clock::time_point last_modified() const override; + std::chrono::seconds update_period() const override; std::string FindKey(std::chrono::system_clock::time_point time) override; std::string FindLatestKey() override; std::chrono::system_clock::time_point FindLatestTime() override; std::vector - GetTimePointsByDate(std::chrono::system_clock::time_point date, - bool update) override; - bool IsDateCached(std::chrono::system_clock::time_point date) override; + GetTimePointsByDate(std::chrono::system_clock::time_point date) override; std::tuple ListObjects(std::chrono::system_clock::time_point date) override; std::shared_ptr - LoadObjectByKey(const std::string& key) override; + LoadObjectByKey(const std::string& key) override; std::shared_ptr LoadObjectByTime(std::chrono::system_clock::time_point time) override; std::pair Refresh() override; @@ -59,4 +61,5 @@ private: std::unique_ptr p; }; -} // namespace scwx::provider +} // namespace provider +} // namespace scwx diff --git a/wxdata/include/scwx/provider/nexrad_data_provider.hpp b/wxdata/include/scwx/provider/nexrad_data_provider.hpp index 2bc3703d..2a7320d2 100644 --- a/wxdata/include/scwx/provider/nexrad_data_provider.hpp +++ b/wxdata/include/scwx/provider/nexrad_data_provider.hpp @@ -7,7 +7,9 @@ #include #include -namespace scwx::provider +namespace scwx +{ +namespace provider { class NexradDataProvider @@ -22,7 +24,7 @@ public: NexradDataProvider(NexradDataProvider&&) noexcept; NexradDataProvider& operator=(NexradDataProvider&&) noexcept; - [[nodiscard]] virtual size_t cache_size() const = 0; + virtual size_t cache_size() const = 0; /** * Gets the last modified time. This is equal to the most recent object's @@ -30,8 +32,7 @@ public: * * @return Last modified time */ - [[nodiscard]] virtual std::chrono::system_clock::time_point - last_modified() const = 0; + virtual std::chrono::system_clock::time_point last_modified() const = 0; /** * Gets the current update period. This is equal to the difference between @@ -40,7 +41,7 @@ public: * * @return Update period */ - [[nodiscard]] virtual std::chrono::seconds update_period() const = 0; + virtual std::chrono::seconds update_period() const = 0; /** * Finds the most recent key in the cache, no later than the time provided. @@ -115,7 +116,7 @@ public: * * @return NEXRAD data time point */ - [[nodiscard]] virtual std::chrono::system_clock::time_point + virtual std::chrono::system_clock::time_point GetTimePointByKey(const std::string& key) const = 0; /** @@ -123,22 +124,11 @@ public: * to the cache if required. * * @param date Date for which to get NEXRAD data time points - * @param update Whether or not to list and add data not present in the cache * * @return NEXRAD data time points */ virtual std::vector - GetTimePointsByDate(std::chrono::system_clock::time_point date, - bool update) = 0; - - /** - * Determines if time points for the requested date are cached. - * - * @param date Date for which to query the cache - * - * @return Whether or not the requested date is cached - */ - virtual bool IsDateCached(std::chrono::system_clock::time_point date) = 0; + GetTimePointsByDate(std::chrono::system_clock::time_point date) = 0; /** * Requests available NEXRAD products for the current radar site, and adds @@ -158,4 +148,5 @@ private: std::unique_ptr p; }; -} // namespace scwx::provider +} // namespace provider +} // namespace scwx diff --git a/wxdata/source/scwx/provider/aws_level2_chunks_data_provider.cpp b/wxdata/source/scwx/provider/aws_level2_chunks_data_provider.cpp index e5f99b99..f7de36ca 100644 --- a/wxdata/source/scwx/provider/aws_level2_chunks_data_provider.cpp +++ b/wxdata/source/scwx/provider/aws_level2_chunks_data_provider.cpp @@ -289,18 +289,11 @@ AwsLevel2ChunksDataProvider::FindLatestTime() std::vector AwsLevel2ChunksDataProvider::GetTimePointsByDate( - std::chrono::system_clock::time_point /* date */, bool /* update */) + std::chrono::system_clock::time_point /*date*/) { return {}; } -bool AwsLevel2ChunksDataProvider::IsDateCached( - std::chrono::system_clock::time_point /* date */) -{ - // No cache, default to true - return true; -} - std::chrono::system_clock::time_point AwsLevel2ChunksDataProvider::Impl::GetScanTime(const std::string& prefix) { diff --git a/wxdata/source/scwx/provider/aws_level2_data_provider.cpp b/wxdata/source/scwx/provider/aws_level2_data_provider.cpp index 074f61f1..c2910773 100644 --- a/wxdata/source/scwx/provider/aws_level2_data_provider.cpp +++ b/wxdata/source/scwx/provider/aws_level2_data_provider.cpp @@ -18,7 +18,7 @@ static const std::string logPrefix_ = "scwx::provider::aws_level2_data_provider"; static const auto logger_ = util::Logger::Create(logPrefix_); -static const std::string kDefaultBucketName_ = "unidata-nexrad-level2"; +static const std::string kDefaultBucketName_ = "noaa-nexrad-level2"; static const std::string kDefaultRegion_ = "us-east-1"; class AwsLevel2DataProvider::Impl diff --git a/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp b/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp index b7eab596..97528a9e 100644 --- a/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp +++ b/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp @@ -15,7 +15,9 @@ #include #include -namespace scwx::provider +namespace scwx +{ +namespace provider { static const std::string logPrefix_ = @@ -175,7 +177,7 @@ std::chrono::system_clock::time_point AwsNexradDataProvider::FindLatestTime() std::vector AwsNexradDataProvider::GetTimePointsByDate( - std::chrono::system_clock::time_point date, bool update) + std::chrono::system_clock::time_point date) { const auto day = std::chrono::floor(date); @@ -186,27 +188,24 @@ AwsNexradDataProvider::GetTimePointsByDate( std::shared_lock lock(p->objectsMutex_); // Is the date present in the date list? - bool currentDatePresent = false; + bool currentDatePresent; auto currentDateIterator = std::find(p->objectDates_.cbegin(), p->objectDates_.cend(), day); if (currentDateIterator == p->objectDates_.cend()) { - if (update) + // Temporarily unlock mutex + lock.unlock(); + + // List objects, since the date is not present in the date list + auto [success, newObjects, totalObjects] = ListObjects(date); + if (success) { - // Temporarily unlock mutex - lock.unlock(); - - // List objects, since the date is not present in the date list - const auto [success, newObjects, totalObjects] = ListObjects(date); - if (success) - { - p->UpdateObjectDates(date); - } - - // Re-lock mutex - lock.lock(); + p->UpdateObjectDates(date); } + // Re-lock mutex + lock.lock(); + currentDatePresent = false; } else @@ -215,8 +214,8 @@ AwsNexradDataProvider::GetTimePointsByDate( } // Determine objects to retrieve - const auto objectsBegin = p->objects_.lower_bound(day); - const auto objectsEnd = p->objects_.lower_bound(day + std::chrono::days {1}); + auto objectsBegin = p->objects_.lower_bound(day); + auto objectsEnd = p->objects_.lower_bound(day + std::chrono::days {1}); // Copy time points to destination vector std::transform(objectsBegin, @@ -237,20 +236,6 @@ AwsNexradDataProvider::GetTimePointsByDate( return timePoints; } -bool AwsNexradDataProvider::IsDateCached( - std::chrono::system_clock::time_point date) -{ - const auto day = std::chrono::floor(date); - - const std::shared_lock lock(p->objectsMutex_); - - // Is the date present in the date list? - const auto currentDateIterator = - std::find(p->objectDates_.cbegin(), p->objectDates_.cend(), day); - - return currentDateIterator != p->objectDates_.cend(); -} - std::tuple AwsNexradDataProvider::ListObjects(std::chrono::system_clock::time_point date) { @@ -461,4 +446,5 @@ void AwsNexradDataProvider::Impl::UpdateObjectDates( objectDates_.push_back(day); } -} // namespace scwx::provider +} // namespace provider +} // namespace scwx