Store radar data in Ar2vFile object

This commit is contained in:
Dan Paulat 2021-06-27 10:20:32 -05:00
parent 79ab14ab95
commit a2c6ee70a4
18 changed files with 183 additions and 39 deletions

View file

@ -1,2 +1,8 @@
cmake_minimum_required(VERSION 3.11)
set_property(DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS
wxdata.cmake)
include(wxdata.cmake)

View file

@ -32,7 +32,7 @@ public:
bool Parse(std::istream& is);
static std::unique_ptr<ClutterFilterMap> Create(MessageHeader&& header,
static std::shared_ptr<ClutterFilterMap> Create(MessageHeader&& header,
std::istream& is);
static const size_t NUM_AZIMUTH_SEGMENTS = 360u;

View file

@ -41,7 +41,7 @@ public:
bool Parse(std::istream& is);
static std::unique_ptr<DigitalRadarData> Create(MessageHeader&& header,
static std::shared_ptr<DigitalRadarData> Create(MessageHeader&& header,
std::istream& is);
private:

View file

@ -11,7 +11,7 @@ namespace rda
struct MessageInfo
{
std::unique_ptr<Message> message;
std::shared_ptr<Message> message;
bool headerValid;
bool messageValid;

View file

@ -278,7 +278,7 @@ public:
bool Parse(std::istream& is);
static std::unique_ptr<PerformanceMaintenanceData>
static std::shared_ptr<PerformanceMaintenanceData>
Create(MessageHeader&& header, std::istream& is);
private:

View file

@ -203,7 +203,7 @@ public:
bool Parse(std::istream& is);
static std::unique_ptr<RdaAdaptationData> Create(MessageHeader&& header,
static std::shared_ptr<RdaAdaptationData> Create(MessageHeader&& header,
std::istream& is);
private:

View file

@ -55,7 +55,7 @@ public:
bool Parse(std::istream& is);
static std::unique_ptr<RdaStatusData> Create(MessageHeader&& header,
static std::shared_ptr<RdaStatusData> Create(MessageHeader&& header,
std::istream& is);
private:

View file

@ -0,0 +1,22 @@
#pragma once
namespace scwx
{
namespace wsr88d
{
namespace rda
{
enum class MessageId : uint8_t
{
RdaStatusData = 2,
PerformanceMaintenanceData = 3,
VolumeCoveragePatternData = 5,
ClutterFilterMap = 15,
RdaAdaptationData = 18,
DigitalRadarData = 31
};
} // namespace rda
} // namespace wsr88d
} // namespace scwx

View file

@ -77,7 +77,7 @@ public:
bool Parse(std::istream& is);
static std::unique_ptr<VolumeCoveragePatternData>
static std::shared_ptr<VolumeCoveragePatternData>
Create(MessageHeader&& header, std::istream& is);
private:

View file

@ -1,5 +1,8 @@
#include <scwx/wsr88d/ar2v_file.hpp>
#include <scwx/wsr88d/rda/digital_radar_data.hpp>
#include <scwx/wsr88d/rda/message_factory.hpp>
#include <scwx/wsr88d/rda/types.hpp>
#include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp>
#include <scwx/util/rangebuf.hpp>
#include <fstream>
@ -27,11 +30,16 @@ public:
milliseconds_ {0},
icao_(),
numRecords_ {0},
rawRecords_() {};
rawRecords_(),
vcpData_ {nullptr},
radarData_ {} {};
~Ar2vFileImpl() = default;
void HandleMessage(std::shared_ptr<rda::Message>& message);
void LoadLDMRecords(std::ifstream& f);
void ParseLDMRecords();
void ProcessRadarData(std::shared_ptr<rda::DigitalRadarData>& message);
void ProcessVcpData();
std::string tapeFilename_;
std::string extensionNumber_;
@ -41,6 +49,12 @@ public:
size_t numRecords_;
std::shared_ptr<rda::VolumeCoveragePatternData> vcpData_;
std::unordered_map<
uint16_t,
std::unordered_map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>>
radarData_;
std::list<std::stringstream> rawRecords_;
};
@ -182,6 +196,11 @@ void Ar2vFileImpl::ParseLDMRecords()
break;
}
if (msgInfo.messageValid)
{
HandleMessage(msgInfo.message);
}
off_t offset = 0;
uint16_t nextSize = 0u;
do
@ -206,5 +225,51 @@ void Ar2vFileImpl::ParseLDMRecords()
}
}
void Ar2vFileImpl::HandleMessage(std::shared_ptr<rda::Message>& message)
{
switch (message->header().message_type())
{
case static_cast<uint8_t>(rda::MessageId::VolumeCoveragePatternData):
vcpData_ =
std::static_pointer_cast<rda::VolumeCoveragePatternData>(message);
ProcessVcpData();
break;
case static_cast<uint8_t>(rda::MessageId::DigitalRadarData):
ProcessRadarData(
std::static_pointer_cast<rda::DigitalRadarData>(message));
break;
default: break;
}
}
void Ar2vFileImpl::ProcessRadarData(
std::shared_ptr<rda::DigitalRadarData>& message)
{
uint16_t azimuthIndex = message->azimuth_number() - 1;
uint16_t elevationIndex = message->elevation_number() - 1;
radarData_[elevationIndex][azimuthIndex] = message;
}
void Ar2vFileImpl::ProcessVcpData()
{
uint16_t numberOfElevationCuts = vcpData_->number_of_elevation_cuts();
radarData_.reserve(numberOfElevationCuts);
for (uint16_t e = 0; e < numberOfElevationCuts; ++e)
{
if (vcpData_->half_degree_azimuth(e))
{
radarData_[e].reserve(720);
}
else
{
radarData_[e].reserve(360);
}
}
}
} // namespace wsr88d
} // namespace scwx

View file

@ -186,13 +186,18 @@ bool ClutterFilterMap::Parse(std::istream& is)
return messageValid;
}
std::unique_ptr<ClutterFilterMap>
std::shared_ptr<ClutterFilterMap>
ClutterFilterMap::Create(MessageHeader&& header, std::istream& is)
{
std::unique_ptr<ClutterFilterMap> message =
std::make_unique<ClutterFilterMap>();
std::shared_ptr<ClutterFilterMap> message =
std::make_shared<ClutterFilterMap>();
message->set_header(std::move(header));
message->Parse(is);
if (!message->Parse(is))
{
message.reset();
}
return message;
}

View file

@ -501,19 +501,34 @@ bool DigitalRadarData::Parse(std::istream& is)
p->elevationAngle_ = SwapFloat(p->elevationAngle_);
p->dataBlockCount_ = ntohs(p->dataBlockCount_);
if (p->azimuthNumber_ < 1 || p->azimuthNumber_ > 720)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid azimuth number: " << p->azimuthNumber_;
messageValid = false;
}
if (p->elevationNumber_ < 1 || p->elevationNumber_ > 32)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Invalid elevation number: " << p->elevationNumber_;
messageValid = false;
}
if (p->dataBlockCount_ < 4 || p->dataBlockCount_ > 10)
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_
<< "Invalid number of data blocks: " << p->dataBlockCount_;
p->dataBlockCount_ = 0;
messageValid = false;
messageValid = false;
}
if (p->compressionIndicator_ != 0)
{
BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Compression not supported";
messageValid = false;
}
if (!messageValid)
{
p->dataBlockCount_ = 0;
messageValid = false;
}
is.read(reinterpret_cast<char*>(&p->dataBlockPointer_),
@ -599,13 +614,18 @@ bool DigitalRadarData::Parse(std::istream& is)
return messageValid;
}
std::unique_ptr<DigitalRadarData>
std::shared_ptr<DigitalRadarData>
DigitalRadarData::Create(MessageHeader&& header, std::istream& is)
{
std::unique_ptr<DigitalRadarData> message =
std::make_unique<DigitalRadarData>();
std::shared_ptr<DigitalRadarData> message =
std::make_shared<DigitalRadarData>();
message->set_header(std::move(header));
message->Parse(is);
if (!message->Parse(is))
{
message.reset();
}
return message;
}

View file

@ -22,7 +22,7 @@ namespace rda
static const std::string logPrefix_ = "[scwx::wsr88d::rda::message_factory] ";
typedef std::function<std::unique_ptr<Message>(MessageHeader&&, std::istream&)>
typedef std::function<std::shared_ptr<Message>(MessageHeader&&, std::istream&)>
CreateMessageFunction;
static const std::unordered_map<uint8_t, CreateMessageFunction> create_ {
@ -133,6 +133,11 @@ MessageInfo MessageFactory::Create(std::istream& is)
std::ios_base::cur);
}
if (info.message == nullptr)
{
info.messageValid = false;
}
return info;
}

View file

@ -2468,13 +2468,18 @@ bool PerformanceMaintenanceData::Parse(std::istream& is)
return messageValid;
}
std::unique_ptr<PerformanceMaintenanceData>
std::shared_ptr<PerformanceMaintenanceData>
PerformanceMaintenanceData::Create(MessageHeader&& header, std::istream& is)
{
std::unique_ptr<PerformanceMaintenanceData> message =
std::make_unique<PerformanceMaintenanceData>();
std::shared_ptr<PerformanceMaintenanceData> message =
std::make_shared<PerformanceMaintenanceData>();
message->set_header(std::move(header));
message->Parse(is);
if (!message->Parse(is))
{
message.reset();
}
return message;
}

View file

@ -1746,13 +1746,18 @@ bool RdaAdaptationData::Parse(std::istream& is)
return messageValid;
}
std::unique_ptr<RdaAdaptationData>
std::shared_ptr<RdaAdaptationData>
RdaAdaptationData::Create(MessageHeader&& header, std::istream& is)
{
std::unique_ptr<RdaAdaptationData> message =
std::make_unique<RdaAdaptationData>();
std::shared_ptr<RdaAdaptationData> message =
std::make_shared<RdaAdaptationData>();
message->set_header(std::move(header));
message->Parse(is);
if (!message->Parse(is))
{
message.reset();
}
return message;
}

View file

@ -322,12 +322,17 @@ bool RdaStatusData::Parse(std::istream& is)
return messageValid;
}
std::unique_ptr<RdaStatusData> RdaStatusData::Create(MessageHeader&& header,
std::shared_ptr<RdaStatusData> RdaStatusData::Create(MessageHeader&& header,
std::istream& is)
{
std::unique_ptr<RdaStatusData> message = std::make_unique<RdaStatusData>();
std::shared_ptr<RdaStatusData> message = std::make_shared<RdaStatusData>();
message->set_header(std::move(header));
message->Parse(is);
if (!message->Parse(is))
{
message.reset();
}
return message;
}

View file

@ -236,22 +236,22 @@ uint8_t VolumeCoveragePatternData::super_resolution_control(uint16_t e) const
bool VolumeCoveragePatternData::half_degree_azimuth(uint16_t e) const
{
return p->elevationCuts_[e].superResolutionControl_ & 0x0001;
return p->elevationCuts_[e].superResolutionControl_ & 0x01;
}
bool VolumeCoveragePatternData::quarter_km_reflectivity(uint16_t e) const
{
return p->elevationCuts_[e].superResolutionControl_ & 0x0002;
return p->elevationCuts_[e].superResolutionControl_ & 0x02;
}
bool VolumeCoveragePatternData::doppler_to_300km(uint16_t e) const
{
return p->elevationCuts_[e].superResolutionControl_ & 0x0004;
return p->elevationCuts_[e].superResolutionControl_ & 0x04;
}
bool VolumeCoveragePatternData::dual_polarization_to_300km(uint16_t e) const
{
return p->elevationCuts_[e].superResolutionControl_ & 0x0008;
return p->elevationCuts_[e].superResolutionControl_ & 0x08;
}
uint8_t VolumeCoveragePatternData::surveillance_prf_number(uint16_t e) const
@ -484,13 +484,18 @@ bool VolumeCoveragePatternData::Parse(std::istream& is)
return messageValid;
}
std::unique_ptr<VolumeCoveragePatternData>
std::shared_ptr<VolumeCoveragePatternData>
VolumeCoveragePatternData::Create(MessageHeader&& header, std::istream& is)
{
std::unique_ptr<VolumeCoveragePatternData> message =
std::make_unique<VolumeCoveragePatternData>();
std::shared_ptr<VolumeCoveragePatternData> message =
std::make_shared<VolumeCoveragePatternData>();
message->set_header(std::move(header));
message->Parse(is);
if (!message->Parse(is))
{
message.reset();
}
return message;
}

View file

@ -16,6 +16,7 @@ set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp
include/scwx/wsr88d/rda/performance_maintenance_data.hpp
include/scwx/wsr88d/rda/rda_adaptation_data.hpp
include/scwx/wsr88d/rda/rda_status_data.hpp
include/scwx/wsr88d/rda/types.hpp
include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp)
set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_map.cpp
source/scwx/wsr88d/rda/digital_radar_data.cpp