mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 21:10:04 +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"));
|
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(
|
std::shared_ptr<Level2ProductView> Level2ProductView::Create(
|
||||||
common::Level2Product product,
|
common::Level2Product product,
|
||||||
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ public:
|
||||||
GetMomentData() const override;
|
GetMomentData() const override;
|
||||||
std::tuple<const void*, std::size_t, std::size_t>
|
std::tuple<const void*, std::size_t, std::size_t>
|
||||||
GetCfpMomentData() const override;
|
GetCfpMomentData() const override;
|
||||||
|
std::optional<std::uint16_t>
|
||||||
|
GetBinLevel(const common::Coordinate& coordinate) const override;
|
||||||
|
|
||||||
static std::shared_ptr<Level2ProductView>
|
static std::shared_ptr<Level2ProductView>
|
||||||
Create(common::Level2Product product,
|
Create(common::Level2Product product,
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ static const auto logger_ = util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
static constexpr uint16_t RANGE_FOLDED = 1u;
|
static constexpr uint16_t RANGE_FOLDED = 1u;
|
||||||
|
|
||||||
class Level3ProductViewImpl
|
class Level3ProductView::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Level3ProductViewImpl(const std::string& product) :
|
explicit Impl(const std::string& product) :
|
||||||
product_ {product},
|
product_ {product},
|
||||||
graphicMessage_ {nullptr},
|
graphicMessage_ {nullptr},
|
||||||
colorTable_ {},
|
colorTable_ {},
|
||||||
|
|
@ -42,7 +42,7 @@ public:
|
||||||
savedOffset_ {0.0f}
|
savedOffset_ {0.0f}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
~Level3ProductViewImpl() = default;
|
~Impl() = default;
|
||||||
|
|
||||||
std::string product_;
|
std::string product_;
|
||||||
|
|
||||||
|
|
@ -61,8 +61,7 @@ public:
|
||||||
Level3ProductView::Level3ProductView(
|
Level3ProductView::Level3ProductView(
|
||||||
const std::string& product,
|
const std::string& product,
|
||||||
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
|
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
|
||||||
RadarProductView(radarProductManager),
|
RadarProductView(radarProductManager), p(std::make_unique<Impl>(product))
|
||||||
p(std::make_unique<Level3ProductViewImpl>(product))
|
|
||||||
{
|
{
|
||||||
ConnectRadarProductManager();
|
ConnectRadarProductManager();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ namespace qt
|
||||||
namespace view
|
namespace view
|
||||||
{
|
{
|
||||||
|
|
||||||
class Level3ProductViewImpl;
|
|
||||||
|
|
||||||
class Level3ProductView : public RadarProductView
|
class Level3ProductView : public RadarProductView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -52,7 +50,8 @@ protected:
|
||||||
void UpdateColorTable() override;
|
void UpdateColorTable() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Level3ProductViewImpl> p;
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> p;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace view
|
} // 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 VERTICES_PER_BIN = 6u;
|
||||||
static constexpr std::uint32_t VALUES_PER_VERTEX = 2u;
|
static constexpr std::uint32_t VALUES_PER_VERTEX = 2u;
|
||||||
|
|
||||||
class Level3RadialViewImpl
|
class Level3RadialView::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Level3RadialViewImpl(Level3RadialView* self) :
|
explicit Impl(Level3RadialView* self) :
|
||||||
self_ {self},
|
self_ {self},
|
||||||
latitude_ {},
|
latitude_ {},
|
||||||
longitude_ {},
|
longitude_ {},
|
||||||
|
|
@ -41,10 +41,10 @@ public:
|
||||||
{
|
{
|
||||||
coordinates_.resize(kMaxCoordinates_);
|
coordinates_.resize(kMaxCoordinates_);
|
||||||
}
|
}
|
||||||
~Level3RadialViewImpl() { threadPool_.join(); };
|
~Impl() { threadPool_.join(); };
|
||||||
|
|
||||||
void ComputeCoordinates(
|
void ComputeCoordinates(
|
||||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData);
|
const std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket>& radialData);
|
||||||
|
|
||||||
Level3RadialView* self_;
|
Level3RadialView* self_;
|
||||||
|
|
||||||
|
|
@ -54,6 +54,8 @@ public:
|
||||||
std::vector<float> vertices_ {};
|
std::vector<float> vertices_ {};
|
||||||
std::vector<std::uint8_t> dataMoments8_ {};
|
std::vector<std::uint8_t> dataMoments8_ {};
|
||||||
|
|
||||||
|
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> lastRadialData_ {};
|
||||||
|
|
||||||
float latitude_;
|
float latitude_;
|
||||||
float longitude_;
|
float longitude_;
|
||||||
float range_;
|
float range_;
|
||||||
|
|
@ -66,7 +68,7 @@ Level3RadialView::Level3RadialView(
|
||||||
const std::string& product,
|
const std::string& product,
|
||||||
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
|
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
|
||||||
Level3ProductView(product, radarProductManager),
|
Level3ProductView(product, radarProductManager),
|
||||||
p(std::make_unique<Level3RadialViewImpl>(this))
|
p(std::make_unique<Impl>(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,6 +237,8 @@ void Level3RadialView::ComputeSweep()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->lastRadialData_ = radialData;
|
||||||
|
|
||||||
// Valid number of radials is 1-720
|
// Valid number of radials is 1-720
|
||||||
size_t radials = radialData->number_of_radials();
|
size_t radials = radialData->number_of_radials();
|
||||||
if (radials < 1 || radials > 720)
|
if (radials < 1 || radials > 720)
|
||||||
|
|
@ -424,8 +428,8 @@ void Level3RadialView::ComputeSweep()
|
||||||
Q_EMIT SweepComputed();
|
Q_EMIT SweepComputed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level3RadialViewImpl::ComputeCoordinates(
|
void Level3RadialView::Impl::ComputeCoordinates(
|
||||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData)
|
const std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket>& radialData)
|
||||||
{
|
{
|
||||||
logger_->debug("ComputeCoordinates()");
|
logger_->debug("ComputeCoordinates()");
|
||||||
|
|
||||||
|
|
@ -485,6 +489,113 @@ void Level3RadialViewImpl::ComputeCoordinates(
|
||||||
logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws"));
|
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(
|
std::shared_ptr<Level3RadialView> Level3RadialView::Create(
|
||||||
const std::string& product,
|
const std::string& product,
|
||||||
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ namespace qt
|
||||||
namespace view
|
namespace view
|
||||||
{
|
{
|
||||||
|
|
||||||
class Level3RadialViewImpl;
|
|
||||||
|
|
||||||
class Level3RadialView : public Level3ProductView
|
class Level3RadialView : public Level3ProductView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -32,6 +30,8 @@ public:
|
||||||
|
|
||||||
std::tuple<const void*, std::size_t, std::size_t>
|
std::tuple<const void*, std::size_t, std::size_t>
|
||||||
GetMomentData() const override;
|
GetMomentData() const override;
|
||||||
|
std::optional<std::uint16_t>
|
||||||
|
GetBinLevel(const common::Coordinate& coordinate) const override;
|
||||||
|
|
||||||
static std::shared_ptr<Level3RadialView>
|
static std::shared_ptr<Level3RadialView>
|
||||||
Create(const std::string& product,
|
Create(const std::string& product,
|
||||||
|
|
@ -44,7 +44,8 @@ protected slots:
|
||||||
void ComputeSweep() override;
|
void ComputeSweep() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Level3RadialViewImpl> p;
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> p;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace view
|
} // namespace view
|
||||||
|
|
|
||||||
|
|
@ -352,6 +352,14 @@ void Level3RasterView::ComputeSweep()
|
||||||
Q_EMIT SweepComputed();
|
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(
|
std::shared_ptr<Level3RasterView> Level3RasterView::Create(
|
||||||
const std::string& product,
|
const std::string& product,
|
||||||
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
std::shared_ptr<manager::RadarProductManager> radarProductManager)
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ public:
|
||||||
|
|
||||||
std::tuple<const void*, std::size_t, std::size_t>
|
std::tuple<const void*, std::size_t, std::size_t>
|
||||||
GetMomentData() const override;
|
GetMomentData() const override;
|
||||||
|
std::optional<std::uint16_t>
|
||||||
|
GetBinLevel(const common::Coordinate& coordinate) const override;
|
||||||
|
|
||||||
static std::shared_ptr<Level3RasterView>
|
static std::shared_ptr<Level3RasterView>
|
||||||
Create(const std::string& product,
|
Create(const std::string& product,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <scwx/common/color_table.hpp>
|
#include <scwx/common/color_table.hpp>
|
||||||
|
#include <scwx/common/geographic.hpp>
|
||||||
#include <scwx/common/products.hpp>
|
#include <scwx/common/products.hpp>
|
||||||
#include <scwx/qt/manager/radar_product_manager.hpp>
|
#include <scwx/qt/manager/radar_product_manager.hpp>
|
||||||
#include <scwx/qt/types/map_types.hpp>
|
#include <scwx/qt/types/map_types.hpp>
|
||||||
|
|
@ -8,6 +9,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
@ -63,7 +65,9 @@ public:
|
||||||
virtual std::tuple<const void*, std::size_t, std::size_t>
|
virtual std::tuple<const void*, std::size_t, std::size_t>
|
||||||
GetMomentData() const = 0;
|
GetMomentData() const = 0;
|
||||||
virtual std::tuple<const void*, std::size_t, std::size_t>
|
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;
|
std::chrono::system_clock::time_point GetSelectedTime() const;
|
||||||
|
|
||||||
virtual std::vector<std::pair<std::string, std::string>>
|
virtual std::vector<std::pair<std::string, std::string>>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue