mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:40:05 +00:00
Parse coded information from text product content
This commit is contained in:
parent
8f3baaa7c3
commit
56cda08b0d
5 changed files with 115 additions and 9 deletions
|
|
@ -205,5 +205,18 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo)
|
|||
return dataValid;
|
||||
}
|
||||
|
||||
std::optional<CodedLocation> CodedLocation::Create(const StringRange& lines,
|
||||
const std::string& wfo)
|
||||
{
|
||||
std::optional<CodedLocation> location = std::make_optional<CodedLocation>();
|
||||
|
||||
if (!location->Parse(lines, wfo))
|
||||
{
|
||||
location.reset();
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
} // namespace awips
|
||||
} // namespace scwx
|
||||
|
|
|
|||
|
|
@ -234,5 +234,20 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines,
|
|||
return dataValid;
|
||||
}
|
||||
|
||||
std::optional<CodedTimeMotionLocation>
|
||||
CodedTimeMotionLocation::Create(const StringRange& lines,
|
||||
const std::string& wfo)
|
||||
{
|
||||
std::optional<CodedTimeMotionLocation> motion =
|
||||
std::make_optional<CodedTimeMotionLocation>();
|
||||
|
||||
if (!motion->Parse(lines, wfo))
|
||||
{
|
||||
motion.reset();
|
||||
}
|
||||
|
||||
return motion;
|
||||
}
|
||||
|
||||
} // namespace awips
|
||||
} // namespace scwx
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include <scwx/awips/text_product_message.hpp>
|
||||
#include <scwx/awips/coded_location.hpp>
|
||||
#include <scwx/awips/coded_time_motion_location.hpp>
|
||||
#include <scwx/awips/pvtec.hpp>
|
||||
#include <scwx/common/characters.hpp>
|
||||
#include <scwx/util/streams.hpp>
|
||||
|
|
@ -59,10 +61,15 @@ struct SegmentHeader
|
|||
|
||||
struct Segment
|
||||
{
|
||||
std::optional<SegmentHeader> header_;
|
||||
std::vector<std::string> productContent_;
|
||||
std::optional<SegmentHeader> header_;
|
||||
std::vector<std::string> productContent_;
|
||||
std::optional<CodedLocation> codedLocation_;
|
||||
std::optional<CodedTimeMotionLocation> codedMotion_;
|
||||
|
||||
Segment() : header_ {}, productContent_ {} {}
|
||||
Segment() :
|
||||
header_ {}, productContent_ {}, codedLocation_ {}, codedMotion_ {}
|
||||
{
|
||||
}
|
||||
|
||||
Segment(const Segment&) = delete;
|
||||
Segment& operator=(const Segment&) = delete;
|
||||
|
|
@ -71,9 +78,11 @@ struct Segment
|
|||
Segment& operator=(Segment&&) noexcept = default;
|
||||
};
|
||||
|
||||
static void ParseCodedInformation(std::shared_ptr<Segment> segment,
|
||||
const std::string& wfo);
|
||||
static std::vector<std::string> ParseProductContent(std::istream& is);
|
||||
void SkipBlankLines(std::istream& is);
|
||||
bool TryParseEndOfProduct(std::istream& is);
|
||||
static void SkipBlankLines(std::istream& is);
|
||||
static bool TryParseEndOfProduct(std::istream& is);
|
||||
static std::vector<std::string> TryParseMndHeader(std::istream& is);
|
||||
static std::vector<std::string> TryParseOverviewBlock(std::istream& is);
|
||||
static std::optional<SegmentHeader> TryParseSegmentHeader(std::istream& is);
|
||||
|
|
@ -156,6 +165,8 @@ bool TextProductMessage::Parse(std::istream& is)
|
|||
segment->productContent_ = ParseProductContent(is);
|
||||
SkipBlankLines(is);
|
||||
|
||||
ParseCodedInformation(segment, p->wmoHeader_->icao());
|
||||
|
||||
if (segment->header_.has_value() || !segment->productContent_.empty())
|
||||
{
|
||||
p->segments_.push_back(std::move(segment));
|
||||
|
|
@ -165,6 +176,58 @@ bool TextProductMessage::Parse(std::istream& is)
|
|||
return dataValid;
|
||||
}
|
||||
|
||||
void ParseCodedInformation(std::shared_ptr<Segment> segment,
|
||||
const std::string& wfo)
|
||||
{
|
||||
typedef std::vector<std::string>::const_iterator StringIterator;
|
||||
|
||||
std::vector<std::string>& productContent = segment->productContent_;
|
||||
|
||||
StringIterator codedLocationBegin = productContent.cend();
|
||||
StringIterator codedLocationEnd = productContent.cend();
|
||||
StringIterator codedMotionBegin = productContent.cend();
|
||||
StringIterator codedMotionEnd = productContent.cend();
|
||||
|
||||
for (auto it = productContent.cbegin(); it != productContent.cend(); ++it)
|
||||
{
|
||||
if (codedLocationBegin == productContent.cend() &&
|
||||
it->starts_with("LAT...LON"))
|
||||
{
|
||||
codedLocationBegin = it;
|
||||
}
|
||||
else if (codedLocationBegin != productContent.cend() &&
|
||||
codedLocationEnd == productContent.cend() &&
|
||||
!it->starts_with(" ") /* Continuation line */)
|
||||
{
|
||||
codedLocationEnd = it;
|
||||
}
|
||||
|
||||
if (codedMotionBegin == productContent.cend() &&
|
||||
it->starts_with("TIME...MOT...LOC"))
|
||||
{
|
||||
codedMotionBegin = it;
|
||||
}
|
||||
else if (codedMotionBegin != productContent.cend() &&
|
||||
codedMotionEnd == productContent.cend() &&
|
||||
!it->starts_with(" ") /* Continuation line */)
|
||||
{
|
||||
codedMotionEnd = it;
|
||||
}
|
||||
}
|
||||
|
||||
if (codedLocationBegin != productContent.cend())
|
||||
{
|
||||
segment->codedLocation_ =
|
||||
CodedLocation::Create({codedLocationBegin, codedLocationEnd}, wfo);
|
||||
}
|
||||
|
||||
if (codedMotionBegin != productContent.cend())
|
||||
{
|
||||
segment->codedMotion_ = CodedTimeMotionLocation::Create(
|
||||
{codedMotionBegin, codedMotionEnd}, wfo);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> ParseProductContent(std::istream& is)
|
||||
{
|
||||
std::vector<std::string> productContent;
|
||||
|
|
@ -367,8 +430,10 @@ std::optional<Vtec> TryParseVtecString(std::istream& is)
|
|||
|
||||
if (std::regex_search(line, rePVtecString))
|
||||
{
|
||||
vtec = Vtec();
|
||||
vtec->pVtec_.Parse(line);
|
||||
bool vtecValid;
|
||||
|
||||
vtec = Vtec();
|
||||
vtecValid = vtec->pVtec_.Parse(line);
|
||||
|
||||
isBegin = is.tellg();
|
||||
|
||||
|
|
@ -384,6 +449,11 @@ std::optional<Vtec> TryParseVtecString(std::istream& is)
|
|||
// the line
|
||||
is.seekg(isBegin, std::ios_base::beg);
|
||||
}
|
||||
|
||||
if (!vtecValid)
|
||||
{
|
||||
vtec.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue