From 87581892a7758d15e4f90ac727a0ba974d7a5417 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 14 Nov 2021 01:28:13 -0600 Subject: [PATCH] Dynamic range circle --- scwx-qt/source/scwx/qt/map/map_widget.cpp | 15 ++--- .../source/scwx/qt/map/radar_range_layer.cpp | 65 ++++++++++++++----- .../source/scwx/qt/map/radar_range_layer.hpp | 9 ++- .../scwx/qt/view/level2_product_view.cpp | 16 ++++- .../scwx/qt/view/level2_product_view.hpp | 3 +- .../scwx/qt/view/radar_product_view.cpp | 5 ++ .../scwx/qt/view/radar_product_view.hpp | 3 +- .../scwx/wsr88d/rda/digital_radar_data.hpp | 6 +- .../scwx/wsr88d/rda/digital_radar_data.cpp | 17 +++++ 9 files changed, 105 insertions(+), 34 deletions(-) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 758ae555..ab94ddd6 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -115,7 +115,10 @@ void MapWidget::SelectRadarProduct(common::Level2Product product) p->radarProductView_.get(), &view::RadarProductView::SweepComputed, this, - [&]() { update(); }, + [&]() { + RadarRangeLayer::Update(p->map_, p->radarProductView_->range()); + update(); + }, Qt::QueuedConnection); if (p->map_ != nullptr) @@ -148,14 +151,6 @@ void MapWidget::changeStyle() void MapWidget::AddLayers() { // TODO: Improve this - if (p->map_->layerExists("rangeCircleLayer")) - { - p->map_->removeLayer("rangeCircleLayer"); - } - if (p->map_->sourceExists("rangeCircleSource")) - { - p->map_->removeSource("rangeCircleSource"); - } if (p->map_->layerExists("radar")) { p->map_->removeLayer("radar"); @@ -185,7 +180,7 @@ void MapWidget::AddLayers() } p->map_->addCustomLayer("radar", pHost, before); - RadarRangeLayer::Add(p->map_, before); + RadarRangeLayer::Add(p->map_, p->radarProductView_->range(), before); p->map_->addCustomLayer("overlay", pOverlayHost); } diff --git a/scwx-qt/source/scwx/qt/map/radar_range_layer.cpp b/scwx-qt/source/scwx/qt/map/radar_range_layer.cpp index 0e9aaea6..de171913 100644 --- a/scwx-qt/source/scwx/qt/map/radar_range_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/radar_range_layer.cpp @@ -13,15 +13,49 @@ namespace map static const std::string logPrefix_ = "[scwx::qt::map::radar_range_layer] "; -void RadarRangeLayer::Add(std::shared_ptr map, const QString& before) +static std::shared_ptr GetRangeCircle(float range); + +void RadarRangeLayer::Add(std::shared_ptr map, + float range, + const QString& before) { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Add()"; + if (map->layerExists("rangeCircleLayer")) + { + map->removeLayer("rangeCircleLayer"); + } + if (map->sourceExists("rangeCircleSource")) + { + map->removeSource("rangeCircleSource"); + } + + std::shared_ptr rangeCircle = GetRangeCircle(range); + + map->addSource( + "rangeCircleSource", + {{"type", "geojson"}, {"data", QVariant::fromValue(*rangeCircle)}}); + map->addLayer({{"id", "rangeCircleLayer"}, + {"type", "line"}, + {"source", "rangeCircleSource"}}, + before); + map->setPaintProperty( + "rangeCircleLayer", "line-color", "rgba(128, 128, 128, 128)"); +} + +void RadarRangeLayer::Update(std::shared_ptr map, float range) +{ + std::shared_ptr rangeCircle = GetRangeCircle(range); + + map->updateSource("rangeCircleSource", + {{"data", QVariant::fromValue(*rangeCircle)}}); +} + +static std::shared_ptr GetRangeCircle(float range) +{ GeographicLib::Geodesic geodesic(GeographicLib::Constants::WGS84_a(), GeographicLib::Constants::WGS84_f()); - constexpr float range = 460.0f * 1000.0f; - constexpr float angleDelta = 0.5f; constexpr float angleDeltaH = angleDelta / 2.0f; @@ -36,26 +70,25 @@ void RadarRangeLayer::Add(std::shared_ptr map, const QString& before) double latitude; double longitude; - geodesic.Direct( - radar.first, radar.second, angle, range, latitude, longitude); + geodesic.Direct(radar.first, + radar.second, + angle, + range * 1000.0f, + latitude, + longitude); geometry.append({latitude, longitude}); angle += angleDelta; } - QMapbox::Feature rangeCircle {QMapbox::Feature::LineStringType, - {{geometry}}}; + std::shared_ptr rangeCircle = + std::make_shared( + QMapbox::Feature::LineStringType, + std::initializer_list { + std::initializer_list {geometry}}); - map->addSource( - "rangeCircleSource", - {{"type", "geojson"}, {"data", QVariant::fromValue(rangeCircle)}}); - map->addLayer({{"id", "rangeCircleLayer"}, - {"type", "line"}, - {"source", "rangeCircleSource"}}, - before); - map->setPaintProperty( - "rangeCircleLayer", "line-color", "rgba(128, 128, 128, 128)"); + return rangeCircle; } } // namespace map diff --git a/scwx-qt/source/scwx/qt/map/radar_range_layer.hpp b/scwx-qt/source/scwx/qt/map/radar_range_layer.hpp index d33ccb68..8b892c31 100644 --- a/scwx-qt/source/scwx/qt/map/radar_range_layer.hpp +++ b/scwx-qt/source/scwx/qt/map/radar_range_layer.hpp @@ -8,12 +8,15 @@ namespace qt { namespace map { - namespace RadarRangeLayer { -void Add(std::shared_ptr map, const QString& before = QString()); -}; +void Add(std::shared_ptr map, + float range, + const QString& before = QString()); +void Update(std::shared_ptr map, float range); + +} // namespace RadarRangeLayer } // namespace map } // namespace qt } // namespace scwx 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 c5860aa9..0c00f333 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp @@ -46,6 +46,7 @@ public: radarProductManager_ {radarProductManager}, latitude_ {}, longitude_ {}, + range_ {}, sweepTime_ {}, colorTable_ {}, colorTableLut_ {}, @@ -80,6 +81,7 @@ public: float latitude_; float longitude_; + float range_; std::chrono::system_clock::time_point sweepTime_; @@ -120,6 +122,11 @@ Level2ProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const } } +float Level2ProductView::range() const +{ + return p->range_; +} + std::chrono::system_clock::time_point Level2ProductView::sweep_time() const { return p->sweepTime_; @@ -295,10 +302,16 @@ void Level2ProductView::ComputeSweep() return; } + const uint32_t gates = momentData0->number_of_data_moment_gates(); + + auto radialData0 = radarData0->radial_data_block(); auto volumeData0 = radarData0->volume_data_block(); p->latitude_ = volumeData0->latitude(); p->longitude_ = volumeData0->longitude(); - p->sweepTime_ = util::TimePoint(radarData0->modified_julian_date(), + p->range_ = + momentData0->data_moment_range() + + momentData0->data_moment_range_sample_interval() * (gates - 0.5f); + p->sweepTime_ = util::TimePoint(radarData0->modified_julian_date(), radarData0->collection_time()); // Calculate vertices @@ -306,7 +319,6 @@ void Level2ProductView::ComputeSweep() // Setup vertex vector std::vector& vertices = p->vertices_; - const uint32_t gates = momentData0->number_of_data_moment_gates(); size_t vIndex = 0; vertices.clear(); vertices.resize(radials * gates * VERTICES_PER_BIN * VALUES_PER_VERTEX); 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 7e48b4f9..b5c59b3a 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp @@ -29,7 +29,8 @@ public: ~Level2ProductView(); const std::vector& - color_table(uint16_t& minValue, uint16_t& maxValue) const override; + color_table(uint16_t& minValue, uint16_t& maxValue) 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 0e892f34..39507703 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::range() const +{ + return 0.0f; +} + std::chrono::system_clock::time_point RadarProductView::sweep_time() const { return {}; 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 63d8b240..90772e65 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -26,7 +26,8 @@ public: ~RadarProductView(); virtual const std::vector& - color_table(uint16_t& minValue, uint16_t& maxValue) const; + color_table(uint16_t& minValue, uint16_t& maxValue) 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/rda/digital_radar_data.hpp b/wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp index 8e0bb5d6..459ff185 100644 --- a/wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp +++ b/wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp @@ -129,6 +129,8 @@ public: RadialDataBlock(RadialDataBlock&&) noexcept; RadialDataBlock& operator=(RadialDataBlock&&) noexcept; + float unambiguous_range() const; + static std::shared_ptr Create(const std::string& dataBlockType, const std::string& dataName, @@ -195,7 +197,9 @@ public: uint8_t azimuth_indexing_mode() const; uint16_t data_block_count() const; - std::shared_ptr volume_data_block() const; + std::shared_ptr elevation_data_block() const; + std::shared_ptr radial_data_block() const; + std::shared_ptr volume_data_block() const; std::shared_ptr moment_data_block(DataBlockType type) const; bool Parse(std::istream& is); diff --git a/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp b/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp index 117130a0..c96fe87a 100644 --- a/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp +++ b/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp @@ -434,6 +434,11 @@ RadialDataBlock::RadialDataBlock(RadialDataBlock&&) noexcept = default; RadialDataBlock& RadialDataBlock::operator=(RadialDataBlock&&) noexcept = default; +float RadialDataBlock::unambiguous_range() const +{ + return p->unambigiousRange_ / 10.0f; +} + std::shared_ptr RadialDataBlock::Create(const std::string& dataBlockType, const std::string& dataName, @@ -613,6 +618,18 @@ uint16_t DigitalRadarData::data_block_count() const { return p->dataBlockCount_; } + +std::shared_ptr +DigitalRadarData::elevation_data_block() const +{ + return p->elevationDataBlock_; +} + +std::shared_ptr DigitalRadarData::radial_data_block() const +{ + return p->radialDataBlock_; +} + std::shared_ptr DigitalRadarData::volume_data_block() const { return p->volumeDataBlock_;