From 19f1207384709448a14cf69b640bd6834a9229d6 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 14 Nov 2021 14:20:24 -0600 Subject: [PATCH] Infrastructure updates for multiple elevations --- .../scwx/qt/manager/radar_product_manager.cpp | 14 ++--- .../scwx/qt/manager/radar_product_manager.hpp | 4 +- .../scwx/qt/view/level2_product_view.cpp | 37 +++++++++----- .../scwx/qt/view/level2_product_view.hpp | 1 + .../scwx/qt/view/radar_product_view.cpp | 5 ++ .../scwx/qt/view/radar_product_view.hpp | 1 + wxdata/include/scwx/wsr88d/ar2v_file.hpp | 4 +- wxdata/source/scwx/wsr88d/ar2v_file.cpp | 51 ++++++++++++++++--- 8 files changed, 85 insertions(+), 32 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 80602df7..c706da82 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -180,17 +180,19 @@ void RadarProductManager::LoadLevel2Data(const std::string& filename) emit Level2DataLoaded(); } -std::shared_ptr +std::pair> RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, - uint16_t elevation, + float elevation, std::chrono::system_clock::time_point time) { - std::shared_ptr radarData = nullptr; + float elevationFound = 0.0f; + std::shared_ptr radarData = nullptr; if (p->level2VolumeScans_.size() > 0) { - radarData = p->level2VolumeScans_.crbegin()->second->GetElevationScan( - dataBlockType, elevation, time); + std::tie(elevationFound, radarData) = + p->level2VolumeScans_.crbegin()->second->GetElevationScan( + dataBlockType, elevation, time); } else { @@ -203,7 +205,7 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, }); } - return radarData; + return std::make_pair(elevationFound, radarData); } } // namespace manager 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 329ee541..32ad3baa 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp @@ -33,9 +33,9 @@ public: void Initialize(); void LoadLevel2Data(const std::string& filename); - std::shared_ptr + std::pair> GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, - uint16_t elevation, + float elevation, std::chrono::system_clock::time_point time = {}); signals: 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 0c00f333..eac5c777 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp @@ -44,8 +44,10 @@ public: std::shared_ptr radarProductManager) : product_ {product}, radarProductManager_ {radarProductManager}, + momentDataBlock0_ {nullptr}, latitude_ {}, longitude_ {}, + elevation_ {}, range_ {}, sweepTime_ {}, colorTable_ {}, @@ -81,6 +83,7 @@ public: float latitude_; float longitude_; + float elevation_; float range_; std::chrono::system_clock::time_point sweepTime_; @@ -122,6 +125,11 @@ Level2ProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const } } +float Level2ProductView::elevation() const +{ + return p->elevation_; +} + float Level2ProductView::range() const { return p->range_; @@ -276,8 +284,10 @@ void Level2ProductView::ComputeSweep() } // TODO: Pick this based on view settings - auto radarData = - p->radarProductManager_->GetLevel2Data(p->dataBlockType_, 0); + float elevation; + std::shared_ptr radarData; + std::tie(elevation, radarData) = + p->radarProductManager_->GetLevel2Data(p->dataBlockType_, 0.0f); if (radarData == nullptr) { return; @@ -308,6 +318,7 @@ void Level2ProductView::ComputeSweep() auto volumeData0 = radarData0->volume_data_block(); p->latitude_ = volumeData0->latitude(); p->longitude_ = volumeData0->longitude(); + p->elevation_ = elevation; p->range_ = momentData0->data_moment_range() + momentData0->data_moment_range_sample_interval() * (gates - 0.5f); @@ -464,16 +475,15 @@ void Level2ProductView::ComputeSweep() { const uint16_t baseCoord = gate - 1; - size_t offset1 = ((startRadial + radial) % common::MAX_RADIALS * + size_t offset1 = ((startRadial + radial) % radials * common::MAX_DATA_MOMENT_GATES + baseCoord) * 2; size_t offset2 = offset1 + gateSize * 2; - size_t offset3 = - (((startRadial + radial + 1) % common::MAX_RADIALS) * - common::MAX_DATA_MOMENT_GATES + - baseCoord) * - 2; + size_t offset3 = (((startRadial + radial + 1) % radials) * + common::MAX_DATA_MOMENT_GATES + + baseCoord) * + 2; size_t offset4 = offset3 + gateSize * 2; vertices[vIndex++] = coordinates[offset1]; @@ -500,15 +510,14 @@ void Level2ProductView::ComputeSweep() { const uint16_t baseCoord = gate; - size_t offset1 = ((startRadial + radial) % common::MAX_RADIALS * + size_t offset1 = ((startRadial + radial) % radials * + common::MAX_DATA_MOMENT_GATES + + baseCoord) * + 2; + size_t offset2 = (((startRadial + radial + 1) % radials) * common::MAX_DATA_MOMENT_GATES + baseCoord) * 2; - size_t offset2 = - (((startRadial + radial + 1) % common::MAX_RADIALS) * - common::MAX_DATA_MOMENT_GATES + - baseCoord) * - 2; vertices[vIndex++] = p->latitude_; vertices[vIndex++] = p->longitude_; diff --git a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp index b5c59b3a..606511dd 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp @@ -30,6 +30,7 @@ public: const std::vector& color_table(uint16_t& minValue, uint16_t& maxValue) const override; + float elevation() const override; float range() const override; std::chrono::system_clock::time_point sweep_time() const override; const std::vector& vertices() const override; 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 39507703..ad17f137 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp @@ -40,6 +40,11 @@ RadarProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const return DEFAULT_COLOR_TABLE; } +float RadarProductView::elevation() const +{ + return 0.0f; +} + float RadarProductView::range() const { return 0.0f; 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 90772e65..0c375860 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -27,6 +27,7 @@ public: virtual const std::vector& color_table(uint16_t& minValue, uint16_t& maxValue) const; + virtual float elevation() const; virtual float range() const; virtual std::chrono::system_clock::time_point sweep_time() const; virtual const std::vector& vertices() const = 0; diff --git a/wxdata/include/scwx/wsr88d/ar2v_file.hpp b/wxdata/include/scwx/wsr88d/ar2v_file.hpp index 1d2e542a..a6d8a9ca 100644 --- a/wxdata/include/scwx/wsr88d/ar2v_file.hpp +++ b/wxdata/include/scwx/wsr88d/ar2v_file.hpp @@ -40,9 +40,9 @@ public: std::map> radar_data() const; std::shared_ptr vcp_data() const; - std::shared_ptr + std::pair> GetElevationScan(rda::DataBlockType dataBlockType, - uint16_t elevation, + float elevation, std::chrono::system_clock::time_point time) const; bool LoadFile(const std::string& filename); diff --git a/wxdata/source/scwx/wsr88d/ar2v_file.cpp b/wxdata/source/scwx/wsr88d/ar2v_file.cpp index 08f38fad..8133f0bb 100644 --- a/wxdata/source/scwx/wsr88d/ar2v_file.cpp +++ b/wxdata/source/scwx/wsr88d/ar2v_file.cpp @@ -106,21 +106,56 @@ std::shared_ptr Ar2vFile::vcp_data() const return p->vcpData_; } -std::shared_ptr +std::pair> Ar2vFile::GetElevationScan(rda::DataBlockType dataBlockType, - uint16_t elevation, + float elevation, std::chrono::system_clock::time_point time) const { - std::shared_ptr elevationScan = nullptr; + constexpr float scaleFactor = 8.0f / 0.043945f; - // TODO: 88 = 0.5 degrees - this should be parameterized and searched - if (p->index_.contains(dataBlockType) && - p->index_.at(dataBlockType).contains(88)) + float elevationFound = 0.0f; + std::shared_ptr elevationScan = nullptr; + + uint16_t codedElevation = + static_cast(std::lroundf(elevation * scaleFactor)); + + if (p->index_.contains(dataBlockType)) { - return p->index_.at(dataBlockType).at(88); + auto scans = p->index_.at(dataBlockType); + + uint16_t lowerBound = scans.cbegin()->first; + uint16_t upperBound = scans.crbegin()->first; + + for (auto scan : scans) + { + if (scan.first > lowerBound && scan.first < codedElevation) + { + lowerBound = scan.first; + } + if (scan.first < upperBound && scan.first > codedElevation) + { + upperBound = scan.first; + } + } + + uint16_t lowerDelta = std::abs(static_cast(codedElevation) - + static_cast(lowerBound)); + uint16_t upperDelta = std::abs(static_cast(codedElevation) - + static_cast(upperBound)); + + if (lowerDelta < upperDelta) + { + elevationFound = lowerBound / scaleFactor; + elevationScan = scans.at(lowerBound); + } + else + { + elevationFound = upperBound / scaleFactor; + elevationScan = scans.at(upperBound); + } } - return elevationScan; + return std::make_pair(elevationFound, elevationScan); } bool Ar2vFile::LoadFile(const std::string& filename)