mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:00:06 +00:00
Add Level 2 Message Type 1, Digital Radar Data
This commit is contained in:
parent
bfd7963d4c
commit
68cca50ddf
4 changed files with 422 additions and 1 deletions
62
wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp
Normal file
62
wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/wsr88d/rda/level2_message.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace wsr88d
|
||||
{
|
||||
namespace rda
|
||||
{
|
||||
|
||||
class DigitalRadarData : public Level2Message
|
||||
{
|
||||
public:
|
||||
explicit DigitalRadarData();
|
||||
~DigitalRadarData();
|
||||
|
||||
DigitalRadarData(const DigitalRadarData&) = delete;
|
||||
DigitalRadarData& operator=(const DigitalRadarData&) = delete;
|
||||
|
||||
DigitalRadarData(DigitalRadarData&&) noexcept;
|
||||
DigitalRadarData& operator=(DigitalRadarData&&) noexcept;
|
||||
|
||||
std::uint32_t collection_time() const;
|
||||
std::uint16_t modified_julian_date() const;
|
||||
std::uint16_t unambiguous_range() const;
|
||||
std::uint16_t azimuth_angle() const;
|
||||
std::uint16_t azimuth_number() const;
|
||||
std::uint16_t radial_status() const;
|
||||
std::uint16_t elevation_angle() const;
|
||||
std::uint16_t elevation_number() const;
|
||||
std::uint16_t surveillance_range() const;
|
||||
std::uint16_t doppler_range() const;
|
||||
std::uint16_t surveillance_range_sample_interval() const;
|
||||
std::uint16_t doppler_range_sample_interval() const;
|
||||
std::uint16_t number_of_surveillance_bins() const;
|
||||
std::uint16_t number_of_doppler_bins() const;
|
||||
std::uint16_t cut_sector_number() const;
|
||||
float calibration_constant() const;
|
||||
std::uint16_t surveillance_pointer() const;
|
||||
std::uint16_t velocity_pointer() const;
|
||||
std::uint16_t spectral_width_pointer() const;
|
||||
std::uint16_t doppler_velocity_resolution() const;
|
||||
std::uint16_t volume_coverage_pattern_number() const;
|
||||
std::uint16_t nyquist_velocity() const;
|
||||
std::uint16_t atmos() const;
|
||||
std::uint16_t tover() const;
|
||||
std::uint16_t radial_spot_blanking_status() const;
|
||||
|
||||
bool Parse(std::istream& is);
|
||||
|
||||
static std::shared_ptr<DigitalRadarData> Create(Level2MessageHeader&& header,
|
||||
std::istream& is);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace rda
|
||||
} // namespace wsr88d
|
||||
} // namespace scwx
|
||||
355
wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp
Normal file
355
wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
#include <scwx/wsr88d/rda/digital_radar_data.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace wsr88d
|
||||
{
|
||||
namespace rda
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::wsr88d::rda::digital_radar_data";
|
||||
static const auto logger_ = util::Logger::Create(logPrefix_);
|
||||
|
||||
class DigitalRadarData::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl() {};
|
||||
~Impl() = default;
|
||||
|
||||
std::uint32_t collectionTime_ {};
|
||||
std::uint16_t modifiedJulianDate_ {};
|
||||
std::uint16_t unambiguousRange_ {};
|
||||
std::uint16_t azimuthAngle_ {};
|
||||
std::uint16_t azimuthNumber_ {};
|
||||
std::uint16_t radialStatus_ {};
|
||||
std::uint16_t elevationAngle_ {};
|
||||
std::uint16_t elevationNumber_ {};
|
||||
std::uint16_t surveillanceRange_ {};
|
||||
std::uint16_t dopplerRange_ {};
|
||||
std::uint16_t surveillanceRangeSampleInterval_ {};
|
||||
std::uint16_t dopplerRangeSampleInterval_ {};
|
||||
std::uint16_t numberOfSurveillanceBins_ {};
|
||||
std::uint16_t numberOfDopplerBins_ {};
|
||||
std::uint16_t cutSectorNumber_ {};
|
||||
float calibrationConstant_ {};
|
||||
std::uint16_t surveillancePointer_ {};
|
||||
std::uint16_t velocityPointer_ {};
|
||||
std::uint16_t spectralWidthPointer_ {};
|
||||
std::uint16_t dopplerVelocityResolution_ {};
|
||||
std::uint16_t vcpNumber_ {};
|
||||
std::uint16_t nyquistVelocity_ {};
|
||||
std::uint16_t atmos_ {};
|
||||
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_ {};
|
||||
};
|
||||
|
||||
DigitalRadarData::DigitalRadarData() :
|
||||
Level2Message(), p(std::make_unique<Impl>())
|
||||
{
|
||||
}
|
||||
DigitalRadarData::~DigitalRadarData() = default;
|
||||
|
||||
DigitalRadarData::DigitalRadarData(DigitalRadarData&&) noexcept = default;
|
||||
DigitalRadarData&
|
||||
DigitalRadarData::operator=(DigitalRadarData&&) noexcept = default;
|
||||
|
||||
std::uint32_t DigitalRadarData::collection_time() const
|
||||
{
|
||||
return p->collectionTime_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::modified_julian_date() const
|
||||
{
|
||||
return p->modifiedJulianDate_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::unambiguous_range() const
|
||||
{
|
||||
return p->unambiguousRange_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::azimuth_angle() const
|
||||
{
|
||||
return p->azimuthAngle_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::azimuth_number() const
|
||||
{
|
||||
return p->azimuthNumber_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::radial_status() const
|
||||
{
|
||||
return p->radialStatus_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::elevation_angle() const
|
||||
{
|
||||
return p->elevationAngle_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::elevation_number() const
|
||||
{
|
||||
return p->elevationNumber_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::surveillance_range() const
|
||||
{
|
||||
return p->surveillanceRange_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::doppler_range() const
|
||||
{
|
||||
return p->dopplerRange_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::surveillance_range_sample_interval() const
|
||||
{
|
||||
return p->surveillanceRangeSampleInterval_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::doppler_range_sample_interval() const
|
||||
{
|
||||
return p->dopplerRangeSampleInterval_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::number_of_surveillance_bins() const
|
||||
{
|
||||
return p->numberOfSurveillanceBins_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::number_of_doppler_bins() const
|
||||
{
|
||||
return p->numberOfDopplerBins_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::cut_sector_number() const
|
||||
{
|
||||
return p->cutSectorNumber_;
|
||||
}
|
||||
|
||||
float DigitalRadarData::calibration_constant() const
|
||||
{
|
||||
return p->calibrationConstant_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::surveillance_pointer() const
|
||||
{
|
||||
return p->surveillancePointer_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::velocity_pointer() const
|
||||
{
|
||||
return p->velocityPointer_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::spectral_width_pointer() const
|
||||
{
|
||||
return p->spectralWidthPointer_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::doppler_velocity_resolution() const
|
||||
{
|
||||
return p->dopplerVelocityResolution_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::volume_coverage_pattern_number() const
|
||||
{
|
||||
return p->vcpNumber_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::nyquist_velocity() const
|
||||
{
|
||||
return p->nyquistVelocity_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::atmos() const
|
||||
{
|
||||
return p->atmos_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::tover() const
|
||||
{
|
||||
return p->tover_;
|
||||
}
|
||||
|
||||
std::uint16_t DigitalRadarData::radial_spot_blanking_status() const
|
||||
{
|
||||
return p->radialSpotBlankingStatus_;
|
||||
}
|
||||
|
||||
bool DigitalRadarData::Parse(std::istream& is)
|
||||
{
|
||||
logger_->trace("Parsing Digital Radar Data (Message Type 1)");
|
||||
|
||||
bool messageValid = true;
|
||||
std::size_t bytesRead = 0;
|
||||
|
||||
std::streampos isBegin = is.tellg();
|
||||
|
||||
is.read(reinterpret_cast<char*>(&p->collectionTime_), 4); // 0-3
|
||||
is.read(reinterpret_cast<char*>(&p->modifiedJulianDate_), 2); // 4-5
|
||||
is.read(reinterpret_cast<char*>(&p->unambiguousRange_), 2); // 6-7
|
||||
is.read(reinterpret_cast<char*>(&p->azimuthAngle_), 2); // 8-9
|
||||
is.read(reinterpret_cast<char*>(&p->azimuthNumber_), 2); // 10-11
|
||||
is.read(reinterpret_cast<char*>(&p->radialStatus_), 2); // 12-13
|
||||
is.read(reinterpret_cast<char*>(&p->elevationAngle_), 2); // 14-15
|
||||
is.read(reinterpret_cast<char*>(&p->elevationNumber_), 2); // 16-17
|
||||
is.read(reinterpret_cast<char*>(&p->surveillanceRange_), 2); // 18-19
|
||||
is.read(reinterpret_cast<char*>(&p->dopplerRange_), 2); // 20-21
|
||||
|
||||
is.read(reinterpret_cast<char*>(&p->surveillanceRangeSampleInterval_),
|
||||
2); // 22-23
|
||||
is.read(reinterpret_cast<char*>(&p->dopplerRangeSampleInterval_),
|
||||
2); // 24-25
|
||||
|
||||
is.read(reinterpret_cast<char*>(&p->numberOfSurveillanceBins_), 2); // 26-27
|
||||
is.read(reinterpret_cast<char*>(&p->numberOfDopplerBins_), 2); // 28-29
|
||||
is.read(reinterpret_cast<char*>(&p->cutSectorNumber_), 2); // 30-31
|
||||
is.read(reinterpret_cast<char*>(&p->calibrationConstant_), 4); // 32-35
|
||||
is.read(reinterpret_cast<char*>(&p->surveillancePointer_), 2); // 36-37
|
||||
is.read(reinterpret_cast<char*>(&p->velocityPointer_), 2); // 38-39
|
||||
is.read(reinterpret_cast<char*>(&p->spectralWidthPointer_), 2); // 40-41
|
||||
is.read(reinterpret_cast<char*>(&p->dopplerVelocityResolution_), 2); // 42-43
|
||||
is.read(reinterpret_cast<char*>(&p->vcpNumber_), 2); // 44-45
|
||||
is.seekg(14, std::ios_base::cur); // 46-59
|
||||
is.read(reinterpret_cast<char*>(&p->nyquistVelocity_), 2); // 60-61
|
||||
is.read(reinterpret_cast<char*>(&p->atmos_), 2); // 62-63
|
||||
is.read(reinterpret_cast<char*>(&p->tover_), 2); // 64-65
|
||||
is.read(reinterpret_cast<char*>(&p->radialSpotBlankingStatus_), 2); // 66-67
|
||||
is.seekg(32, std::ios_base::cur); // 68-99
|
||||
|
||||
p->collectionTime_ = ntohl(p->collectionTime_);
|
||||
p->modifiedJulianDate_ = ntohs(p->modifiedJulianDate_);
|
||||
p->unambiguousRange_ = ntohs(p->unambiguousRange_);
|
||||
p->azimuthAngle_ = ntohs(p->azimuthAngle_);
|
||||
p->azimuthNumber_ = ntohs(p->azimuthNumber_);
|
||||
p->radialStatus_ = ntohs(p->radialStatus_);
|
||||
p->elevationAngle_ = ntohs(p->elevationAngle_);
|
||||
p->elevationNumber_ = ntohs(p->elevationNumber_);
|
||||
p->surveillanceRange_ = ntohs(p->surveillanceRange_);
|
||||
p->dopplerRange_ = ntohs(p->dopplerRange_);
|
||||
|
||||
p->surveillanceRangeSampleInterval_ =
|
||||
ntohs(p->surveillanceRangeSampleInterval_);
|
||||
|
||||
p->dopplerRangeSampleInterval_ = ntohs(p->dopplerRangeSampleInterval_);
|
||||
p->numberOfSurveillanceBins_ = ntohs(p->numberOfSurveillanceBins_);
|
||||
p->numberOfDopplerBins_ = ntohs(p->numberOfDopplerBins_);
|
||||
p->cutSectorNumber_ = ntohs(p->cutSectorNumber_);
|
||||
p->calibrationConstant_ = SwapFloat(p->calibrationConstant_);
|
||||
p->surveillancePointer_ = ntohs(p->surveillancePointer_);
|
||||
p->velocityPointer_ = ntohs(p->velocityPointer_);
|
||||
p->spectralWidthPointer_ = ntohs(p->spectralWidthPointer_);
|
||||
p->dopplerVelocityResolution_ = ntohs(p->dopplerVelocityResolution_);
|
||||
p->vcpNumber_ = ntohs(p->vcpNumber_);
|
||||
p->nyquistVelocity_ = ntohs(p->nyquistVelocity_);
|
||||
p->atmos_ = ntohs(p->atmos_);
|
||||
p->tover_ = ntohs(p->tover_);
|
||||
p->radialSpotBlankingStatus_ = ntohs(p->radialSpotBlankingStatus_);
|
||||
|
||||
if (p->azimuthNumber_ < 1 || p->azimuthNumber_ > 400)
|
||||
{
|
||||
logger_->warn("Invalid azimuth number: {}", p->azimuthNumber_);
|
||||
messageValid = false;
|
||||
}
|
||||
if (p->elevationNumber_ < 1 || p->elevationNumber_ > 25)
|
||||
{
|
||||
logger_->warn("Invalid elevation number: {}", p->elevationNumber_);
|
||||
messageValid = false;
|
||||
}
|
||||
if (p->numberOfSurveillanceBins_ > 460)
|
||||
{
|
||||
logger_->warn("Invalid number of surveillance bins: {}",
|
||||
p->numberOfSurveillanceBins_);
|
||||
messageValid = false;
|
||||
}
|
||||
if (p->numberOfDopplerBins_ > 920)
|
||||
{
|
||||
logger_->warn("Invalid number of doppler bins: {}",
|
||||
p->numberOfDopplerBins_);
|
||||
messageValid = false;
|
||||
}
|
||||
if (p->surveillancePointer_ != 0 && p->surveillancePointer_ != 100)
|
||||
{
|
||||
logger_->warn("Invalid surveillance pointer: {}",
|
||||
p->surveillancePointer_);
|
||||
messageValid = false;
|
||||
}
|
||||
if (p->velocityPointer_ != 0 &&
|
||||
(p->velocityPointer_ < 100 || p->velocityPointer_ > 560))
|
||||
{
|
||||
logger_->warn("Invalid velocity pointer: {}", p->velocityPointer_);
|
||||
messageValid = false;
|
||||
}
|
||||
if (p->spectralWidthPointer_ != 0 &&
|
||||
(p->spectralWidthPointer_ < 100 || p->spectralWidthPointer_ > 1480 ||
|
||||
p->spectralWidthPointer_ > data_size()))
|
||||
{
|
||||
logger_->warn("Invalid spectral width pointer: {}",
|
||||
p->spectralWidthPointer_);
|
||||
messageValid = false;
|
||||
}
|
||||
|
||||
if (messageValid && p->surveillancePointer_ != 0)
|
||||
{
|
||||
is.seekg(isBegin + std::streamoff(p->surveillancePointer_),
|
||||
std::ios_base::beg);
|
||||
|
||||
p->reflectivity_.resize(p->numberOfSurveillanceBins_);
|
||||
is.read(reinterpret_cast<char*>(p->reflectivity_.data()),
|
||||
p->numberOfSurveillanceBins_);
|
||||
}
|
||||
|
||||
if (messageValid && p->velocityPointer_ != 0)
|
||||
{
|
||||
is.seekg(isBegin + std::streamoff(p->velocityPointer_),
|
||||
std::ios_base::beg);
|
||||
|
||||
p->dopplerVelocity_.resize(p->numberOfDopplerBins_);
|
||||
is.read(reinterpret_cast<char*>(p->dopplerVelocity_.data()),
|
||||
p->numberOfDopplerBins_);
|
||||
}
|
||||
|
||||
if (messageValid && p->spectralWidthPointer_ != 0)
|
||||
{
|
||||
is.seekg(isBegin + std::streamoff(p->spectralWidthPointer_),
|
||||
std::ios_base::beg);
|
||||
|
||||
p->dopplerSpectrumWidth_.resize(p->numberOfDopplerBins_);
|
||||
is.read(reinterpret_cast<char*>(p->dopplerSpectrumWidth_.data()),
|
||||
p->numberOfDopplerBins_);
|
||||
}
|
||||
|
||||
is.seekg(isBegin, std::ios_base::beg);
|
||||
if (!ValidateMessage(is, bytesRead))
|
||||
{
|
||||
messageValid = false;
|
||||
}
|
||||
|
||||
return messageValid;
|
||||
}
|
||||
|
||||
std::shared_ptr<DigitalRadarData>
|
||||
DigitalRadarData::Create(Level2MessageHeader&& header, std::istream& is)
|
||||
{
|
||||
std::shared_ptr<DigitalRadarData> message =
|
||||
std::make_shared<DigitalRadarData>();
|
||||
message->set_header(std::move(header));
|
||||
|
||||
if (!message->Parse(is))
|
||||
{
|
||||
message.reset();
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
} // namespace rda
|
||||
} // namespace wsr88d
|
||||
} // namespace scwx
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include <scwx/util/vectorbuf.hpp>
|
||||
#include <scwx/wsr88d/rda/clutter_filter_bypass_map.hpp>
|
||||
#include <scwx/wsr88d/rda/clutter_filter_map.hpp>
|
||||
#include <scwx/wsr88d/rda/digital_radar_data.hpp>
|
||||
#include <scwx/wsr88d/rda/digital_radar_data_generic.hpp>
|
||||
#include <scwx/wsr88d/rda/performance_maintenance_data.hpp>
|
||||
#include <scwx/wsr88d/rda/rda_adaptation_data.hpp>
|
||||
|
|
@ -29,7 +30,8 @@ typedef std::function<std::shared_ptr<Level2Message>(Level2MessageHeader&&,
|
|||
CreateLevel2MessageFunction;
|
||||
|
||||
static const std::unordered_map<unsigned int, CreateLevel2MessageFunction>
|
||||
create_ {{2, RdaStatusData::Create},
|
||||
create_ {{1, DigitalRadarData::Create},
|
||||
{2, RdaStatusData::Create},
|
||||
{3, PerformanceMaintenanceData::Create},
|
||||
{5, VolumeCoveragePatternData::Create},
|
||||
{13, ClutterFilterBypassMap::Create},
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp
|
|||
source/scwx/wsr88d/wsr88d_types.cpp)
|
||||
set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_bypass_map.hpp
|
||||
include/scwx/wsr88d/rda/clutter_filter_map.hpp
|
||||
include/scwx/wsr88d/rda/digital_radar_data.hpp
|
||||
include/scwx/wsr88d/rda/digital_radar_data_generic.hpp
|
||||
include/scwx/wsr88d/rda/level2_message.hpp
|
||||
include/scwx/wsr88d/rda/level2_message_factory.hpp
|
||||
|
|
@ -113,6 +114,7 @@ set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_bypass_map.hpp
|
|||
include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp)
|
||||
set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_bypass_map.cpp
|
||||
source/scwx/wsr88d/rda/clutter_filter_map.cpp
|
||||
source/scwx/wsr88d/rda/digital_radar_data.cpp
|
||||
source/scwx/wsr88d/rda/digital_radar_data_generic.cpp
|
||||
source/scwx/wsr88d/rda/level2_message.cpp
|
||||
source/scwx/wsr88d/rda/level2_message_factory.cpp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue