mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 21:00:05 +00:00
Finish parsing Storm Position / Forecast page
This commit is contained in:
parent
0415223571
commit
925f91995a
4 changed files with 127 additions and 9 deletions
|
|
@ -30,6 +30,8 @@ std::vector<std::string> ParseTokens(const std::string& s,
|
|||
|
||||
std::string ToString(const std::vector<std::string>& v);
|
||||
|
||||
std::optional<float> TryParseFloat(const std::string& str);
|
||||
|
||||
template<typename T>
|
||||
std::optional<T> TryParseUnsignedLong(const std::string& str);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,21 +22,21 @@ public:
|
|||
{
|
||||
struct Position
|
||||
{
|
||||
std::optional<units::angle::degrees<float>> azimuth_ {};
|
||||
std::optional<units::length::nautical_miles<float>> range_ {};
|
||||
std::optional<units::angle::degrees<std::uint16_t>> azimuth_ {};
|
||||
std::optional<units::length::nautical_miles<std::uint16_t>> range_ {};
|
||||
};
|
||||
|
||||
Position currentPosition_ {};
|
||||
std::optional<units::angle::degrees<float>> direction_;
|
||||
std::optional<units::velocity::knots<float>> speed_;
|
||||
Position currentPosition_ {};
|
||||
std::optional<units::angle::degrees<std::uint16_t>> direction_;
|
||||
std::optional<units::velocity::knots<std::uint16_t>> speed_;
|
||||
|
||||
std::array<Position, 4> forecastPosition_ {};
|
||||
|
||||
std::optional<units::length::nautical_miles<float>> forecastError_ {};
|
||||
std::optional<units::length::nautical_miles<float>> meanError_ {};
|
||||
|
||||
std::optional<std::int16_t> maxDbz_ {};
|
||||
std::optional<units::length::feet<float>> maxDbzHeight_ {};
|
||||
std::optional<std::int16_t> maxDbz_ {};
|
||||
std::optional<units::length::feet<std::uint32_t>> maxDbzHeight_ {};
|
||||
};
|
||||
|
||||
explicit StormTrackingInformationMessage();
|
||||
|
|
|
|||
|
|
@ -88,6 +88,21 @@ std::string ToString(const std::vector<std::string>& v)
|
|||
return value;
|
||||
}
|
||||
|
||||
std::optional<float> TryParseFloat(const std::string& str)
|
||||
{
|
||||
std::optional<float> value = std::nullopt;
|
||||
|
||||
try
|
||||
{
|
||||
value = static_cast<float>(std::stof(str));
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<T> TryParseUnsignedLong(const std::string& str)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -143,9 +143,110 @@ void StormTrackingInformationMessage::Impl::ParseStormPositionForecastPage(
|
|||
// clang-format on
|
||||
else if (i >= 7 && line.size() >= 80)
|
||||
{
|
||||
// TODO: STI Record
|
||||
std::string stormId = line.substr(2, 2);
|
||||
(void) (stormId);
|
||||
|
||||
if (std::isupper(stormId[0]) && std::isdigit(stormId[1]))
|
||||
{
|
||||
auto& record = stiRecords_[stormId];
|
||||
|
||||
if (record.currentPosition_.azimuth_ == std::nullopt)
|
||||
{
|
||||
// Current Position: Azimuth (Degrees)
|
||||
auto azimuth =
|
||||
util::TryParseUnsignedLong<std::uint16_t>(line.substr(9, 3));
|
||||
if (azimuth.has_value())
|
||||
{
|
||||
record.currentPosition_.azimuth_ =
|
||||
units::angle::degrees<std::uint16_t> {azimuth.value()};
|
||||
}
|
||||
}
|
||||
if (record.currentPosition_.range_ == std::nullopt)
|
||||
{
|
||||
// Current Position: Range (Nautical Miles)
|
||||
auto range =
|
||||
util::TryParseUnsignedLong<std::uint16_t>(line.substr(13, 3));
|
||||
if (range.has_value())
|
||||
{
|
||||
record.currentPosition_.range_ =
|
||||
units::length::nautical_miles<std::uint16_t> {
|
||||
range.value()};
|
||||
}
|
||||
}
|
||||
if (record.direction_ == std::nullopt)
|
||||
{
|
||||
// Movement: Direction (Degrees)
|
||||
auto direction =
|
||||
util::TryParseUnsignedLong<std::uint16_t>(line.substr(19, 3));
|
||||
if (direction.has_value())
|
||||
{
|
||||
record.direction_ =
|
||||
units::angle::degrees<std::uint16_t> {direction.value()};
|
||||
}
|
||||
}
|
||||
if (record.speed_ == std::nullopt)
|
||||
{
|
||||
// Movement: Speed (Knots)
|
||||
auto speed =
|
||||
util::TryParseUnsignedLong<std::uint16_t>(line.substr(23, 3));
|
||||
if (speed.has_value())
|
||||
{
|
||||
record.speed_ =
|
||||
units::velocity::knots<std::uint16_t> {speed.value()};
|
||||
}
|
||||
}
|
||||
for (std::size_t j = 0; j < record.forecastPosition_.size(); ++j)
|
||||
{
|
||||
const std::size_t positionOffset = j * 10;
|
||||
|
||||
if (record.forecastPosition_[j].azimuth_ == std::nullopt)
|
||||
{
|
||||
// Forecast Position: Azimuth (Degrees)
|
||||
std::size_t offset = 31 + positionOffset;
|
||||
|
||||
auto azimuth = util::TryParseUnsignedLong<std::uint16_t>(
|
||||
line.substr(offset, 3));
|
||||
if (azimuth.has_value())
|
||||
{
|
||||
record.forecastPosition_[j].azimuth_ =
|
||||
units::angle::degrees<std::uint16_t> {azimuth.value()};
|
||||
}
|
||||
}
|
||||
if (record.forecastPosition_[j].range_ == std::nullopt)
|
||||
{
|
||||
// Forecast Position: Range (Nautical Miles)
|
||||
std::size_t offset = 35 + positionOffset;
|
||||
|
||||
auto range = util::TryParseUnsignedLong<std::uint16_t>(
|
||||
line.substr(offset, 3));
|
||||
if (range.has_value())
|
||||
{
|
||||
record.forecastPosition_[j].range_ =
|
||||
units::length::nautical_miles<std::uint16_t> {
|
||||
range.value()};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (record.forecastError_ == std::nullopt)
|
||||
{
|
||||
// Forecast Error (Nautical Miles)
|
||||
auto forecastError = util::TryParseFloat(line.substr(71, 4));
|
||||
if (forecastError.has_value())
|
||||
{
|
||||
record.forecastError_ = units::length::nautical_miles<float> {
|
||||
forecastError.value()};
|
||||
}
|
||||
}
|
||||
if (record.meanError_ == std::nullopt)
|
||||
{
|
||||
// Mean Error (Nautical Miles)
|
||||
auto meanError = util::TryParseFloat(line.substr(76, 4));
|
||||
if (meanError.has_value())
|
||||
{
|
||||
record.meanError_ =
|
||||
units::length::nautical_miles<float> {meanError.value()};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue