mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 17:40:05 +00:00
Get bin values at coordinates from level 3 radial data, stubs for raster and level 2
This commit is contained in:
parent
c67b4cf536
commit
6e04e1fab3
9 changed files with 153 additions and 19 deletions
|
|
@ -774,6 +774,14 @@ void Level2ProductViewImpl::ComputeCoordinates(
|
|||
logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws"));
|
||||
}
|
||||
|
||||
std::optional<std::uint16_t>
|
||||
Level2ProductView::GetBinLevel(const common::Coordinate& coordinate) const
|
||||
{
|
||||
// TODO
|
||||
Q_UNUSED(coordinate);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Level2ProductView> Level2ProductView::Create(
|
||||
common::Level2Product product,
|
||||
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public:
|
|||
GetMomentData() const override;
|
||||
std::tuple<const void*, std::size_t, std::size_t>
|
||||
GetCfpMomentData() const override;
|
||||
std::optional<std::uint16_t>
|
||||
GetBinLevel(const common::Coordinate& coordinate) const override;
|
||||
|
||||
static std::shared_ptr<Level2ProductView>
|
||||
Create(common::Level2Product product,
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ static const auto logger_ = util::Logger::Create(logPrefix_);
|
|||
|
||||
static constexpr uint16_t RANGE_FOLDED = 1u;
|
||||
|
||||
class Level3ProductViewImpl
|
||||
class Level3ProductView::Impl
|
||||
{
|
||||
public:
|
||||
explicit Level3ProductViewImpl(const std::string& product) :
|
||||
explicit Impl(const std::string& product) :
|
||||
product_ {product},
|
||||
graphicMessage_ {nullptr},
|
||||
colorTable_ {},
|
||||
|
|
@ -42,7 +42,7 @@ public:
|
|||
savedOffset_ {0.0f}
|
||||
{
|
||||
}
|
||||
~Level3ProductViewImpl() = default;
|
||||
~Impl() = default;
|
||||
|
||||
std::string product_;
|
||||
|
||||
|
|
@ -61,8 +61,7 @@ public:
|
|||
Level3ProductView::Level3ProductView(
|
||||
const std::string& product,
|
||||
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
|
||||
RadarProductView(radarProductManager),
|
||||
p(std::make_unique<Level3ProductViewImpl>(product))
|
||||
RadarProductView(radarProductManager), p(std::make_unique<Impl>(product))
|
||||
{
|
||||
ConnectRadarProductManager();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ namespace qt
|
|||
namespace view
|
||||
{
|
||||
|
||||
class Level3ProductViewImpl;
|
||||
|
||||
class Level3ProductView : public RadarProductView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -52,7 +50,8 @@ protected:
|
|||
void UpdateColorTable() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Level3ProductViewImpl> p;
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ static constexpr std::uint16_t RANGE_FOLDED = 1u;
|
|||
static constexpr std::uint32_t VERTICES_PER_BIN = 6u;
|
||||
static constexpr std::uint32_t VALUES_PER_VERTEX = 2u;
|
||||
|
||||
class Level3RadialViewImpl
|
||||
class Level3RadialView::Impl
|
||||
{
|
||||
public:
|
||||
explicit Level3RadialViewImpl(Level3RadialView* self) :
|
||||
explicit Impl(Level3RadialView* self) :
|
||||
self_ {self},
|
||||
latitude_ {},
|
||||
longitude_ {},
|
||||
|
|
@ -41,10 +41,10 @@ public:
|
|||
{
|
||||
coordinates_.resize(kMaxCoordinates_);
|
||||
}
|
||||
~Level3RadialViewImpl() { threadPool_.join(); };
|
||||
~Impl() { threadPool_.join(); };
|
||||
|
||||
void ComputeCoordinates(
|
||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData);
|
||||
const std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket>& radialData);
|
||||
|
||||
Level3RadialView* self_;
|
||||
|
||||
|
|
@ -54,6 +54,8 @@ public:
|
|||
std::vector<float> vertices_ {};
|
||||
std::vector<std::uint8_t> dataMoments8_ {};
|
||||
|
||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> lastRadialData_ {};
|
||||
|
||||
float latitude_;
|
||||
float longitude_;
|
||||
float range_;
|
||||
|
|
@ -66,7 +68,7 @@ Level3RadialView::Level3RadialView(
|
|||
const std::string& product,
|
||||
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
|
||||
Level3ProductView(product, radarProductManager),
|
||||
p(std::make_unique<Level3RadialViewImpl>(this))
|
||||
p(std::make_unique<Impl>(this))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -235,6 +237,8 @@ void Level3RadialView::ComputeSweep()
|
|||
return;
|
||||
}
|
||||
|
||||
p->lastRadialData_ = radialData;
|
||||
|
||||
// Valid number of radials is 1-720
|
||||
size_t radials = radialData->number_of_radials();
|
||||
if (radials < 1 || radials > 720)
|
||||
|
|
@ -424,8 +428,8 @@ void Level3RadialView::ComputeSweep()
|
|||
Q_EMIT SweepComputed();
|
||||
}
|
||||
|
||||
void Level3RadialViewImpl::ComputeCoordinates(
|
||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData)
|
||||
void Level3RadialView::Impl::ComputeCoordinates(
|
||||
const std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket>& radialData)
|
||||
{
|
||||
logger_->debug("ComputeCoordinates()");
|
||||
|
||||
|
|
@ -485,6 +489,113 @@ void Level3RadialViewImpl::ComputeCoordinates(
|
|||
logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws"));
|
||||
}
|
||||
|
||||
std::optional<std::uint16_t>
|
||||
Level3RadialView::GetBinLevel(const common::Coordinate& coordinate) const
|
||||
{
|
||||
auto gpm = graphic_product_message();
|
||||
if (gpm == nullptr)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<wsr88d::rpg::ProductDescriptionBlock> descriptionBlock =
|
||||
gpm->description_block();
|
||||
if (descriptionBlock == nullptr)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData =
|
||||
p->lastRadialData_;
|
||||
if (radialData == nullptr)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Determine distance and azimuth of coordinate relative to radar location
|
||||
double s12; // Distance (meters)
|
||||
double azi1; // Azimuth (degrees)
|
||||
double azi2; // Unused
|
||||
util::GeographicLib::DefaultGeodesic().Inverse(
|
||||
descriptionBlock->latitude_of_radar(),
|
||||
descriptionBlock->longitude_of_radar(),
|
||||
coordinate.latitude_,
|
||||
coordinate.longitude_,
|
||||
s12,
|
||||
azi1,
|
||||
azi2);
|
||||
|
||||
if (std::isnan(azi1))
|
||||
{
|
||||
// If a problem occurred with the geodesic inverse calculation
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Azimuth is returned as [-180, 180) from the geodesic inverse, we need a
|
||||
// range of [0, 360)
|
||||
while (azi1 < 0.0)
|
||||
{
|
||||
azi1 += 360.0;
|
||||
}
|
||||
|
||||
// Compute gate interval
|
||||
const std::uint16_t gates = radialData->number_of_range_bins();
|
||||
const std::uint16_t dataMomentInterval =
|
||||
descriptionBlock->x_resolution_raw();
|
||||
std::uint16_t gate = s12 / dataMomentInterval;
|
||||
|
||||
if (gate >= gates)
|
||||
{
|
||||
// Coordinate is beyond radar range
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Find Radial
|
||||
const std::uint16_t numRadials = radialData->number_of_radials();
|
||||
std::uint16_t radial = numRadials;
|
||||
float nextAngle = radialData->start_angle(0);
|
||||
for (std::uint16_t i = 0; i < numRadials; ++i)
|
||||
{
|
||||
float startAngle = nextAngle;
|
||||
nextAngle = radialData->start_angle((i + 1) % numRadials);
|
||||
|
||||
if (startAngle < nextAngle)
|
||||
{
|
||||
if (startAngle <= azi1 && azi1 < nextAngle)
|
||||
{
|
||||
radial = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the bin crosses 0/360 degrees, special handling is needed
|
||||
if (startAngle <= azi1 || azi1 < nextAngle)
|
||||
{
|
||||
radial = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (radial == numRadials)
|
||||
{
|
||||
// No radial was found (not likely to happen without a gap in data)
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Compute threshold at which to display an individual bin
|
||||
const std::uint16_t snrThreshold = descriptionBlock->threshold();
|
||||
const std::uint8_t level = radialData->level(radial).at(gate);
|
||||
|
||||
if (level < snrThreshold && level != RANGE_FOLDED)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
std::shared_ptr<Level3RadialView> Level3RadialView::Create(
|
||||
const std::string& product,
|
||||
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ namespace qt
|
|||
namespace view
|
||||
{
|
||||
|
||||
class Level3RadialViewImpl;
|
||||
|
||||
class Level3RadialView : public Level3ProductView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -32,6 +30,8 @@ public:
|
|||
|
||||
std::tuple<const void*, std::size_t, std::size_t>
|
||||
GetMomentData() const override;
|
||||
std::optional<std::uint16_t>
|
||||
GetBinLevel(const common::Coordinate& coordinate) const override;
|
||||
|
||||
static std::shared_ptr<Level3RadialView>
|
||||
Create(const std::string& product,
|
||||
|
|
@ -44,7 +44,8 @@ protected slots:
|
|||
void ComputeSweep() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Level3RadialViewImpl> p;
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
|
|
|
|||
|
|
@ -352,6 +352,14 @@ void Level3RasterView::ComputeSweep()
|
|||
Q_EMIT SweepComputed();
|
||||
}
|
||||
|
||||
std::optional<std::uint16_t>
|
||||
Level3RasterView::GetBinLevel(const common::Coordinate& coordinate) const
|
||||
{
|
||||
// TODO
|
||||
Q_UNUSED(coordinate);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Level3RasterView> Level3RasterView::Create(
|
||||
const std::string& product,
|
||||
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ public:
|
|||
|
||||
std::tuple<const void*, std::size_t, std::size_t>
|
||||
GetMomentData() const override;
|
||||
std::optional<std::uint16_t>
|
||||
GetBinLevel(const common::Coordinate& coordinate) const override;
|
||||
|
||||
static std::shared_ptr<Level3RasterView>
|
||||
Create(const std::string& product,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/common/color_table.hpp>
|
||||
#include <scwx/common/geographic.hpp>
|
||||
#include <scwx/common/products.hpp>
|
||||
#include <scwx/qt/manager/radar_product_manager.hpp>
|
||||
#include <scwx/qt/types/map_types.hpp>
|
||||
|
|
@ -8,6 +9,7 @@
|
|||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
|
@ -63,7 +65,9 @@ public:
|
|||
virtual std::tuple<const void*, std::size_t, std::size_t>
|
||||
GetMomentData() const = 0;
|
||||
virtual std::tuple<const void*, std::size_t, std::size_t>
|
||||
GetCfpMomentData() const;
|
||||
GetCfpMomentData() const;
|
||||
virtual std::optional<std::uint16_t>
|
||||
GetBinLevel(const common::Coordinate& coordinate) const = 0;
|
||||
std::chrono::system_clock::time_point GetSelectedTime() const;
|
||||
|
||||
virtual std::vector<std::pair<std::string, std::string>>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue