mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 08:10:05 +00:00
fully working merging of data from last and current scan
This commit is contained in:
parent
8b7a3e9781
commit
094d286b41
5 changed files with 140 additions and 153 deletions
|
|
@ -1520,87 +1520,17 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
|
||||||
std::vector<float> elevationCuts {};
|
std::vector<float> elevationCuts {};
|
||||||
std::chrono::system_clock::time_point foundTime {};
|
std::chrono::system_clock::time_point foundTime {};
|
||||||
|
|
||||||
auto records = p->GetLevel2ProductRecords(time);
|
|
||||||
|
|
||||||
//TODO decide when to use chunked vs archived data.
|
//TODO decide when to use chunked vs archived data.
|
||||||
if (true)
|
if constexpr (true)
|
||||||
{
|
{
|
||||||
auto currentFile = std::dynamic_pointer_cast<wsr88d::Ar2vFile>(
|
auto currentFile = std::dynamic_pointer_cast<wsr88d::Ar2vFile>(
|
||||||
p->level2ChunksProviderManager_->provider_->LoadLatestObject());
|
p->level2ChunksProviderManager_->provider_->LoadLatestObject());
|
||||||
auto lastFile = std::dynamic_pointer_cast<wsr88d::Ar2vFile>(
|
|
||||||
p->level2ChunksProviderManager_->provider_->LoadSecondLatestObject());
|
|
||||||
auto radarFile =
|
|
||||||
std::make_shared<wsr88d::Ar2vFile>(currentFile, lastFile);
|
|
||||||
std::tie(radarData, elevationCut, elevationCuts) =
|
std::tie(radarData, elevationCut, elevationCuts) =
|
||||||
radarFile->GetElevationScan(dataBlockType, elevation, time);
|
|
||||||
|
|
||||||
/*
|
|
||||||
auto currentFile = std::dynamic_pointer_cast<wsr88d::Ar2vFile>(
|
|
||||||
p->level2ChunksProviderManager_->provider_->LoadLatestObject());
|
|
||||||
std::shared_ptr<wsr88d::rda::ElevationScan> currentRadarData = nullptr;
|
|
||||||
float currentElevationCut = 0.0f;
|
|
||||||
std::vector<float> currentElevationCuts;
|
|
||||||
if (currentFile != nullptr)
|
|
||||||
{
|
|
||||||
std::tie(currentRadarData, currentElevationCut, currentElevationCuts) =
|
|
||||||
currentFile->GetElevationScan(dataBlockType, elevation, time);
|
currentFile->GetElevationScan(dataBlockType, elevation, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<wsr88d::rda::ElevationScan> lastRadarData = nullptr;
|
|
||||||
float lastElevationCut = 0.0f;
|
|
||||||
std::vector<float> lastElevationCuts;
|
|
||||||
auto lastFile = std::dynamic_pointer_cast<wsr88d::Ar2vFile>(
|
|
||||||
p->level2ChunksProviderManager_->provider_->LoadSecondLatestObject());
|
|
||||||
if (lastFile != nullptr)
|
|
||||||
{
|
|
||||||
std::tie(lastRadarData, lastElevationCut, lastElevationCuts) =
|
|
||||||
lastFile->GetElevationScan(dataBlockType, elevation, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentRadarData != nullptr)
|
|
||||||
{
|
|
||||||
if (lastRadarData != nullptr)
|
|
||||||
{
|
|
||||||
auto& radarData0 = (*currentRadarData)[0];
|
|
||||||
auto collectionTime = std::chrono::floor<std::chrono::seconds>(
|
|
||||||
scwx::util::TimePoint(radarData0->modified_julian_date(),
|
|
||||||
radarData0->collection_time()));
|
|
||||||
|
|
||||||
// TODO merge data
|
|
||||||
radarData = currentRadarData;
|
|
||||||
elevationCut = currentElevationCut;
|
|
||||||
elevationCuts = std::move(currentElevationCuts);
|
|
||||||
foundTime = collectionTime;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto& radarData0 = (*currentRadarData)[0];
|
|
||||||
auto collectionTime = std::chrono::floor<std::chrono::seconds>(
|
|
||||||
scwx::util::TimePoint(radarData0->modified_julian_date(),
|
|
||||||
radarData0->collection_time()));
|
|
||||||
|
|
||||||
radarData = currentRadarData;
|
|
||||||
elevationCut = currentElevationCut;
|
|
||||||
elevationCuts = std::move(currentElevationCuts);
|
|
||||||
foundTime = collectionTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (lastRadarData != nullptr)
|
|
||||||
{
|
|
||||||
auto& radarData0 = (*lastRadarData)[0];
|
|
||||||
auto collectionTime = std::chrono::floor<std::chrono::seconds>(
|
|
||||||
scwx::util::TimePoint(radarData0->modified_julian_date(),
|
|
||||||
radarData0->collection_time()));
|
|
||||||
|
|
||||||
radarData = lastRadarData;
|
|
||||||
elevationCut = lastElevationCut;
|
|
||||||
elevationCuts = std::move(lastElevationCuts);
|
|
||||||
foundTime = collectionTime;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto records = p->GetLevel2ProductRecords(time);
|
||||||
for (auto& recordPair : records)
|
for (auto& recordPair : records)
|
||||||
{
|
{
|
||||||
auto& record = recordPair.second;
|
auto& record = recordPair.second;
|
||||||
|
|
|
||||||
|
|
@ -561,8 +561,7 @@ void Level2ProductView::ComputeSweep()
|
||||||
Q_EMIT SweepNotComputed(types::NoUpdateReason::NotLoaded);
|
Q_EMIT SweepNotComputed(types::NoUpdateReason::NotLoaded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO do not do this when updating from live data
|
if ((radarData == p->elevationScan_) &&
|
||||||
if (false && (radarData == p->elevationScan_) &&
|
|
||||||
smoothingEnabled == p->lastSmoothingEnabled_ &&
|
smoothingEnabled == p->lastSmoothingEnabled_ &&
|
||||||
(showSmoothedRangeFolding == p->lastShowSmoothedRangeFolding_ ||
|
(showSmoothedRangeFolding == p->lastShowSmoothedRangeFolding_ ||
|
||||||
!smoothingEnabled))
|
!smoothingEnabled))
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ public:
|
||||||
Ar2vFile(Ar2vFile&&) noexcept;
|
Ar2vFile(Ar2vFile&&) noexcept;
|
||||||
Ar2vFile& operator=(Ar2vFile&&) noexcept;
|
Ar2vFile& operator=(Ar2vFile&&) noexcept;
|
||||||
|
|
||||||
Ar2vFile(std::shared_ptr<Ar2vFile> current, std::shared_ptr<Ar2vFile> last);
|
Ar2vFile(const std::shared_ptr<Ar2vFile>& current,
|
||||||
|
const std::shared_ptr<Ar2vFile>& last);
|
||||||
|
|
||||||
std::uint32_t julian_date() const;
|
std::uint32_t julian_date() const;
|
||||||
std::uint32_t milliseconds() const;
|
std::uint32_t milliseconds() const;
|
||||||
|
|
|
||||||
|
|
@ -637,7 +637,9 @@ AwsLevel2ChunksDataProvider::LoadObjectByTime(
|
||||||
std::shared_ptr<wsr88d::NexradFile>
|
std::shared_ptr<wsr88d::NexradFile>
|
||||||
AwsLevel2ChunksDataProvider::LoadLatestObject()
|
AwsLevel2ChunksDataProvider::LoadLatestObject()
|
||||||
{
|
{
|
||||||
return p->currentScan_.nexradFile_;
|
return std::make_shared<wsr88d::Ar2vFile>(p->currentScan_.nexradFile_,
|
||||||
|
p->lastScan_.nexradFile_);
|
||||||
|
//return p->currentScan_.nexradFile_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<wsr88d::NexradFile>
|
std::shared_ptr<wsr88d::NexradFile>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
|
|
@ -559,40 +558,34 @@ bool IsRadarDataIncomplete(
|
||||||
return angleDelta > kIncompleteDataAngleThreshold_;
|
return angleDelta > kIncompleteDataAngleThreshold_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ar2vFile::Ar2vFile(std::shared_ptr<Ar2vFile> current,
|
Ar2vFile::Ar2vFile(const std::shared_ptr<Ar2vFile>& current,
|
||||||
std::shared_ptr<Ar2vFile> last) :
|
const std::shared_ptr<Ar2vFile>& last) :
|
||||||
Ar2vFile()
|
Ar2vFile()
|
||||||
{
|
{
|
||||||
/*p->vcpData_ = std::make_shared<rda::VolumeCoveragePatternData>(
|
// This is only used to index right now, so not a huge deal
|
||||||
*current->vcp_data());*/
|
p->vcpData_ = nullptr;
|
||||||
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)
|
// Reconstruct index from the other's indexes
|
||||||
|
if (current != nullptr)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& type : current->p->index_)
|
for (const auto& type : current->p->index_)
|
||||||
{
|
{
|
||||||
for (const auto& elevation : type.second)
|
for (const auto& elevation : type.second)
|
||||||
{
|
{
|
||||||
|
// Get the most recent scan
|
||||||
const auto& mostRecent = elevation.second.crbegin();
|
const auto& mostRecent = elevation.second.crbegin();
|
||||||
if (mostRecent == elevation.second.crend())
|
if (mostRecent == elevation.second.crend())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge this scan with the last one if it is incomplete
|
||||||
if (IsRadarDataIncomplete(mostRecent->second))
|
if (IsRadarDataIncomplete(mostRecent->second))
|
||||||
{
|
{
|
||||||
std::shared_ptr<rda::ElevationScan> secondMostRecent =
|
std::shared_ptr<rda::ElevationScan> secondMostRecent = nullptr;
|
||||||
nullptr;
|
|
||||||
auto maybe = elevation.second.rbegin();
|
// check if this volume scan has an earlier elevation scan
|
||||||
|
auto maybe = elevation.second.rbegin(); // TODO name
|
||||||
++maybe;
|
++maybe;
|
||||||
|
|
||||||
if (maybe == elevation.second.rend())
|
if (maybe == elevation.second.rend())
|
||||||
|
|
@ -605,9 +598,11 @@ Ar2vFile::Ar2vFile(std::shared_ptr<Ar2vFile> current,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the scan from the last scan
|
||||||
auto elevationScan =
|
auto elevationScan =
|
||||||
std::get<std::shared_ptr<rda::ElevationScan>>(
|
std::get<std::shared_ptr<rda::ElevationScan>>(
|
||||||
last->GetElevationScan(type.first, elevation.first, {}));
|
last->GetElevationScan(
|
||||||
|
type.first, elevation.first, {}));
|
||||||
if (elevationScan == nullptr)
|
if (elevationScan == nullptr)
|
||||||
{
|
{
|
||||||
// Nothing to merge with
|
// Nothing to merge with
|
||||||
|
|
@ -623,23 +618,76 @@ Ar2vFile::Ar2vFile(std::shared_ptr<Ar2vFile> current,
|
||||||
secondMostRecent = maybe->second;
|
secondMostRecent = maybe->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the new scan
|
||||||
auto newScan = std::make_shared<rda::ElevationScan>();
|
auto newScan = std::make_shared<rda::ElevationScan>();
|
||||||
|
|
||||||
// Convert old into new coords
|
// Copy over the new radials
|
||||||
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))
|
for (const auto& radial : *(mostRecent->second))
|
||||||
{
|
{
|
||||||
(*newScan)[radial.first] = radial.second;
|
(*newScan)[radial.first] = radial.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Correctly order the old radials. The radials need to be in
|
||||||
|
* order for the rendering to work, and the index needs to start
|
||||||
|
* at 0 and increase by one from there. Since the new radial
|
||||||
|
* should have index 0, the old radial needs to be reshaped to
|
||||||
|
* match the new radials indexing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const double lowestAzm =
|
||||||
|
mostRecent->second->cbegin()->second->azimuth_angle().value();
|
||||||
|
const double heighestAzm = mostRecent->second->crbegin()
|
||||||
|
->second->azimuth_angle()
|
||||||
|
.value();
|
||||||
|
std::uint16_t index = mostRecent->second->crbegin()->first + 1;
|
||||||
|
|
||||||
|
// Sort by the azimuth. Makes the rest of this way easier
|
||||||
|
auto secondMostRecentAzmMap =
|
||||||
|
std::map<float, std::shared_ptr<rda::GenericRadarData>>();
|
||||||
|
for (const auto& radial : *secondMostRecent)
|
||||||
|
{
|
||||||
|
secondMostRecentAzmMap[radial.second->azimuth_angle()
|
||||||
|
.value()] = radial.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lowestAzm <= heighestAzm) // New scan does not contain 0/360
|
||||||
|
{
|
||||||
|
// Get the radials following the new radials
|
||||||
|
for (const auto& radial : secondMostRecentAzmMap)
|
||||||
|
{
|
||||||
|
if (radial.first > heighestAzm)
|
||||||
|
{
|
||||||
|
(*newScan)[index] = radial.second;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get the radials before the new radials
|
||||||
|
for (const auto& radial : secondMostRecentAzmMap)
|
||||||
|
{
|
||||||
|
if (radial.first < lowestAzm)
|
||||||
|
{
|
||||||
|
(*newScan)[index] = radial.second;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // New scan includes 0/360
|
||||||
|
{
|
||||||
|
// The radials will already be in the right order
|
||||||
|
for (const auto& radial : secondMostRecentAzmMap)
|
||||||
|
{
|
||||||
|
if (radial.first > heighestAzm && radial.first < lowestAzm)
|
||||||
|
{
|
||||||
|
(*newScan)[index] = radial.second;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p->index_[type.first][elevation.first][mostRecent->first] =
|
p->index_[type.first][elevation.first][mostRecent->first] =
|
||||||
newScan;
|
newScan;
|
||||||
}
|
}
|
||||||
|
|
@ -650,23 +698,31 @@ Ar2vFile::Ar2vFile(std::shared_ptr<Ar2vFile> current,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Go though last, adding other elevations TODO
|
// Go though last, adding other elevations
|
||||||
if (last != nullptr)
|
if (last != nullptr)
|
||||||
{
|
{
|
||||||
for (const auto& type : last->p->index_)
|
for (const auto& type : last->p->index_)
|
||||||
{
|
{
|
||||||
|
// Find the highest elevation this type has for the current scan
|
||||||
|
// Start below any reasonable elevation
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
|
||||||
float highestCurrentElevation = -90;
|
float highestCurrentElevation = -90;
|
||||||
const auto& maybe1 = p->index_.find(type.first);
|
const auto& maybe1 = p->index_.find(type.first);
|
||||||
if (maybe1 != p->index_.cend())
|
if (maybe1 != p->index_.cend())
|
||||||
{
|
{
|
||||||
const auto& maybe2 = maybe1->second.crbegin();
|
const auto& maybe2 = maybe1->second.crbegin();
|
||||||
if (maybe2 != maybe1->second.crend()) {
|
if (maybe2 != maybe1->second.crend()) {
|
||||||
highestCurrentElevation = maybe2->first + 0.01;
|
// Add a slight offset to ensure good floating point compare.
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
|
||||||
|
highestCurrentElevation = maybe2->first + 0.01f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& elevation : type.second)
|
for (const auto& elevation : type.second)
|
||||||
{
|
{
|
||||||
|
// Only add elevations above the current scan's elevation
|
||||||
if (elevation.first > highestCurrentElevation)
|
if (elevation.first > highestCurrentElevation)
|
||||||
{
|
{
|
||||||
const auto& mostRecent = elevation.second.crbegin();
|
const auto& mostRecent = elevation.second.crbegin();
|
||||||
|
|
@ -680,7 +736,6 @@ Ar2vFile::Ar2vFile(std::shared_ptr<Ar2vFile> current,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace wsr88d
|
} // namespace wsr88d
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue