mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 17:20:04 +00:00
Draw 4-bit encoded radial data
This commit is contained in:
parent
41b491314b
commit
8d1be0f54a
7 changed files with 158 additions and 25 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
#include <scwx/util/time.hpp>
|
#include <scwx/util/time.hpp>
|
||||||
#include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp>
|
#include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp>
|
||||||
#include <scwx/wsr88d/rpg/graphic_product_message.hpp>
|
#include <scwx/wsr88d/rpg/graphic_product_message.hpp>
|
||||||
|
#include <scwx/wsr88d/rpg/radial_data_packet.hpp>
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <boost/range/irange.hpp>
|
#include <boost/range/irange.hpp>
|
||||||
|
|
@ -322,8 +323,10 @@ void Level3RadialView::ComputeSweep()
|
||||||
|
|
||||||
// A message with radial data should either have a Digital Radial Data Array
|
// A message with radial data should either have a Digital Radial Data Array
|
||||||
// Packet, or a Radial Data Array Packet (TODO)
|
// Packet, or a Radial Data Array Packet (TODO)
|
||||||
std::shared_ptr<wsr88d::rpg::DigitalRadialDataArrayPacket> digitalData =
|
std::shared_ptr<wsr88d::rpg::DigitalRadialDataArrayPacket>
|
||||||
nullptr;
|
digitalDataPacket = nullptr;
|
||||||
|
std::shared_ptr<wsr88d::rpg::RadialDataPacket> radialDataPacket = nullptr;
|
||||||
|
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData = nullptr;
|
||||||
|
|
||||||
for (uint16_t layer = 0; layer < numberOfLayers; layer++)
|
for (uint16_t layer = 0; layer < numberOfLayers; layer++)
|
||||||
{
|
{
|
||||||
|
|
@ -332,40 +335,56 @@ void Level3RadialView::ComputeSweep()
|
||||||
|
|
||||||
for (auto it = packetList.begin(); it != packetList.end(); it++)
|
for (auto it = packetList.begin(); it != packetList.end(); it++)
|
||||||
{
|
{
|
||||||
digitalData = std::dynamic_pointer_cast<
|
// Prefer Digital Radial Data to Radial Data
|
||||||
|
digitalDataPacket = std::dynamic_pointer_cast<
|
||||||
wsr88d::rpg::DigitalRadialDataArrayPacket>(*it);
|
wsr88d::rpg::DigitalRadialDataArrayPacket>(*it);
|
||||||
|
|
||||||
if (digitalData != nullptr)
|
if (digitalDataPacket != nullptr)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Otherwise, check for Radial Data
|
||||||
|
if (radialDataPacket == nullptr)
|
||||||
|
{
|
||||||
|
radialDataPacket =
|
||||||
|
std::dynamic_pointer_cast<wsr88d::rpg::RadialDataPacket>(*it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (digitalData != nullptr)
|
if (digitalDataPacket != nullptr)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (digitalData == nullptr)
|
if (digitalDataPacket != nullptr)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
radialData = digitalDataPacket;
|
||||||
<< logPrefix_ << "No digital radial data array found";
|
}
|
||||||
|
else if (radialDataPacket != nullptr)
|
||||||
|
{
|
||||||
|
radialData = radialDataPacket;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "No radial data found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (digitalData->i_center_of_sweep() != 0 ||
|
// Check if radial data is centered on the radar location
|
||||||
digitalData->j_center_of_sweep() != 0)
|
if (radialData->i_center_of_sweep() != 0 ||
|
||||||
|
radialData->j_center_of_sweep() != 0)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
<< logPrefix_
|
<< logPrefix_
|
||||||
<< "(i, j) is not centered on radar, display is inaccurate: ("
|
<< "(i, j) is not centered on radar, display is inaccurate: ("
|
||||||
<< digitalData->i_center_of_sweep() << ", "
|
<< radialData->i_center_of_sweep() << ", "
|
||||||
<< digitalData->j_center_of_sweep() << ")";
|
<< radialData->j_center_of_sweep() << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume the number of radials should be 360 or 720
|
// Assume the number of radials should be 360 or 720
|
||||||
const size_t radials = digitalData->number_of_radials();
|
const size_t radials = radialData->number_of_radials();
|
||||||
if (radials != 360 && radials != 720)
|
if (radials != 360 && radials != 720)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
|
@ -381,7 +400,7 @@ void Level3RadialView::ComputeSweep()
|
||||||
p->radarProductManager_->coordinates(radialSize);
|
p->radarProductManager_->coordinates(radialSize);
|
||||||
|
|
||||||
// There should be a positive number of range bins in radial data
|
// There should be a positive number of range bins in radial data
|
||||||
const uint16_t gates = digitalData->number_of_range_bins();
|
const uint16_t gates = radialData->number_of_range_bins();
|
||||||
if (gates < 1)
|
if (gates < 1)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
|
|
@ -419,13 +438,12 @@ void Level3RadialView::ComputeSweep()
|
||||||
|
|
||||||
// Determine which radial to start at
|
// Determine which radial to start at
|
||||||
const float radialMultiplier = radials / 360.0f;
|
const float radialMultiplier = radials / 360.0f;
|
||||||
const float startAngle = digitalData->start_angle(0);
|
const float startAngle = radialData->start_angle(0);
|
||||||
const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier);
|
const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier);
|
||||||
|
|
||||||
for (uint16_t radial = 0; radial < digitalData->number_of_radials();
|
for (uint16_t radial = 0; radial < radialData->number_of_radials(); radial++)
|
||||||
radial++)
|
|
||||||
{
|
{
|
||||||
const auto dataMomentsArray8 = digitalData->level(radial);
|
const auto dataMomentsArray8 = radialData->level(radial);
|
||||||
|
|
||||||
// Compute gate interval
|
// Compute gate interval
|
||||||
const uint16_t dataMomentInterval = descriptionBlock->x_resolution_raw();
|
const uint16_t dataMomentInterval = descriptionBlock->x_resolution_raw();
|
||||||
|
|
@ -449,7 +467,8 @@ void Level3RadialView::ComputeSweep()
|
||||||
size_t vertexCount = (gate > 0) ? 6 : 3;
|
size_t vertexCount = (gate > 0) ? 6 : 3;
|
||||||
|
|
||||||
// Store data moment value
|
// Store data moment value
|
||||||
uint8_t dataValue = dataMomentsArray8[i];
|
uint8_t dataValue =
|
||||||
|
(i < dataMomentsArray8.size()) ? dataMomentsArray8[i] : 0;
|
||||||
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -457,7 +476,7 @@ void Level3RadialView::ComputeSweep()
|
||||||
|
|
||||||
for (size_t m = 0; m < vertexCount; m++)
|
for (size_t m = 0; m < vertexCount; m++)
|
||||||
{
|
{
|
||||||
dataMoments8[mIndex++] = dataMomentsArray8[i];
|
dataMoments8[mIndex++] = dataValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store vertices
|
// Store vertices
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <scwx/wsr88d/rpg/packet.hpp>
|
#include <scwx/wsr88d/rpg/generic_radial_data_packet.hpp>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -14,7 +14,7 @@ namespace rpg
|
||||||
|
|
||||||
class DigitalRadialDataArrayPacketImpl;
|
class DigitalRadialDataArrayPacketImpl;
|
||||||
|
|
||||||
class DigitalRadialDataArrayPacket : public Packet
|
class DigitalRadialDataArrayPacket : public GenericRadialDataPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DigitalRadialDataArrayPacket();
|
explicit DigitalRadialDataArrayPacket();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <scwx/wsr88d/rpg/packet.hpp>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace wsr88d
|
||||||
|
{
|
||||||
|
namespace rpg
|
||||||
|
{
|
||||||
|
|
||||||
|
class GenericRadialDataPacketImpl;
|
||||||
|
|
||||||
|
class GenericRadialDataPacket : public Packet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit GenericRadialDataPacket();
|
||||||
|
~GenericRadialDataPacket();
|
||||||
|
|
||||||
|
GenericRadialDataPacket(const GenericRadialDataPacket&) = delete;
|
||||||
|
GenericRadialDataPacket& operator=(const GenericRadialDataPacket&) = delete;
|
||||||
|
|
||||||
|
GenericRadialDataPacket(GenericRadialDataPacket&&) noexcept;
|
||||||
|
GenericRadialDataPacket& operator=(GenericRadialDataPacket&&) noexcept;
|
||||||
|
|
||||||
|
virtual int16_t i_center_of_sweep() const = 0;
|
||||||
|
virtual int16_t j_center_of_sweep() const = 0;
|
||||||
|
virtual uint16_t number_of_radials() const = 0;
|
||||||
|
virtual uint16_t number_of_range_bins() const = 0;
|
||||||
|
virtual float start_angle(uint16_t r) const = 0;
|
||||||
|
|
||||||
|
virtual const std::vector<uint8_t>& level(uint16_t r) const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<GenericRadialDataPacketImpl> p;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rpg
|
||||||
|
} // namespace wsr88d
|
||||||
|
} // namespace scwx
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <scwx/wsr88d/rpg/packet.hpp>
|
#include <scwx/wsr88d/rpg/generic_radial_data_packet.hpp>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -14,7 +14,7 @@ namespace rpg
|
||||||
|
|
||||||
class RadialDataPacketImpl;
|
class RadialDataPacketImpl;
|
||||||
|
|
||||||
class RadialDataPacket : public Packet
|
class RadialDataPacket : public GenericRadialDataPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit RadialDataPacket();
|
explicit RadialDataPacket();
|
||||||
|
|
@ -34,6 +34,10 @@ public:
|
||||||
float scale_factor() const;
|
float scale_factor() const;
|
||||||
uint16_t number_of_radials() const;
|
uint16_t number_of_radials() const;
|
||||||
|
|
||||||
|
float start_angle(uint16_t r) const;
|
||||||
|
float delta_angle(uint16_t r) const;
|
||||||
|
const std::vector<uint8_t>& level(uint16_t r) const;
|
||||||
|
|
||||||
size_t data_size() const override;
|
size_t data_size() const override;
|
||||||
|
|
||||||
bool Parse(std::istream& is) override;
|
bool Parse(std::istream& is) override;
|
||||||
|
|
|
||||||
37
wxdata/source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp
Normal file
37
wxdata/source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <scwx/wsr88d/rpg/generic_radial_data_packet.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace wsr88d
|
||||||
|
{
|
||||||
|
namespace rpg
|
||||||
|
{
|
||||||
|
|
||||||
|
static const std::string logPrefix_ =
|
||||||
|
"[scwx::wsr88d::rpg::generic_radial_data_packet] ";
|
||||||
|
|
||||||
|
class GenericRadialDataPacketImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit GenericRadialDataPacketImpl() = default;
|
||||||
|
~GenericRadialDataPacketImpl() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
GenericRadialDataPacket::GenericRadialDataPacket() :
|
||||||
|
p(std::make_unique<GenericRadialDataPacketImpl>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
GenericRadialDataPacket::~GenericRadialDataPacket() = default;
|
||||||
|
|
||||||
|
GenericRadialDataPacket::GenericRadialDataPacket(
|
||||||
|
GenericRadialDataPacket&&) noexcept = default;
|
||||||
|
GenericRadialDataPacket& GenericRadialDataPacket::operator=(
|
||||||
|
GenericRadialDataPacket&&) noexcept = default;
|
||||||
|
|
||||||
|
} // namespace rpg
|
||||||
|
} // namespace wsr88d
|
||||||
|
} // namespace scwx
|
||||||
|
|
@ -24,9 +24,14 @@ public:
|
||||||
uint16_t startAngle_;
|
uint16_t startAngle_;
|
||||||
uint16_t angleDelta_;
|
uint16_t angleDelta_;
|
||||||
std::vector<uint8_t> data_;
|
std::vector<uint8_t> data_;
|
||||||
|
std::vector<uint8_t> level_;
|
||||||
|
|
||||||
Radial() :
|
Radial() :
|
||||||
numberOfRleHalfwords_ {0}, startAngle_ {0}, angleDelta_ {0}, data_ {}
|
numberOfRleHalfwords_ {0},
|
||||||
|
startAngle_ {0},
|
||||||
|
angleDelta_ {0},
|
||||||
|
data_ {},
|
||||||
|
level_ {}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -103,6 +108,21 @@ uint16_t RadialDataPacket::number_of_radials() const
|
||||||
return p->numberOfRadials_;
|
return p->numberOfRadials_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float RadialDataPacket::start_angle(uint16_t r) const
|
||||||
|
{
|
||||||
|
return p->radial_[r].startAngle_ * 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RadialDataPacket::delta_angle(uint16_t r) const
|
||||||
|
{
|
||||||
|
return p->radial_[r].angleDelta_ * 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<uint8_t>& RadialDataPacket::level(uint16_t r) const
|
||||||
|
{
|
||||||
|
return p->radial_[r].level_;
|
||||||
|
}
|
||||||
|
|
||||||
size_t RadialDataPacket::data_size() const
|
size_t RadialDataPacket::data_size() const
|
||||||
{
|
{
|
||||||
return p->dataSize_;
|
return p->dataSize_;
|
||||||
|
|
@ -197,6 +217,14 @@ bool RadialDataPacket::Parse(std::istream& is)
|
||||||
{
|
{
|
||||||
radial.data_.pop_back();
|
radial.data_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
radial.level_.resize(radial.data_.size());
|
||||||
|
|
||||||
|
std::transform(std::execution::par_unseq,
|
||||||
|
radial.data_.cbegin(),
|
||||||
|
radial.data_.cend(),
|
||||||
|
radial.level_.begin(),
|
||||||
|
[](uint8_t data) -> uint8_t { return data & 0x0f; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp
|
||||||
include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp
|
include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp
|
||||||
include/scwx/wsr88d/rpg/general_status_message.hpp
|
include/scwx/wsr88d/rpg/general_status_message.hpp
|
||||||
include/scwx/wsr88d/rpg/generic_data_packet.hpp
|
include/scwx/wsr88d/rpg/generic_data_packet.hpp
|
||||||
|
include/scwx/wsr88d/rpg/generic_radial_data_packet.hpp
|
||||||
include/scwx/wsr88d/rpg/graphic_alphanumeric_block.hpp
|
include/scwx/wsr88d/rpg/graphic_alphanumeric_block.hpp
|
||||||
include/scwx/wsr88d/rpg/graphic_product_message.hpp
|
include/scwx/wsr88d/rpg/graphic_product_message.hpp
|
||||||
include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp
|
include/scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp
|
||||||
|
|
@ -118,6 +119,7 @@ set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/ccb_header.cpp
|
||||||
source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp
|
source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp
|
||||||
source/scwx/wsr88d/rpg/general_status_message.cpp
|
source/scwx/wsr88d/rpg/general_status_message.cpp
|
||||||
source/scwx/wsr88d/rpg/generic_data_packet.cpp
|
source/scwx/wsr88d/rpg/generic_data_packet.cpp
|
||||||
|
source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp
|
||||||
source/scwx/wsr88d/rpg/graphic_alphanumeric_block.cpp
|
source/scwx/wsr88d/rpg/graphic_alphanumeric_block.cpp
|
||||||
source/scwx/wsr88d/rpg/graphic_product_message.cpp
|
source/scwx/wsr88d/rpg/graphic_product_message.cpp
|
||||||
source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp
|
source/scwx/wsr88d/rpg/hda_hail_symbol_packet.cpp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue