diff --git a/wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp b/wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp new file mode 100644 index 00000000..3bf72966 --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rda/digital_radar_data.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rda +{ + +class DigitalRadarDataImpl; + +class DigitalRadarData : public Message +{ +public: + explicit DigitalRadarData(); + ~DigitalRadarData(); + + DigitalRadarData(const Message&) = delete; + DigitalRadarData& operator=(const DigitalRadarData&) = delete; + + DigitalRadarData(DigitalRadarData&&) noexcept; + DigitalRadarData& operator=(DigitalRadarData&&) noexcept; + + bool Parse(std::istream& is); + + static std::unique_ptr Create(MessageHeader&& header, + std::istream& is); + +private: + std::unique_ptr p; +}; + +} // namespace rda +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/include/scwx/wsr88d/rda/message.hpp b/wxdata/include/scwx/wsr88d/rda/message.hpp index 44b16a95..aef7cdb4 100644 --- a/wxdata/include/scwx/wsr88d/rda/message.hpp +++ b/wxdata/include/scwx/wsr88d/rda/message.hpp @@ -36,6 +36,18 @@ protected: bool ValidateMessage(std::istream& is, size_t bytesRead) const; +public: + virtual ~Message(); + + const MessageHeader& header() const; + + void set_header(MessageHeader&& header); + + virtual bool Parse(std::istream& is) = 0; + + static constexpr double ANGLE_DATA_SCALE = 0.005493125; + static constexpr double AZ_EL_RATE_DATA_SCALE = 0.001373291015625; + static void ReadBoolean(std::istream& is, bool& value) { std::string data(4, ' '); @@ -56,45 +68,43 @@ protected: } template - static void SwapFloatArray(std::array& arr) + static void SwapArray(std::array& arr, size_t size = _Size) { std::transform(std::execution::par_unseq, arr.begin(), - arr.end(), + arr.begin() + size, arr.begin(), [](float f) { return SwapFloat(f); }); } template - static void SwapUInt16Array(std::array& arr) + static void SwapArray(std::array& arr, size_t size = _Size) { std::transform(std::execution::par_unseq, arr.begin(), - arr.end(), + arr.begin() + size, arr.begin(), [](uint16_t u) { return ntohs(u); }); } + template + static void SwapArray(std::array& arr, size_t size = _Size) + { + std::transform(std::execution::par_unseq, + arr.begin(), + arr.begin() + size, + arr.begin(), + [](uint32_t u) { return ntohl(u); }); + } + template - static void SwapFloatMap(std::map& m) + static void SwapMap(std::map& m) { std::for_each(std::execution::par_unseq, m.begin(), m.end(), [](auto& p) { p.second = SwapFloat(p.second); }); } -public: - virtual ~Message(); - - const MessageHeader& header() const; - - void set_header(MessageHeader&& header); - - virtual bool Parse(std::istream& is) = 0; - - static constexpr double ANGLE_DATA_SCALE = 0.005493125; - static constexpr double AZ_EL_RATE_DATA_SCALE = 0.001373291015625; - private: std::unique_ptr p; }; diff --git a/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp b/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp new file mode 100644 index 00000000..6ddd425b --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rda/digital_radar_data.cpp @@ -0,0 +1,510 @@ +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rda +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rda::digital_radar_data] "; + +enum class DataBlockType +{ + Volume, + Elevation, + Radial, + MomentRef, + MomentVel, + MomentSw, + MomentZdr, + MomentPhi, + MomentRho, + MomentCfp, + Unknown +}; + +static const std::unordered_map strToDataBlock_ { + {"VOL", DataBlockType::Volume}, + {"ELV", DataBlockType::Elevation}, + {"RAD", DataBlockType::Radial}, + {"REF", DataBlockType::MomentRef}, + {"VEL", DataBlockType::MomentVel}, + {"SW ", DataBlockType::MomentSw}, + {"ZDR", DataBlockType::MomentZdr}, + {"PHI", DataBlockType::MomentPhi}, + {"RHO", DataBlockType::MomentRho}, + {"CFP", DataBlockType::MomentCfp}}; + +struct DataBlock +{ + explicit DataBlock(const std::string& dataBlockType, + const std::string& dataName) : + dataBlockType_ {dataBlockType}, dataName_ {dataName} + { + } + + std::string dataBlockType_; + std::string dataName_; +}; + +struct MomentDataBlock : DataBlock +{ + explicit MomentDataBlock(const std::string& dataBlockType, + const std::string& dataName) : + DataBlock(dataBlockType, dataName), + numberOfDataMomentGates_ {0}, + dataMomentRange_ {0}, + dataMomentRangeSampleInterval_ {0}, + tover_ {0}, + snrThreshold_ {0}, + controlFlags_ {0}, + dataWordSize_ {0}, + scale_ {0.0f}, + offset_ {0.0f} + { + } + + uint16_t numberOfDataMomentGates_; + uint16_t dataMomentRange_; + uint16_t dataMomentRangeSampleInterval_; + uint16_t tover_; + int16_t snrThreshold_; + uint8_t controlFlags_; + uint8_t dataWordSize_; + float scale_; + float offset_; + + static std::unique_ptr + Create(const std::string& dataBlockType, + const std::string& dataName, + std::istream& is) + { + std::unique_ptr p = + std::make_unique(dataBlockType, dataName); + + is.seekg(4, std::ios_base::cur); // 4-7 + is.read(reinterpret_cast(&p->numberOfDataMomentGates_), 2); // 8-9 + is.read(reinterpret_cast(&p->dataMomentRange_), 2); // 10-11 + is.read(reinterpret_cast(&p->dataMomentRangeSampleInterval_), + 2); // 12-13 + is.read(reinterpret_cast(&p->tover_), 2); // 14-15 + is.read(reinterpret_cast(&p->snrThreshold_), 2); // 16-17 + is.read(reinterpret_cast(&p->controlFlags_), 1); // 18 + is.read(reinterpret_cast(&p->dataWordSize_), 1); // 19 + is.read(reinterpret_cast(&p->scale_), 4); // 20-23 + is.read(reinterpret_cast(&p->offset_), 4); // 24-27 + + p->numberOfDataMomentGates_ = ntohs(p->numberOfDataMomentGates_); + p->dataMomentRange_ = ntohs(p->dataMomentRange_); + p->dataMomentRangeSampleInterval_ = + ntohs(p->dataMomentRangeSampleInterval_); + p->tover_ = ntohs(p->tover_); + p->snrThreshold_ = ntohs(p->snrThreshold_); + p->scale_ = Message::SwapFloat(p->scale_); + p->offset_ = Message::SwapFloat(p->offset_); + + // TODO: Moment gates + + return p; + } +}; + +struct VolumeDataBlock : DataBlock +{ + explicit VolumeDataBlock(const std::string& dataBlockType, + const std::string& dataName) : + DataBlock(dataBlockType, dataName), + lrtup_ {0}, + versionNumberMajor_ {0}, + versionNumberMinor_ {0}, + latitude_ {0.0f}, + longitude_ {0.0f}, + siteHeight_ {0}, + feedhornHeight_ {0}, + calibrationConstant_ {0.0f}, + horizontaShvTxPower_ {0.0f}, + verticalShvTxPower_ {0.0f}, + systemDifferentialReflectivity_ {0.0f}, + initialSystemDifferentialPhase_ {0.0f}, + volumeCoveragePatternNumber_ {0}, + processingStatus_ {0} + { + } + + uint16_t lrtup_; + uint8_t versionNumberMajor_; + uint8_t versionNumberMinor_; + float latitude_; + float longitude_; + int16_t siteHeight_; + uint16_t feedhornHeight_; + float calibrationConstant_; + float horizontaShvTxPower_; + float verticalShvTxPower_; + float systemDifferentialReflectivity_; + float initialSystemDifferentialPhase_; + uint16_t volumeCoveragePatternNumber_; + uint16_t processingStatus_; + + static std::unique_ptr + Create(const std::string& dataBlockType, + const std::string& dataName, + std::istream& is) + { + std::unique_ptr p = + std::make_unique(dataBlockType, dataName); + + is.read(reinterpret_cast(&p->lrtup_), 2); // 4-5 + is.read(reinterpret_cast(&p->versionNumberMajor_), 1); // 6 + is.read(reinterpret_cast(&p->versionNumberMinor_), 1); // 7 + is.read(reinterpret_cast(&p->latitude_), 4); // 8-11 + is.read(reinterpret_cast(&p->longitude_), 4); // 12-15 + is.read(reinterpret_cast(&p->siteHeight_), 2); // 16-17 + is.read(reinterpret_cast(&p->feedhornHeight_), 2); // 18-19 + is.read(reinterpret_cast(&p->calibrationConstant_), 4); // 20-23 + is.read(reinterpret_cast(&p->horizontaShvTxPower_), 4); // 24-27 + is.read(reinterpret_cast(&p->verticalShvTxPower_), 4); // 28-31 + is.read(reinterpret_cast(&p->systemDifferentialReflectivity_), + 4); // 32-35 + is.read(reinterpret_cast(&p->initialSystemDifferentialPhase_), + 4); // 36-39 + is.read(reinterpret_cast(&p->volumeCoveragePatternNumber_), + 2); // 40-41 + is.read(reinterpret_cast(&p->processingStatus_), 2); // 42-43 + + p->lrtup_ = ntohs(p->lrtup_); + p->latitude_ = Message::SwapFloat(p->latitude_); + p->longitude_ = Message::SwapFloat(p->longitude_); + p->siteHeight_ = ntohs(p->siteHeight_); + p->feedhornHeight_ = ntohs(p->feedhornHeight_); + p->calibrationConstant_ = Message::SwapFloat(p->calibrationConstant_); + p->horizontaShvTxPower_ = Message::SwapFloat(p->horizontaShvTxPower_); + p->verticalShvTxPower_ = Message::SwapFloat(p->verticalShvTxPower_); + p->systemDifferentialReflectivity_ = + Message::SwapFloat(p->systemDifferentialReflectivity_); + p->initialSystemDifferentialPhase_ = + Message::SwapFloat(p->initialSystemDifferentialPhase_); + p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_); + p->processingStatus_ = ntohs(p->processingStatus_); + + return p; + } +}; + +struct ElevationDataBlock : DataBlock +{ + explicit ElevationDataBlock(const std::string& dataBlockType, + const std::string& dataName) : + DataBlock(dataBlockType, dataName), + lrtup_ {0}, + atmos_ {0}, + calibrationConstant_ {0.0f} + { + } + + uint16_t lrtup_; + int16_t atmos_; + float calibrationConstant_; + + static std::unique_ptr + Create(const std::string& dataBlockType, + const std::string& dataName, + std::istream& is) + { + std::unique_ptr p = + std::make_unique(dataBlockType, dataName); + + is.read(reinterpret_cast(&p->lrtup_), 2); // 4-5 + is.read(reinterpret_cast(&p->atmos_), 2); // 6-7 + is.read(reinterpret_cast(&p->calibrationConstant_), 4); // 8-11 + + p->lrtup_ = ntohs(p->lrtup_); + p->atmos_ = ntohs(p->atmos_); + p->calibrationConstant_ = Message::SwapFloat(p->calibrationConstant_); + + return p; + } +}; + +struct RadialDataBlock : DataBlock +{ + explicit RadialDataBlock(const std::string& dataBlockType, + const std::string& dataName) : + DataBlock(dataBlockType, dataName), + lrtup_ {0}, + unambigiousRange_ {0}, + noiseLevelHorizontal_ {0.0f}, + noiseLevelVertical_ {0.0f}, + nyquistVelocity_ {0}, + radialFlags_ {0}, + calibrationConstantHorizontal_ {0.0f}, + calibrationConstantVertical_ {0.0f} + { + } + + uint16_t lrtup_; + uint16_t unambigiousRange_; + float noiseLevelHorizontal_; + float noiseLevelVertical_; + uint16_t nyquistVelocity_; + uint16_t radialFlags_; + float calibrationConstantHorizontal_; + float calibrationConstantVertical_; + + static std::unique_ptr + Create(const std::string& dataBlockType, + const std::string& dataName, + std::istream& is) + { + std::unique_ptr p = + std::make_unique(dataBlockType, dataName); + + is.read(reinterpret_cast(&p->lrtup_), 2); // 4-5 + is.read(reinterpret_cast(&p->unambigiousRange_), 2); // 6-7 + is.read(reinterpret_cast(&p->noiseLevelHorizontal_), 4); // 8-11 + is.read(reinterpret_cast(&p->noiseLevelVertical_), 4); // 12-15 + is.read(reinterpret_cast(&p->nyquistVelocity_), 2); // 16-17 + is.read(reinterpret_cast(&p->radialFlags_), 2); // 18-19 + is.read(reinterpret_cast(&p->calibrationConstantHorizontal_), + 4); // 20-23 + is.read(reinterpret_cast(&p->calibrationConstantVertical_), + 4); // 24-27 + + p->lrtup_ = ntohs(p->lrtup_); + p->unambigiousRange_ = ntohs(p->unambigiousRange_); + p->noiseLevelHorizontal_ = Message::SwapFloat(p->noiseLevelHorizontal_); + p->noiseLevelVertical_ = Message::SwapFloat(p->noiseLevelVertical_); + p->nyquistVelocity_ = ntohs(p->nyquistVelocity_); + p->radialFlags_ = ntohs(p->radialFlags_); + p->calibrationConstantHorizontal_ = + Message::SwapFloat(p->calibrationConstantHorizontal_); + p->calibrationConstantVertical_ = + Message::SwapFloat(p->calibrationConstantVertical_); + + return p; + } +}; + +class DigitalRadarDataImpl +{ +public: + explicit DigitalRadarDataImpl() : + radarIdentifier_ {}, + collectionTime_ {0}, + modifiedJulianDate_ {0}, + azimuthNumber_ {0}, + azimuthAngle_ {0.0f}, + compressionIndicator_ {0}, + radialLength_ {0}, + azimuthResolutionSpacing_ {0}, + radialStatus_ {0}, + elevationNumber_ {0}, + cutSectorNumber_ {0}, + elevationAngle_ {0.0f}, + radialSpotBlankingStatus_ {0}, + azimuthIndexingMode_ {0}, + dataBlockCount_ {0}, + dataBlockPointer_ {0}, + volumeDataBlock_ {nullptr}, + elevationDataBlock_ {nullptr}, + radialDataBlock_ {nullptr}, + momentRefDataBlock_ {nullptr}, + momentVelDataBlock_ {nullptr}, + momentSwDataBlock_ {nullptr}, + momentZdrDataBlock_ {nullptr}, + momentPhiDataBlock_ {nullptr}, + momentRhoDataBlock_ {nullptr}, + momentCfpDataBlock_ {nullptr} {}; + ~DigitalRadarDataImpl() = default; + + std::string radarIdentifier_; + uint32_t collectionTime_; + uint16_t modifiedJulianDate_; + uint16_t azimuthNumber_; + float azimuthAngle_; + uint8_t compressionIndicator_; + uint16_t radialLength_; + uint8_t azimuthResolutionSpacing_; + uint8_t radialStatus_; + uint8_t elevationNumber_; + uint8_t cutSectorNumber_; + float elevationAngle_; + uint8_t radialSpotBlankingStatus_; + uint8_t azimuthIndexingMode_; + uint16_t dataBlockCount_; + std::array dataBlockPointer_; + + std::unique_ptr volumeDataBlock_; + std::unique_ptr elevationDataBlock_; + std::unique_ptr radialDataBlock_; + std::unique_ptr momentRefDataBlock_; + std::unique_ptr momentVelDataBlock_; + std::unique_ptr momentSwDataBlock_; + std::unique_ptr momentZdrDataBlock_; + std::unique_ptr momentPhiDataBlock_; + std::unique_ptr momentRhoDataBlock_; + std::unique_ptr momentCfpDataBlock_; +}; + +DigitalRadarData::DigitalRadarData() : + Message(), p(std::make_unique()) +{ +} +DigitalRadarData::~DigitalRadarData() = default; + +DigitalRadarData::DigitalRadarData(DigitalRadarData&&) noexcept = default; +DigitalRadarData& +DigitalRadarData::operator=(DigitalRadarData&&) noexcept = default; + +bool DigitalRadarData::Parse(std::istream& is) +{ + BOOST_LOG_TRIVIAL(debug) + << logPrefix_ << "Parsing Digital Radar Data (Message Type 31)"; + + bool messageValid = true; + size_t bytesRead = 0; + + std::streampos isBegin = is.tellg(); + + p->radarIdentifier_.resize(4); + + is.read(&p->radarIdentifier_[0], 4); // 0-3 + is.read(reinterpret_cast(&p->collectionTime_), 4); // 4-7 + is.read(reinterpret_cast(&p->modifiedJulianDate_), 2); // 8-9 + is.read(reinterpret_cast(&p->azimuthNumber_), 2); // 10-11 + is.read(reinterpret_cast(&p->azimuthAngle_), 4); // 12-15 + is.read(reinterpret_cast(&p->compressionIndicator_), 1); // 16 + is.seekg(1, std::ios_base::cur); // 17 + is.read(reinterpret_cast(&p->radialLength_), 2); // 18-19 + is.read(reinterpret_cast(&p->azimuthResolutionSpacing_), 1); // 20 + is.read(reinterpret_cast(&p->radialStatus_), 1); // 21 + is.read(reinterpret_cast(&p->elevationNumber_), 1); // 22 + is.read(reinterpret_cast(&p->cutSectorNumber_), 1); // 23 + is.read(reinterpret_cast(&p->elevationAngle_), 4); // 24-27 + is.read(reinterpret_cast(&p->radialSpotBlankingStatus_), 1); // 28 + is.read(reinterpret_cast(&p->azimuthIndexingMode_), 1); // 29 + is.read(reinterpret_cast(&p->dataBlockCount_), 2); // 30-31 + + p->collectionTime_ = ntohl(p->collectionTime_); + p->modifiedJulianDate_ = ntohs(p->modifiedJulianDate_); + p->azimuthNumber_ = ntohs(p->azimuthNumber_); + p->azimuthAngle_ = SwapFloat(p->azimuthAngle_); + p->radialLength_ = ntohs(p->radialLength_); + p->elevationAngle_ = SwapFloat(p->elevationAngle_); + p->dataBlockCount_ = ntohs(p->dataBlockCount_); + + if (p->dataBlockCount_ < 4 || p->dataBlockCount_ > 10) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ + << "Invalid number of data blocks: " << p->dataBlockCount_; + p->dataBlockCount_ = 0; + messageValid = false; + } + if (p->compressionIndicator_ != 0) + { + BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Compression not supported"; + p->dataBlockCount_ = 0; + messageValid = false; + } + + is.read(reinterpret_cast(&p->dataBlockPointer_), + p->dataBlockCount_ * 4); + + SwapArray(p->dataBlockPointer_, p->dataBlockCount_); + + for (uint16_t b = 0; b < p->dataBlockCount_; ++b) + { + is.seekg(isBegin + std::streamoff(p->dataBlockPointer_[b]), + std::ios_base::beg); + + std::string dataBlockType(1, 0); + std::string dataName(3, 0); + + is.read(&dataBlockType[0], 1); + is.read(&dataName[0], 3); + + DataBlockType dataBlock = DataBlockType::Unknown; + try + { + dataBlock = strToDataBlock_.at(dataName); + } + catch (const std::exception&) + { + } + + switch (dataBlock) + { + case DataBlockType::Volume: + p->volumeDataBlock_ = + std::move(VolumeDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::Elevation: + p->elevationDataBlock_ = + std::move(ElevationDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::Radial: + p->radialDataBlock_ = + std::move(RadialDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentRef: + p->momentRefDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentVel: + p->momentVelDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentSw: + p->momentSwDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentZdr: + p->momentZdrDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentPhi: + p->momentPhiDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentRho: + p->momentRhoDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + case DataBlockType::MomentCfp: + p->momentCfpDataBlock_ = + std::move(MomentDataBlock::Create(dataBlockType, dataName, is)); + break; + default: + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Unknown data name: " << dataName; + break; + } + } + + is.seekg(isBegin, std::ios_base::beg); + if (!ValidateMessage(is, bytesRead)) + { + messageValid = false; + } + + return messageValid; +} + +std::unique_ptr +DigitalRadarData::Create(MessageHeader&& header, std::istream& is) +{ + std::unique_ptr message = + std::make_unique(); + message->set_header(std::move(header)); + message->Parse(is); + return message; +} + +} // namespace rda +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rda/message_factory.cpp b/wxdata/source/scwx/wsr88d/rda/message_factory.cpp index a3735bc1..243d53e3 100644 --- a/wxdata/source/scwx/wsr88d/rda/message_factory.cpp +++ b/wxdata/source/scwx/wsr88d/rda/message_factory.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,8 @@ static const std::unordered_map create_ { {3, PerformanceMaintenanceData::Create}, {5, VolumeCoveragePatternData::Create}, {15, ClutterFilterMap::Create}, - {18, RdaAdaptationData::Create}}; + {18, RdaAdaptationData::Create}, + {31, DigitalRadarData::Create}}; static std::vector messageData_; static size_t bufferedSize_; diff --git a/wxdata/source/scwx/wsr88d/rda/performance_maintenance_data.cpp b/wxdata/source/scwx/wsr88d/rda/performance_maintenance_data.cpp index 0dd7bfa6..b305aec6 100644 --- a/wxdata/source/scwx/wsr88d/rda/performance_maintenance_data.cpp +++ b/wxdata/source/scwx/wsr88d/rda/performance_maintenance_data.cpp @@ -2294,8 +2294,8 @@ bool PerformanceMaintenanceData::Parse(std::istream& is) p->transmitterRecyclingSummary_ = htons(p->transmitterRecyclingSummary_); p->transmitterInoperable_ = htons(p->transmitterInoperable_); p->transmitterAirFilter_ = htons(p->transmitterAirFilter_); - SwapUInt16Array(p->zeroTestBit_); - SwapUInt16Array(p->oneTestBit_); + SwapArray(p->zeroTestBit_); + SwapArray(p->oneTestBit_); p->xmtrSpipInterface_ = htons(p->xmtrSpipInterface_); p->transmitterSummaryStatus_ = htons(p->transmitterSummaryStatus_); p->transmitterRfPower_ = SwapFloat(p->transmitterRfPower_); diff --git a/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp b/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp index 016298df..bca58216 100644 --- a/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp +++ b/wxdata/source/scwx/wsr88d/rda/rda_adaptation_data.cpp @@ -1582,7 +1582,7 @@ bool RdaAdaptationData::Parse(std::istream& is) p->parkaz_ = SwapFloat(p->parkaz_); p->parkel_ = SwapFloat(p->parkel_); - SwapFloatArray(p->aFuelConv_); + SwapArray(p->aFuelConv_); p->aMinShelterTemp_ = SwapFloat(p->aMinShelterTemp_); p->aMaxShelterTemp_ = SwapFloat(p->aMaxShelterTemp_); @@ -1605,14 +1605,14 @@ bool RdaAdaptationData::Parse(std::istream& is) p->configChanNumber_ = ntohl(p->configChanNumber_); p->redundantChanConfig_ = ntohl(p->redundantChanConfig_); - SwapFloatArray(p->attenTable_); - SwapFloatMap(p->pathLosses_); + SwapArray(p->attenTable_); + SwapMap(p->pathLosses_); p->vTsCw_ = SwapFloat(p->vTsCw_); - SwapFloatArray(p->hRnscale_); - SwapFloatArray(p->atmos_); - SwapFloatArray(p->elIndex_); + SwapArray(p->hRnscale_); + SwapArray(p->atmos_); + SwapArray(p->elIndex_); p->tfreqMhz_ = ntohl(p->tfreqMhz_); p->baseDataTcn_ = SwapFloat(p->baseDataTcn_); @@ -1687,7 +1687,7 @@ bool RdaAdaptationData::Parse(std::istream& is) p->elInertia_ = SwapFloat(p->elInertia_); p->rvp8nvIwaveguideLength_ = ntohl(p->rvp8nvIwaveguideLength_); - SwapFloatArray(p->vRnscale_); + SwapArray(p->vRnscale_); p->velDataTover_ = SwapFloat(p->velDataTover_); p->widthDataTover_ = SwapFloat(p->widthDataTover_); diff --git a/wxdata/source/scwx/wsr88d/rda/rda_status_data.cpp b/wxdata/source/scwx/wsr88d/rda/rda_status_data.cpp index 92608937..249634c5 100644 --- a/wxdata/source/scwx/wsr88d/rda/rda_status_data.cpp +++ b/wxdata/source/scwx/wsr88d/rda/rda_status_data.cpp @@ -310,7 +310,7 @@ bool RdaStatusData::Parse(std::istream& is) p->transitionPowerSourceStatus_ = htons(p->transitionPowerSourceStatus_); p->rmsControlStatus_ = htons(p->rmsControlStatus_); p->performanceCheckStatus_ = htons(p->performanceCheckStatus_); - SwapUInt16Array(p->alarmCodes_); + SwapArray(p->alarmCodes_); p->signalProcessingOptions_ = htons(p->signalProcessingOptions_); p->statusVersion_ = htons(p->statusVersion_); diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index a76bbe0a..8c78f184 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -9,6 +9,7 @@ set(SRC_UTIL source/scwx/util/rangebuf.cpp set(HDR_WSR88D include/scwx/wsr88d/ar2v_file.hpp) set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp) set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp + include/scwx/wsr88d/rda/digital_radar_data.hpp include/scwx/wsr88d/rda/message.hpp include/scwx/wsr88d/rda/message_factory.hpp include/scwx/wsr88d/rda/message_header.hpp @@ -17,6 +18,7 @@ set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_map.hpp include/scwx/wsr88d/rda/rda_status_data.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 source/scwx/wsr88d/rda/message.cpp source/scwx/wsr88d/rda/message_factory.cpp source/scwx/wsr88d/rda/message_header.cpp