Placefile text statement support

- Merged place and text
- Todo: Custom fonts not yet supported
- Todo: End statements sometimes appear after "Text" or other items
- Todo: Support "Title" statement
This commit is contained in:
Dan Paulat 2023-07-21 00:26:42 -05:00
parent 9f5de14f6b
commit 48d71cc14d
3 changed files with 80 additions and 25 deletions

View file

@ -24,8 +24,9 @@ public:
explicit Impl(std::shared_ptr<MapContext> context) {}; explicit Impl(std::shared_ptr<MapContext> context) {};
~Impl() = default; ~Impl() = default;
void RenderPlace(const QMapLibreGL::CustomLayerRenderParameters& params, void
std::shared_ptr<gr::Placefile::PlaceDrawItem> place); RenderTextDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params,
std::shared_ptr<gr::Placefile::TextDrawItem> di);
void RenderText(const QMapLibreGL::CustomLayerRenderParameters& params, void RenderText(const QMapLibreGL::CustomLayerRenderParameters& params,
const std::string& text, const std::string& text,
@ -55,27 +56,26 @@ void PlacefileLayer::Initialize()
DrawLayer::Initialize(); DrawLayer::Initialize();
} }
void PlacefileLayer::Impl::RenderPlace( void PlacefileLayer::Impl::RenderTextDrawItem(
const QMapLibreGL::CustomLayerRenderParameters& params, const QMapLibreGL::CustomLayerRenderParameters& params,
std::shared_ptr<gr::Placefile::PlaceDrawItem> place) std::shared_ptr<gr::Placefile::TextDrawItem> di)
{ {
auto distance = util::GeographicLib::GetDistance( auto distance = util::GeographicLib::GetDistance(
params.latitude, params.longitude, place->latitude_, place->longitude_); params.latitude, params.longitude, di->latitude_, di->longitude_);
if (distance < place->threshold_) if (distance < di->threshold_)
{ {
const auto screenCoordinates = const auto screenCoordinates = (util::maplibre::LatLongToScreenCoordinate(
(util::maplibre::LatLongToScreenCoordinate( {di->latitude_, di->longitude_}) -
{place->latitude_, place->longitude_}) - mapScreenCoordLocation_) *
mapScreenCoordLocation_) * mapScale_;
mapScale_;
RenderText(params, RenderText(params,
place->text_, di->text_,
"", di->hoverText_,
place->color_, di->color_,
screenCoordinates.x + place->x_ + halfWidth_, screenCoordinates.x + di->x_ + halfWidth_,
screenCoordinates.y + place->y_ + halfHeight_); screenCoordinates.y + di->y_ + halfHeight_);
} }
} }
@ -146,11 +146,10 @@ void PlacefileLayer::Render(
{ {
switch (drawItem->itemType_) switch (drawItem->itemType_)
{ {
case gr::Placefile::ItemType::Place: case gr::Placefile::ItemType::Text:
p->RenderPlace( p->RenderTextDrawItem(
params, params,
std::static_pointer_cast<gr::Placefile::PlaceDrawItem>( std::static_pointer_cast<gr::Placefile::TextDrawItem>(drawItem));
drawItem));
break; break;
} }
} }

View file

@ -37,7 +37,6 @@ public:
enum class ItemType enum class ItemType
{ {
Place,
Icon, Icon,
Font, Font,
Text, Text,
@ -54,16 +53,18 @@ public:
boost::units::quantity<boost::units::si::length> threshold_ {}; boost::units::quantity<boost::units::si::length> threshold_ {};
}; };
struct PlaceDrawItem : DrawItem struct TextDrawItem : DrawItem
{ {
PlaceDrawItem() { itemType_ = ItemType::Place; } TextDrawItem() { itemType_ = ItemType::Text; }
boost::gil::rgba8_pixel_t color_ {}; boost::gil::rgba8_pixel_t color_ {};
double latitude_ {}; double latitude_ {};
double longitude_ {}; double longitude_ {};
double x_ {}; double x_ {};
double y_ {}; double y_ {};
std::size_t fontNumber_ {0u};
std::string text_ {}; std::string text_ {};
std::string hoverText_ {};
}; };
bool IsValid() const; bool IsValid() const;

View file

@ -48,6 +48,8 @@ public:
double& y); double& y);
void ProcessLine(const std::string& line); void ProcessLine(const std::string& line);
static void TrimQuotes(std::string& s);
std::chrono::seconds refresh_ {-1}; std::chrono::seconds refresh_ {-1};
// Parsing state // Parsing state
@ -243,7 +245,7 @@ void Placefile::Impl::ProcessLine(const std::string& line)
if (tokenList.size() >= 3) if (tokenList.size() >= 3)
{ {
std::shared_ptr<PlaceDrawItem> di = std::make_shared<PlaceDrawItem>(); std::shared_ptr<TextDrawItem> di = std::make_shared<TextDrawItem>();
di->threshold_ = threshold_; di->threshold_ = threshold_;
di->color_ = color_; di->color_ = color_;
@ -255,6 +257,7 @@ void Placefile::Impl::ProcessLine(const std::string& line)
di->x_, di->x_,
di->y_); di->y_);
ProcessEscapeCharacters(tokenList[2]);
di->text_.swap(tokenList[2]); di->text_.swap(tokenList[2]);
drawItems_.emplace_back(std::move(di)); drawItems_.emplace_back(std::move(di));
@ -285,8 +288,46 @@ void Placefile::Impl::ProcessLine(const std::string& line)
else if (boost::istarts_with(line, textKey_)) else if (boost::istarts_with(line, textKey_))
{ {
// Text: lat, lon, fontNumber, "string", "hover" // Text: lat, lon, fontNumber, "string", "hover"
std::vector<std::string> tokenList =
util::ParseTokens(line, {",", ",", ",", ",", ","}, textKey_.size());
// TODO std::shared_ptr<TextDrawItem> di = nullptr;
if (tokenList.size() >= 4)
{
di = std::make_shared<TextDrawItem>();
di->threshold_ = threshold_;
di->color_ = color_;
ParseLocation(tokenList[0],
tokenList[1],
di->latitude_,
di->longitude_,
di->x_,
di->y_);
di->fontNumber_ = std::stoul(tokenList[2]);
ProcessEscapeCharacters(tokenList[3]);
TrimQuotes(tokenList[3]);
di->text_.swap(tokenList[3]);
}
if (tokenList.size() >= 5)
{
ProcessEscapeCharacters(tokenList[4]);
TrimQuotes(tokenList[4]);
di->hoverText_.swap(tokenList[4]);
}
if (di != nullptr)
{
drawItems_.emplace_back(std::move(di));
}
else
{
logger_->warn("Text statement malformed: {}", line);
}
} }
else if (boost::istarts_with(line, objectKey_)) else if (boost::istarts_with(line, objectKey_))
{ {
@ -409,5 +450,19 @@ void Placefile::Impl::ParseLocation(const std::string& latitudeToken,
} }
} }
void Placefile::Impl::ProcessEscapeCharacters(std::string& s)
{
boost::replace_all(s, "\\n", "\n");
}
void Placefile::Impl::TrimQuotes(std::string& s)
{
if (s.size() >= 2 && s.front() == '"' && s.back() == '"')
{
s.erase(s.size() - 1);
s.erase(0, 1);
}
}
} // namespace gr } // namespace gr
} // namespace scwx } // namespace scwx