mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:50:06 +00:00
Inherit DigitalRadarData from GenericRadarData
This commit is contained in:
parent
571d0b2ce9
commit
730c1a9ba7
2 changed files with 223 additions and 15 deletions
|
|
@ -1,9 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/wsr88d/rda/level2_message.hpp>
|
||||
|
||||
#include <units/angle.h>
|
||||
#include <units/length.h>
|
||||
#include <scwx/wsr88d/rda/generic_radar_data.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -12,7 +9,7 @@ namespace wsr88d
|
|||
namespace rda
|
||||
{
|
||||
|
||||
class DigitalRadarData : public Level2Message
|
||||
class DigitalRadarData : public GenericRadarData
|
||||
{
|
||||
public:
|
||||
explicit DigitalRadarData();
|
||||
|
|
@ -56,6 +53,9 @@ public:
|
|||
std::uint16_t tover() const;
|
||||
std::uint16_t radial_spot_blanking_status() const;
|
||||
|
||||
std::shared_ptr<GenericRadarData::MomentDataBlock>
|
||||
moment_data_block(DataBlockType type) const;
|
||||
|
||||
bool Parse(std::istream& is);
|
||||
|
||||
static std::shared_ptr<DigitalRadarData> Create(Level2MessageHeader&& header,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ constexpr float kRangeScale = 0.001f;
|
|||
class DigitalRadarData::Impl
|
||||
{
|
||||
public:
|
||||
class MomentDataBlock;
|
||||
|
||||
explicit Impl() {};
|
||||
~Impl() = default;
|
||||
|
||||
|
|
@ -49,13 +51,59 @@ public:
|
|||
std::uint16_t tover_ {};
|
||||
std::uint16_t radialSpotBlankingStatus_ {};
|
||||
|
||||
std::vector<std::uint8_t> reflectivity_ {};
|
||||
std::vector<std::uint8_t> dopplerVelocity_ {};
|
||||
std::vector<std::uint8_t> dopplerSpectrumWidth_ {};
|
||||
std::shared_ptr<MomentDataBlock> reflectivityDataBlock_ {nullptr};
|
||||
std::shared_ptr<MomentDataBlock> dopplerVelocityDataBlock_ {nullptr};
|
||||
std::shared_ptr<MomentDataBlock> dopplerSpectrumWidthDataBlock_ {nullptr};
|
||||
};
|
||||
|
||||
class DigitalRadarData::Impl::MomentDataBlock :
|
||||
public GenericRadarData::MomentDataBlock
|
||||
{
|
||||
public:
|
||||
explicit MomentDataBlock(const DigitalRadarData* self, DataBlockType type);
|
||||
~MomentDataBlock() = default;
|
||||
|
||||
MomentDataBlock(const MomentDataBlock&) = delete;
|
||||
MomentDataBlock& operator=(const MomentDataBlock&) = delete;
|
||||
|
||||
MomentDataBlock(MomentDataBlock&&) noexcept = default;
|
||||
MomentDataBlock& operator=(MomentDataBlock&&) noexcept = default;
|
||||
|
||||
std::uint16_t number_of_data_moment_gates() const;
|
||||
units::kilometers<float> data_moment_range() const;
|
||||
std::uint16_t data_moment_range_raw() const;
|
||||
units::kilometers<float> data_moment_range_sample_interval() const;
|
||||
std::uint16_t data_moment_range_sample_interval_raw() const;
|
||||
std::int16_t snr_threshold_raw() const;
|
||||
std::uint8_t data_word_size() const;
|
||||
float scale() const;
|
||||
float offset() const;
|
||||
const void* data_moments() const;
|
||||
|
||||
std::vector<std::uint8_t>& data_moment_vector() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
class DigitalRadarData::Impl::MomentDataBlock::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl() {};
|
||||
~Impl() = default;
|
||||
|
||||
std::uint16_t numberOfDataMomentGates_ {};
|
||||
std::uint16_t dataMomentRange_ {};
|
||||
std::uint16_t dataMomentRangeSampleInterval_ {};
|
||||
float scale_ {};
|
||||
float offset_ {};
|
||||
|
||||
std::vector<std::uint8_t> dataMoments_ {};
|
||||
};
|
||||
|
||||
DigitalRadarData::DigitalRadarData() :
|
||||
Level2Message(), p(std::make_unique<Impl>())
|
||||
GenericRadarData(), p(std::make_unique<Impl>())
|
||||
{
|
||||
}
|
||||
DigitalRadarData::~DigitalRadarData() = default;
|
||||
|
|
@ -222,6 +270,151 @@ std::uint16_t DigitalRadarData::radial_spot_blanking_status() const
|
|||
return p->radialSpotBlankingStatus_;
|
||||
}
|
||||
|
||||
std::shared_ptr<GenericRadarData::MomentDataBlock>
|
||||
DigitalRadarData::moment_data_block(DataBlockType type) const
|
||||
{
|
||||
std::shared_ptr<GenericRadarData::MomentDataBlock> block = nullptr;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DataBlockType::MomentRef:
|
||||
block = p->reflectivityDataBlock_;
|
||||
break;
|
||||
|
||||
case DataBlockType::MomentVel:
|
||||
block = p->dopplerVelocityDataBlock_;
|
||||
break;
|
||||
|
||||
case DataBlockType::MomentSw:
|
||||
block = p->dopplerSpectrumWidthDataBlock_;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
DigitalRadarData::Impl::MomentDataBlock::MomentDataBlock(
|
||||
const DigitalRadarData* self, DataBlockType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataBlockType::MomentRef:
|
||||
p->numberOfDataMomentGates_ = self->number_of_surveillance_bins();
|
||||
p->dataMomentRange_ = self->surveillance_range_raw();
|
||||
p->dataMomentRangeSampleInterval_ =
|
||||
self->surveillance_range_sample_interval_raw();
|
||||
|
||||
// Table III-E Base Data Scaling
|
||||
// Rnum = (R / 2) - 33.0
|
||||
p->scale_ = 2.0f;
|
||||
p->offset_ = 66.0f; // (33.0 * 2)
|
||||
break;
|
||||
|
||||
case DataBlockType::MomentVel:
|
||||
p->numberOfDataMomentGates_ = self->number_of_doppler_bins();
|
||||
p->dataMomentRange_ = self->doppler_range_raw();
|
||||
p->dataMomentRangeSampleInterval_ =
|
||||
self->doppler_range_sample_interval_raw();
|
||||
|
||||
// Table III-E Base Data Scaling
|
||||
if (self->doppler_velocity_resolution() == 2) // 2 = 0.5 m/s
|
||||
{
|
||||
// Vnum = (V / 2) - 64.5
|
||||
p->scale_ = 2.0f;
|
||||
p->offset_ = 129.0f; // (64.5 * 2)
|
||||
}
|
||||
else // 4 = 1.0 m/s
|
||||
{
|
||||
// Vnum = V - 129.0
|
||||
p->scale_ = 1.0f;
|
||||
p->offset_ = 129.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBlockType::MomentSw:
|
||||
p->numberOfDataMomentGates_ = self->number_of_doppler_bins();
|
||||
p->dataMomentRange_ = self->doppler_range_raw();
|
||||
p->dataMomentRangeSampleInterval_ =
|
||||
self->doppler_range_sample_interval_raw();
|
||||
|
||||
// Table III-E Base Data Scaling
|
||||
// SWnum = (SW / 2) - 64.5
|
||||
p->scale_ = 2.0f;
|
||||
p->offset_ = 129.0f; // (64.5 * 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::uint16_t
|
||||
DigitalRadarData::Impl::MomentDataBlock::number_of_data_moment_gates() const
|
||||
{
|
||||
return p->numberOfDataMomentGates_;
|
||||
}
|
||||
|
||||
units::kilometers<float>
|
||||
DigitalRadarData::Impl::MomentDataBlock::data_moment_range() const
|
||||
{
|
||||
return units::kilometers<float> {p->dataMomentRange_ * kRangeScale};
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
DigitalRadarData::Impl::MomentDataBlock::data_moment_range_raw() const
|
||||
{
|
||||
return p->dataMomentRange_;
|
||||
}
|
||||
|
||||
units::kilometers<float>
|
||||
DigitalRadarData::Impl::MomentDataBlock::data_moment_range_sample_interval()
|
||||
const
|
||||
{
|
||||
return units::kilometers<float> {p->dataMomentRangeSampleInterval_ *
|
||||
kRangeScale};
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
DigitalRadarData::Impl::MomentDataBlock::data_moment_range_sample_interval_raw()
|
||||
const
|
||||
{
|
||||
return p->dataMomentRangeSampleInterval_;
|
||||
}
|
||||
|
||||
std::int16_t DigitalRadarData::Impl::MomentDataBlock::snr_threshold_raw() const
|
||||
{
|
||||
// Table III Digital Radar Data (Message Type 1) Note 10:
|
||||
// Value of 00 (prior to scaling) is Signal Below Threshold, value of 01
|
||||
// (prior to scaling) is Signal Overlaid
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::uint8_t DigitalRadarData::Impl::MomentDataBlock::data_word_size() const
|
||||
{
|
||||
// Data moments are 8-bit for Digital Radar Data
|
||||
return 8;
|
||||
}
|
||||
|
||||
float DigitalRadarData::Impl::MomentDataBlock::scale() const
|
||||
{
|
||||
return p->scale_;
|
||||
}
|
||||
|
||||
float DigitalRadarData::Impl::MomentDataBlock::offset() const
|
||||
{
|
||||
return p->offset_;
|
||||
}
|
||||
|
||||
const void* DigitalRadarData::Impl::MomentDataBlock::data_moments() const
|
||||
{
|
||||
return p->dataMoments_.data();
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t>&
|
||||
DigitalRadarData::Impl::MomentDataBlock::data_moment_vector() const
|
||||
{
|
||||
return p->dataMoments_;
|
||||
}
|
||||
|
||||
bool DigitalRadarData::Parse(std::istream& is)
|
||||
{
|
||||
logger_->trace("Parsing Digital Radar Data (Message Type 1)");
|
||||
|
|
@ -337,31 +530,46 @@ bool DigitalRadarData::Parse(std::istream& is)
|
|||
|
||||
if (messageValid && p->surveillancePointer_ != 0)
|
||||
{
|
||||
p->reflectivityDataBlock_ = std::make_shared<Impl::MomentDataBlock>(
|
||||
this, DataBlockType::MomentRef);
|
||||
auto& reflectivity = p->reflectivityDataBlock_->data_moment_vector();
|
||||
|
||||
is.seekg(isBegin + std::streamoff(p->surveillancePointer_),
|
||||
std::ios_base::beg);
|
||||
|
||||
p->reflectivity_.resize(p->numberOfSurveillanceBins_);
|
||||
is.read(reinterpret_cast<char*>(p->reflectivity_.data()),
|
||||
reflectivity.resize(p->numberOfSurveillanceBins_);
|
||||
is.read(reinterpret_cast<char*>(reflectivity.data()),
|
||||
p->numberOfSurveillanceBins_);
|
||||
}
|
||||
|
||||
if (messageValid && p->velocityPointer_ != 0)
|
||||
{
|
||||
p->dopplerVelocityDataBlock_ = std::make_shared<Impl::MomentDataBlock>(
|
||||
this, DataBlockType::MomentVel);
|
||||
auto& dopplerVelocity =
|
||||
p->dopplerVelocityDataBlock_->data_moment_vector();
|
||||
|
||||
is.seekg(isBegin + std::streamoff(p->velocityPointer_),
|
||||
std::ios_base::beg);
|
||||
|
||||
p->dopplerVelocity_.resize(p->numberOfDopplerBins_);
|
||||
is.read(reinterpret_cast<char*>(p->dopplerVelocity_.data()),
|
||||
dopplerVelocity.resize(p->numberOfDopplerBins_);
|
||||
is.read(reinterpret_cast<char*>(dopplerVelocity.data()),
|
||||
p->numberOfDopplerBins_);
|
||||
}
|
||||
|
||||
if (messageValid && p->spectralWidthPointer_ != 0)
|
||||
{
|
||||
p->dopplerSpectrumWidthDataBlock_ =
|
||||
std::make_shared<Impl::MomentDataBlock>(this,
|
||||
DataBlockType::MomentVel);
|
||||
auto& dopplerSpectrumWidth =
|
||||
p->dopplerSpectrumWidthDataBlock_->data_moment_vector();
|
||||
|
||||
is.seekg(isBegin + std::streamoff(p->spectralWidthPointer_),
|
||||
std::ios_base::beg);
|
||||
|
||||
p->dopplerSpectrumWidth_.resize(p->numberOfDopplerBins_);
|
||||
is.read(reinterpret_cast<char*>(p->dopplerSpectrumWidth_.data()),
|
||||
dopplerSpectrumWidth.resize(p->numberOfDopplerBins_);
|
||||
is.read(reinterpret_cast<char*>(dopplerSpectrumWidth.data()),
|
||||
p->numberOfDopplerBins_);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue