From 8b7a3e978126673fe326255f4605b24524c0c4c7 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sun, 6 Apr 2025 16:09:48 -0400 Subject: [PATCH] partiallaly complete merging of radar data --- .../scwx/qt/manager/radar_product_manager.cpp | 11 ++ wxdata/include/scwx/wsr88d/ar2v_file.hpp | 2 + .../aws_level2_chunks_data_provider.cpp | 2 - wxdata/source/scwx/wsr88d/ar2v_file.cpp | 144 ++++++++++++++++++ 4 files changed, 157 insertions(+), 2 deletions(-) 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 bc29ed9a..e6ede7b4 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -1525,6 +1525,16 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, //TODO decide when to use chunked vs archived data. if (true) { + auto currentFile = std::dynamic_pointer_cast( + p->level2ChunksProviderManager_->provider_->LoadLatestObject()); + auto lastFile = std::dynamic_pointer_cast( + p->level2ChunksProviderManager_->provider_->LoadSecondLatestObject()); + auto radarFile = + std::make_shared(currentFile, lastFile); + std::tie(radarData, elevationCut, elevationCuts) = + radarFile->GetElevationScan(dataBlockType, elevation, time); + + /* auto currentFile = std::dynamic_pointer_cast( p->level2ChunksProviderManager_->provider_->LoadLatestObject()); std::shared_ptr currentRadarData = nullptr; @@ -1587,6 +1597,7 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, elevationCuts = std::move(lastElevationCuts); foundTime = collectionTime; } + */ } else { diff --git a/wxdata/include/scwx/wsr88d/ar2v_file.hpp b/wxdata/include/scwx/wsr88d/ar2v_file.hpp index 34d50b32..9afca516 100644 --- a/wxdata/include/scwx/wsr88d/ar2v_file.hpp +++ b/wxdata/include/scwx/wsr88d/ar2v_file.hpp @@ -32,6 +32,8 @@ public: Ar2vFile(Ar2vFile&&) noexcept; Ar2vFile& operator=(Ar2vFile&&) noexcept; + Ar2vFile(std::shared_ptr current, std::shared_ptr last); + std::uint32_t julian_date() const; std::uint32_t milliseconds() const; std::string icao() const; 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 09436bbe..ef5c392e 100644 --- a/wxdata/source/scwx/provider/aws_level2_chunks_data_provider.cpp +++ b/wxdata/source/scwx/provider/aws_level2_chunks_data_provider.cpp @@ -676,12 +676,10 @@ std::pair AwsLevel2ChunksDataProvider::Refresh() } if (p->lastScan_.valid_) { - /* if (p->LoadScan(p->lastScan_)) { newObjects += 1; } - */ totalObjects += 1; } diff --git a/wxdata/source/scwx/wsr88d/ar2v_file.cpp b/wxdata/source/scwx/wsr88d/ar2v_file.cpp index db04feba..a5f46731 100644 --- a/wxdata/source/scwx/wsr88d/ar2v_file.cpp +++ b/wxdata/source/scwx/wsr88d/ar2v_file.cpp @@ -5,9 +5,11 @@ #include #include #include +#include #include #include +#include #if defined(_MSC_VER) # pragma warning(push) @@ -539,5 +541,147 @@ bool Ar2vFile::IndexFile() return true; } +// TODO not good +bool IsRadarDataIncomplete( + const std::shared_ptr& radarData) +{ + // Assume the data is incomplete when the delta between the first and last + // angles is greater than 2.5 degrees. + constexpr units::degrees kIncompleteDataAngleThreshold_ {2.5}; + + const units::degrees firstAngle = + radarData->cbegin()->second->azimuth_angle(); + const units::degrees lastAngle = + radarData->crbegin()->second->azimuth_angle(); + const units::degrees angleDelta = + common::GetAngleDelta(firstAngle, lastAngle); + + return angleDelta > kIncompleteDataAngleThreshold_; +} + +Ar2vFile::Ar2vFile(std::shared_ptr current, + std::shared_ptr last) : + Ar2vFile() +{ + /*p->vcpData_ = std::make_shared( + *current->vcp_data());*/ + p->vcpData_ = nullptr; // TODO + /* + use index_ to go through each block type, and elevation. + get the latest time. + if the latest time is not complete, get the previous time (possibly in + last), and merge + */ + + if (current == nullptr) + { + return; + } + + for (const auto& type : current->p->index_) + { + for (const auto& elevation : type.second) + { + const auto& mostRecent = elevation.second.crbegin(); + if (mostRecent == elevation.second.crend()) + { + continue; + } + + if (IsRadarDataIncomplete(mostRecent->second)) + { + std::shared_ptr secondMostRecent = + nullptr; + auto maybe = elevation.second.rbegin(); + ++maybe; + + if (maybe == elevation.second.rend()) + { + if (last == nullptr) + { + // Nothing to merge with + p->index_[type.first][elevation.first][mostRecent->first] = + mostRecent->second; + continue; + } + + auto elevationScan = + std::get>( + last->GetElevationScan(type.first, elevation.first, {})); + if (elevationScan == nullptr) + { + // Nothing to merge with + p->index_[type.first][elevation.first][mostRecent->first] = + mostRecent->second; + continue; + } + + secondMostRecent = elevationScan; + } + else + { + secondMostRecent = maybe->second; + } + + auto newScan = std::make_shared(); + + // Convert old into new coords + logger_->error( + "old {}, new {}", + secondMostRecent->cbegin()->second->azimuth_angle().value(), + mostRecent->second->cbegin()->second->azimuth_angle().value()); + // TODO Ordering these correctly + for (const auto& radial : *secondMostRecent) + { + (*newScan)[radial.first] = radial.second; + } + for (const auto& radial : *(mostRecent->second)) + { + (*newScan)[radial.first] = radial.second; + } + + p->index_[type.first][elevation.first][mostRecent->first] = + newScan; + } + else + { + p->index_[type.first][elevation.first][mostRecent->first] = + mostRecent->second; + } + } + } + + // Go though last, adding other elevations TODO + if (last != nullptr) + { + for (const auto& type : last->p->index_) + { + float highestCurrentElevation = -90; + const auto& maybe1 = p->index_.find(type.first); + if (maybe1 != p->index_.cend()) + { + const auto& maybe2 = maybe1->second.crbegin(); + if (maybe2 != maybe1->second.crend()) { + highestCurrentElevation = maybe2->first + 0.01; + } + } + for (const auto& elevation : type.second) + { + if (elevation.first > highestCurrentElevation) + { + const auto& mostRecent = elevation.second.crbegin(); + if (mostRecent == elevation.second.crend()) + { + continue; + } + p->index_[type.first][elevation.first][mostRecent->first] = + mostRecent->second; + } + } + } + } + +} + } // namespace wsr88d } // namespace scwx