mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 04:53:36 +00:00
[indexer] Support for road shield parsing by highway class
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
This commit is contained in:
@@ -353,7 +353,7 @@ void RuleDrawer::ProcessLineStyle(FeatureType & f, Stylist const & s, TInsertSha
|
||||
df::RoadClass m_roadClass;
|
||||
};
|
||||
static Checker const checkers[] = {
|
||||
{{HighwayClass::Trunk, HighwayClass::Primary}, kRoadClass0ZoomLevel, df::RoadClass::Class0},
|
||||
{{HighwayClass::Motorway, HighwayClass::Trunk, HighwayClass::Primary}, kRoadClass0ZoomLevel, df::RoadClass::Class0},
|
||||
{{HighwayClass::Secondary, HighwayClass::Tertiary}, kRoadClass1ZoomLevel, df::RoadClass::Class1},
|
||||
{{HighwayClass::LivingStreet, HighwayClass::Service, HighwayClass::ServiceMinor},
|
||||
kRoadClass2ZoomLevel,
|
||||
|
||||
@@ -30,8 +30,8 @@ public:
|
||||
m_map[c.GetTypeByPath({"route", "ferry"})] = HighwayClass::Transported;
|
||||
m_map[c.GetTypeByPath({"route", "shuttle_train"})] = HighwayClass::Transported;
|
||||
|
||||
m_map[c.GetTypeByPath({"highway", "motorway"})] = HighwayClass::Trunk;
|
||||
m_map[c.GetTypeByPath({"highway", "motorway_link"})] = HighwayClass::Trunk;
|
||||
m_map[c.GetTypeByPath({"highway", "motorway"})] = HighwayClass::Motorway;
|
||||
m_map[c.GetTypeByPath({"highway", "motorway_link"})] = HighwayClass::Motorway;
|
||||
m_map[c.GetTypeByPath({"highway", "trunk"})] = HighwayClass::Trunk;
|
||||
m_map[c.GetTypeByPath({"highway", "trunk_link"})] = HighwayClass::Trunk;
|
||||
|
||||
@@ -83,6 +83,7 @@ char const * HighwayClassToString(HighwayClass const cls)
|
||||
{
|
||||
case HighwayClass::Undefined: return "Undefined";
|
||||
case HighwayClass::Transported: return "Transported";
|
||||
case HighwayClass::Motorway: return "Motorway";
|
||||
case HighwayClass::Trunk: return "Trunk";
|
||||
case HighwayClass::Primary: return "Primary";
|
||||
case HighwayClass::Secondary: return "Secondary";
|
||||
|
||||
@@ -674,6 +674,7 @@ uint64_t GetPopulationByRadius(double r);
|
||||
enum class HighwayClass
|
||||
{
|
||||
Undefined = 0, // There has not been any attempt of calculating HighwayClass.
|
||||
Motorway,
|
||||
Trunk,
|
||||
Primary,
|
||||
Secondary,
|
||||
|
||||
@@ -107,7 +107,7 @@ UNIT_TEST(GetHighwayClassTest)
|
||||
|
||||
feature::TypesHolder types2;
|
||||
types2.Add(c.GetTypeByPath({"highway", "motorway_link", "tunnel"}));
|
||||
TEST_EQUAL(ftypes::GetHighwayClass(types2), ftypes::HighwayClass::Trunk, ());
|
||||
TEST_EQUAL(ftypes::GetHighwayClass(types2), ftypes::HighwayClass::Motorway, ());
|
||||
|
||||
feature::TypesHolder types3;
|
||||
types3.Add(c.GetTypeByPath({"highway", "unclassified"}));
|
||||
|
||||
@@ -94,7 +94,7 @@ class RoadShieldParser
|
||||
public:
|
||||
explicit RoadShieldParser(std::string const & baseRoadNumber) : m_baseRoadNumber(baseRoadNumber) {}
|
||||
virtual ~RoadShieldParser() = default;
|
||||
virtual RoadShield ParseRoadShield(std::string_view rawText) const = 0;
|
||||
virtual RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const = 0;
|
||||
|
||||
RoadShieldType FindNetworkShield(std::string network) const
|
||||
{
|
||||
@@ -128,17 +128,19 @@ public:
|
||||
{
|
||||
RoadShieldsSetT result, defaultShields;
|
||||
|
||||
uint8_t index = 0;
|
||||
strings::Tokenize(m_baseRoadNumber, ";", [&](std::string_view rawText)
|
||||
{
|
||||
++index;
|
||||
RoadShield shield;
|
||||
auto slashPos = rawText.find('/');
|
||||
if (slashPos == std::string::npos)
|
||||
{
|
||||
shield = ParseRoadShield(rawText);
|
||||
shield = ParseRoadShield(rawText, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
shield = ParseRoadShield(rawText.substr(slashPos + 1));
|
||||
shield = ParseRoadShield(rawText.substr(slashPos + 1), index);
|
||||
// TODO: use a network-based shield type override only if a parser couldn't make it
|
||||
// more specific than country's default shield type.
|
||||
// E.g. "94" is set to Generic_Orange by Estonia parser, but then
|
||||
@@ -176,7 +178,7 @@ class USRoadShieldParser : public RoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit USRoadShieldParser(std::string const & baseRoadNumber) : RoadShieldParser(baseRoadNumber) {}
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
std::string shieldText(rawText);
|
||||
|
||||
@@ -236,7 +238,7 @@ class IndiaRoadShieldParser : public RoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit IndiaRoadShieldParser(std::string const & baseRoadNumber) : RoadShieldParser(baseRoadNumber) {}
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
std::string shieldText(rawText);
|
||||
|
||||
@@ -269,7 +271,7 @@ public:
|
||||
, m_type(defaultType)
|
||||
{}
|
||||
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
if (rawText.size() > kMaxRoadShieldBytesSize)
|
||||
return RoadShield();
|
||||
@@ -304,7 +306,7 @@ public:
|
||||
, m_defaultType(defaultType)
|
||||
{}
|
||||
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
if (rawText.size() > kMaxRoadShieldBytesSize)
|
||||
return RoadShield();
|
||||
@@ -329,6 +331,72 @@ private:
|
||||
RoadShieldType const m_defaultType;
|
||||
};
|
||||
|
||||
// Matches by a list of given highway classes for the first shield.
|
||||
// Falls back to matching by a list of given substrings (identical to SimpleRoadShieldParser) for all other shields.
|
||||
class HighwayClassRoadShieldParser : public RoadShieldParser
|
||||
{
|
||||
public:
|
||||
struct Entry
|
||||
{
|
||||
Entry() = default;
|
||||
Entry(std::string_view name, HighwayClass highwayClass, RoadShieldType type, bool isRedundant = false) : m_name(name), m_highwayClass(highwayClass), m_type(type), m_isRedundant(isRedundant) {}
|
||||
|
||||
std::string_view m_name;
|
||||
HighwayClass m_highwayClass = HighwayClass::Undefined;
|
||||
RoadShieldType m_type = RoadShieldType::Default;
|
||||
/* Hides a specific secondary etc. sign, if there is a primary one */
|
||||
bool m_isRedundant = false;
|
||||
};
|
||||
|
||||
using ShieldTypes = buffer_vector<Entry, 8>;
|
||||
|
||||
HighwayClassRoadShieldParser(std::string const & baseRoadNumber, HighwayClass highwayClass, ShieldTypes && types, RoadShieldType defaultType = RoadShieldType::Default)
|
||||
: RoadShieldParser(baseRoadNumber)
|
||||
, m_highwayClass(highwayClass)
|
||||
, m_types(std::move(types))
|
||||
, m_defaultType(defaultType)
|
||||
{}
|
||||
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
if (rawText.size() > kMaxRoadShieldBytesSize)
|
||||
return RoadShield();
|
||||
|
||||
RoadShieldType type = m_defaultType;
|
||||
if (index == 1) {
|
||||
for (auto const & p : m_types)
|
||||
{
|
||||
if (p.m_highwayClass == m_highwayClass)
|
||||
{
|
||||
return RoadShield(p.m_type, rawText);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
size_t idx = std::numeric_limits<size_t>::max();
|
||||
for (auto const & p : m_types)
|
||||
{
|
||||
auto const i = rawText.find(p.m_name);
|
||||
if (i != std::string::npos && i < idx)
|
||||
{
|
||||
if (p.m_isRedundant) {
|
||||
type = RoadShieldType::Hidden;
|
||||
} else {
|
||||
type = p.m_type;
|
||||
}
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {type, rawText};
|
||||
}
|
||||
|
||||
private:
|
||||
HighwayClass const m_highwayClass;
|
||||
ShieldTypes const m_types;
|
||||
RoadShieldType const m_defaultType;
|
||||
};
|
||||
|
||||
uint16_t constexpr kAnyHigherRoadNumber = std::numeric_limits<uint16_t>::max();
|
||||
|
||||
// Matches by a list of numeric ranges (a first matching range is used).
|
||||
@@ -354,7 +422,7 @@ public:
|
||||
, m_types(std::move(types))
|
||||
{}
|
||||
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
if (rawText.size() > kMaxRoadShieldBytesSize)
|
||||
return RoadShield();
|
||||
@@ -403,7 +471,7 @@ public:
|
||||
, m_defaultType(defaultType)
|
||||
{}
|
||||
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
uint32_t constexpr kMaxRoadShieldSymbolsSize = 4 * kMaxRoadShieldBytesSize;
|
||||
|
||||
@@ -429,14 +497,15 @@ private:
|
||||
|
||||
// Implementations of "ref" parses for some countries.
|
||||
|
||||
class AustriaRoadShieldParser : public SimpleRoadShieldParser
|
||||
class AustriaRoadShieldParser : public HighwayClassRoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit AustriaRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Blue_Bordered},
|
||||
{"S", RoadShieldType::Generic_Blue_Bordered},
|
||||
{"B", RoadShieldType::Generic_Blue},
|
||||
{"L", RoadShieldType::Generic_Pill_White_Bordered}})
|
||||
explicit AustriaRoadShieldParser(std::string const & baseRoadNumber, HighwayClass const & highwayClass)
|
||||
: HighwayClassRoadShieldParser(baseRoadNumber, highwayClass,
|
||||
{{"A", HighwayClass::Motorway, RoadShieldType::Generic_Blue_Bordered},
|
||||
{"S", HighwayClass::Trunk, RoadShieldType::Generic_Blue_Bordered},
|
||||
{"B", HighwayClass::Primary, RoadShieldType::Generic_Blue},
|
||||
{"L", HighwayClass::Secondary, RoadShieldType::Generic_Pill_White_Bordered}})
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -585,11 +654,16 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
class UKRoadShieldParser : public SimpleRoadShieldParser
|
||||
class UKRoadShieldParser : public HighwayClassRoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit UKRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"M", RoadShieldType::Generic_Blue}, {"A", RoadShieldType::UK_Highway}})
|
||||
explicit UKRoadShieldParser(std::string const & baseRoadNumber, HighwayClass const & highwayClass)
|
||||
: HighwayClassRoadShieldParser(baseRoadNumber, highwayClass,
|
||||
{{"M", HighwayClass::Motorway, RoadShieldType::Generic_Blue, true},
|
||||
{"E", HighwayClass::Motorway, RoadShieldType::Hidden},
|
||||
{"A", HighwayClass::Trunk, RoadShieldType::UK_Highway, true},
|
||||
{"A", HighwayClass::Primary, RoadShieldType::Generic_White_Bordered},
|
||||
{"B", HighwayClass::Secondary, RoadShieldType::Generic_White_Bordered}})
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -605,14 +679,17 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
class GermanyRoadShieldParser : public SimpleRoadShieldParser
|
||||
class GermanyRoadShieldParser : public HighwayClassRoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit GermanyRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Highway_Hexagon_Blue},
|
||||
{"B", RoadShieldType::Generic_Orange_Bordered},
|
||||
{"L", RoadShieldType::Generic_White_Bordered},
|
||||
{"K", RoadShieldType::Generic_White_Bordered}})
|
||||
explicit GermanyRoadShieldParser(std::string const & baseRoadNumber, HighwayClass const & highwayClass)
|
||||
: HighwayClassRoadShieldParser(baseRoadNumber, highwayClass,
|
||||
{{"A", HighwayClass::Motorway, RoadShieldType::Highway_Hexagon_Blue},
|
||||
{"D", HighwayClass::Motorway, RoadShieldType::Hidden},
|
||||
{"B", HighwayClass::Trunk, RoadShieldType::Generic_Orange_Bordered},
|
||||
{"B", HighwayClass::Primary, RoadShieldType::Generic_Orange_Bordered},
|
||||
{"L", HighwayClass::Secondary, RoadShieldType::Generic_White_Bordered},
|
||||
{"K", HighwayClass::Secondary, RoadShieldType::Generic_White_Bordered}})
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -719,7 +796,7 @@ class MexicoRoadShieldParser : public RoadShieldParser
|
||||
public:
|
||||
explicit MexicoRoadShieldParser(std::string const & baseRoadNumber) : RoadShieldParser(baseRoadNumber) {}
|
||||
|
||||
RoadShield ParseRoadShield(std::string_view rawText) const override
|
||||
RoadShield ParseRoadShield(std::string_view rawText, uint8_t index) const override
|
||||
{
|
||||
std::string shieldText(rawText);
|
||||
|
||||
@@ -762,6 +839,10 @@ RoadShieldsSetT GetRoadShields(FeatureType & f)
|
||||
if (ref.empty())
|
||||
return {};
|
||||
|
||||
auto const & highwayClass = ftypes::GetHighwayClass(feature::TypesHolder(f));
|
||||
if (highwayClass == HighwayClass::Undefined)
|
||||
return {};
|
||||
|
||||
// Find out country name.
|
||||
std::string mwmName = f.GetID().GetMwmName();
|
||||
ASSERT(!mwmName.empty(), (f.GetID()));
|
||||
@@ -770,19 +851,19 @@ RoadShieldsSetT GetRoadShields(FeatureType & f)
|
||||
if (underlinePos != std::string::npos)
|
||||
mwmName = mwmName.substr(0, underlinePos);
|
||||
|
||||
return GetRoadShields(mwmName, ref);
|
||||
return GetRoadShields(mwmName, ref, highwayClass);
|
||||
}
|
||||
|
||||
RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const & roadNumber)
|
||||
RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const & roadNumber, HighwayClass const & highwayClass)
|
||||
{
|
||||
if (mwmName == "US")
|
||||
return USRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "UK")
|
||||
return UKRoadShieldParser(roadNumber).GetRoadShields();
|
||||
return UKRoadShieldParser(roadNumber, highwayClass).GetRoadShields();
|
||||
if (mwmName == "India")
|
||||
return IndiaRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Austria")
|
||||
return AustriaRoadShieldParser(roadNumber).GetRoadShields();
|
||||
return AustriaRoadShieldParser(roadNumber, highwayClass).GetRoadShields();
|
||||
if (mwmName == "Belgium")
|
||||
return BelgiumRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Greece")
|
||||
@@ -816,7 +897,7 @@ RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const &
|
||||
if (mwmName == "France")
|
||||
return FranceRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Germany")
|
||||
return GermanyRoadShieldParser(roadNumber).GetRoadShields();
|
||||
return GermanyRoadShieldParser(roadNumber, highwayClass).GetRoadShields();
|
||||
if (mwmName == "Spain")
|
||||
return SpainRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Ukraine")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
|
||||
#include "geometry/rect2d.hpp"
|
||||
|
||||
@@ -79,7 +80,7 @@ struct RoadShield
|
||||
// Use specific country road shield styles based on mwm feature belongs to.
|
||||
using RoadShieldsSetT = buffer_vector<RoadShield, 2>;
|
||||
RoadShieldsSetT GetRoadShields(FeatureType & f);
|
||||
RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const & roadNumber);
|
||||
RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const & roadNumber, HighwayClass const & highwayClass);
|
||||
|
||||
// Simple parsing without specific country styles.
|
||||
RoadShieldsSetT GetRoadShields(std::string const & rawRoadNumber);
|
||||
|
||||
@@ -14,7 +14,7 @@ using namespace ftypes;
|
||||
|
||||
bool IsHighway(HighwayClass hwClass, bool isLink)
|
||||
{
|
||||
return (hwClass == HighwayClass::Trunk || hwClass == HighwayClass::Primary) && !isLink;
|
||||
return (hwClass == HighwayClass::Motorway || hwClass == HighwayClass::Trunk || hwClass == HighwayClass::Primary) && !isLink;
|
||||
}
|
||||
|
||||
bool IsSmallRoad(HighwayClass hwClass)
|
||||
@@ -102,6 +102,7 @@ double CalcEstimatedTimeToPass(double const distanceMeters, HighwayClass const h
|
||||
double speedKmph = 0;
|
||||
switch (highwayClass)
|
||||
{
|
||||
case HighwayClass::Motorway: speedKmph = 100.0; break;
|
||||
case HighwayClass::Trunk: speedKmph = 100.0; break;
|
||||
case HighwayClass::Primary: speedKmph = 70.0; break;
|
||||
case HighwayClass::Secondary: speedKmph = 70.0; break;
|
||||
|
||||
@@ -21,6 +21,7 @@ openlr::FunctionalRoadClass HighwayClassToFunctionalRoadClass(ftypes::HighwayCla
|
||||
{
|
||||
switch (hwClass)
|
||||
{
|
||||
case ftypes::HighwayClass::Motorway: return openlr::FunctionalRoadClass::FRC0;
|
||||
case ftypes::HighwayClass::Trunk: return openlr::FunctionalRoadClass::FRC0;
|
||||
case ftypes::HighwayClass::Primary: return openlr::FunctionalRoadClass::FRC1;
|
||||
case ftypes::HighwayClass::Secondary: return openlr::FunctionalRoadClass::FRC2;
|
||||
@@ -48,11 +49,10 @@ optional<Score> GetFrcScore(Graph::Edge const & e, FunctionalRoadClass functiona
|
||||
switch (functionalRoadClass)
|
||||
{
|
||||
case FunctionalRoadClass::FRC0:
|
||||
// Note. HighwayClass::Trunk means motorway, motorway_link, trunk or trunk_link.
|
||||
return hwClass == HighwayClass::Trunk ? optional<Score>(kMaxScoreForFrc) : nullopt;
|
||||
return hwClass == HighwayClass::Motorway || hwClass == HighwayClass::Trunk ? optional<Score>(kMaxScoreForFrc) : nullopt;
|
||||
|
||||
case FunctionalRoadClass::FRC1:
|
||||
return (hwClass == HighwayClass::Trunk || hwClass == HighwayClass::Primary) ? optional<Score>(kMaxScoreForFrc)
|
||||
return (HighwayClass::Motorway || hwClass == HighwayClass::Trunk || hwClass == HighwayClass::Primary) ? optional<Score>(kMaxScoreForFrc)
|
||||
: nullopt;
|
||||
|
||||
case FunctionalRoadClass::FRC2:
|
||||
|
||||
Reference in New Issue
Block a user