Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Zverev <zverik@textual.ru>2017-03-30 12:17:22 +0300
committerIlya Zverev <zverik@textual.ru>2017-04-05 14:06:04 +0300
commit008e27dee3830c2dab0383773918e6f63ad4a9e7 (patch)
treeeeda7340d013e8774914268f0d7299c9621fdd76 /indexer/road_shields_parser.cpp
parent60a583044afd78f89f4dfab29d356f4b86f16019 (diff)
[shields] Process road networks on relations
Diffstat (limited to 'indexer/road_shields_parser.cpp')
-rw-r--r--indexer/road_shields_parser.cpp329
1 files changed, 261 insertions, 68 deletions
diff --git a/indexer/road_shields_parser.cpp b/indexer/road_shields_parser.cpp
index cead636a21..50fe93fc28 100644
--- a/indexer/road_shields_parser.cpp
+++ b/indexer/road_shields_parser.cpp
@@ -16,9 +16,7 @@ using ftypes::RoadShieldType;
uint32_t constexpr kMaxRoadShieldBytesSize = 8;
-std::array<std::string, 3> const kFederalCode = {{
- "US", "SR", "FSR"
-}};
+std::array<std::string, 3> const kFederalCode = {{"US", "SR", "FSR"}};
std::array<std::string, 60> const kStatesCode = {{
"AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL", "GA", "HI", "ID", "IL", "IN",
@@ -27,29 +25,92 @@ std::array<std::string, 60> const kStatesCode = {{
"VT", "VA", "WA", "WV", "WI", "WY", "AS", "GU", "MP", "PR", "VI", "UM", "FM", "MH", "PW",
}};
-std::array<std::string, 13> const kModifiers = {{
- "alt", "alternate", "bus", "business", "bypass", "historic", "connector",
- "loop", "scenic", "spur", "temporary", "toll", "truck"
-}};
+std::array<std::string, 13> const kModifiers = {{"alt", "alternate", "bus", "business", "bypass",
+ "historic", "connector", "loop", "scenic", "spur",
+ "temporary", "toll", "truck"}};
+
+// Shields based on a network tag in a route=road relation.
+std::unordered_map<std::string, RoadShieldType> const kRoadNetworkShields = {
+ // International road networks.
+ {"e-road", RoadShieldType::Generic_Green}, // E 105
+ {"asianhighway", RoadShieldType::Hidden}, // AH8. Blue, but usually not posted.
+ // National and regional networks for some countries.
+ {"ru:national", RoadShieldType::Generic_Blue},
+ {"ru:regional", RoadShieldType::Generic_Blue},
+ {"bg:national", RoadShieldType::Generic_Green},
+ {"bg:regional", RoadShieldType::Generic_Blue},
+ {"by:national", RoadShieldType::Generic_Red},
+ {"by:regional", RoadShieldType::Generic_Red},
+ {"co:national", RoadShieldType::Generic_White},
+ {"cz:national", RoadShieldType::Generic_Red},
+ {"cz:regional", RoadShieldType::Generic_Blue},
+ {"ee:national", RoadShieldType::Generic_Red},
+ {"ee:regional", RoadShieldType::Generic_White},
+ {"fr:a-road", RoadShieldType::Generic_Red},
+ {"jp:national", RoadShieldType::Generic_Blue},
+ {"jp:regional", RoadShieldType::Generic_Blue},
+ {"jp:prefectural", RoadShieldType::Generic_Blue},
+ {"lt:national", RoadShieldType::Generic_Red},
+ {"lt:regional", RoadShieldType::Generic_Blue},
+ {"lv:national", RoadShieldType::Generic_Red},
+ {"lv:regional", RoadShieldType::Generic_Blue},
+ {"pl:national", RoadShieldType::Generic_Red},
+ {"pl:regional", RoadShieldType::Generic_Orange},
+ {"pl:local", RoadShieldType::Generic_White},
+ {"ua:national", RoadShieldType::Generic_Blue},
+ {"ua:regional", RoadShieldType::Generic_Blue},
+ {"ua:territorial", RoadShieldType::Generic_White},
+ {"ua:local", RoadShieldType::Generic_White},
+ {"za:national", RoadShieldType::Generic_White},
+ {"za:regional", RoadShieldType::Generic_White},
+ // United States road networks.
+ {"us:i", RoadShieldType::US_Interstate},
+ {"us:us", RoadShieldType::US_Highway},
+ {"us:sr", RoadShieldType::US_Highway},
+ {"us:fsr", RoadShieldType::US_Highway},
+};
class RoadShieldParser
{
public:
- RoadShieldParser(std::string const & baseRoadNumber)
- : m_baseRoadNumber(baseRoadNumber)
- {}
- virtual ~RoadShieldParser(){}
- virtual RoadShield ParseRoadShield(std::string const & rawText) = 0;
+ explicit RoadShieldParser(std::string const & baseRoadNumber) : m_baseRoadNumber(baseRoadNumber) {}
+ virtual ~RoadShieldParser() {}
+ virtual RoadShield ParseRoadShield(std::string const & rawText) const = 0;
+
+ RoadShieldType FindNetworkShield(std::string network) const
+ {
+ // Minimum length for the network tag is 4 (US:I).
+ if (network.size() > 4)
+ {
+ strings::AsciiToLower(network);
- std::vector<RoadShield> GetRoadShields()
+ // Cut off suffixes after a semicolon repeatedly, until we find a relevant shield.
+ auto semicolonPos = network.size();
+ while (semicolonPos != std::string::npos)
+ {
+ network.resize(semicolonPos); // cut off the ":xxx" suffix
+ auto const it = kRoadNetworkShields.find(network);
+ if (it != kRoadNetworkShields.cend())
+ return it->second;
+ semicolonPos = network.rfind(':');
+ }
+ }
+ return RoadShieldType::Default;
+ }
+
+ std::set<RoadShield> GetRoadShields() const
{
- std::vector<RoadShield> result;
+ std::set<RoadShield> result;
std::vector<std::string> shieldsRawTests = strings::Tokenize(m_baseRoadNumber, ";");
for (std::string const & rawText : shieldsRawTests)
{
- RoadShield shield = ParseRoadShield(rawText);
- if (!shield.m_name.empty())
- result.push_back(std::move(shield));
+ auto slashPos = rawText.find('/');
+ RoadShield shield = slashPos == std::string::npos
+ ? ParseRoadShield(rawText)
+ : RoadShield{FindNetworkShield(rawText.substr(0, slashPos)),
+ rawText.substr(slashPos + 1)};
+ if (!shield.m_name.empty() && shield.m_type != RoadShieldType::Hidden)
+ result.insert(std::move(shield));
}
return result;
}
@@ -61,11 +122,8 @@ protected:
class USRoadShieldParser : public RoadShieldParser
{
public:
- USRoadShieldParser(std::string const & baseRoadNumber)
- : RoadShieldParser(baseRoadNumber)
- {}
-
- RoadShield ParseRoadShield(std::string const & rawText) override
+ USRoadShieldParser(std::string const & baseRoadNumber) : RoadShieldParser(baseRoadNumber) {}
+ RoadShield ParseRoadShield(std::string const & rawText) const override
{
std::string shieldText = rawText;
@@ -94,7 +152,8 @@ public:
if (shieldParts.size() <= 1)
return RoadShield(RoadShieldType::Default, rawText);
- std::string const & roadType = shieldParts[0]; // 'I' for interstates and kFederalCode/kStatesCode for highways.
+ std::string const & roadType =
+ shieldParts[0]; // 'I' for interstates and kFederalCode/kStatesCode for highways.
std::string roadNumber = shieldParts[1];
std::string additionalInfo;
if (shieldParts.size() >= 3)
@@ -115,23 +174,44 @@ public:
return RoadShield(RoadShieldType::US_Highway, roadNumber, additionalInfo);
if (std::find(kStatesCode.begin(), kStatesCode.end(), shieldParts[0]) != kStatesCode.end())
- return RoadShield(RoadShieldType::Default, roadNumber, additionalInfo);
+ return RoadShield(RoadShieldType::Generic_White, roadNumber, additionalInfo);
return RoadShield(RoadShieldType::Default, rawText);
}
};
+class DefaultTypeRoadShieldParser : public RoadShieldParser
+{
+public:
+ DefaultTypeRoadShieldParser(std::string const & baseRoadNumber,
+ RoadShieldType const & defaultType)
+ : RoadShieldParser(baseRoadNumber), m_type(defaultType)
+ {
+ }
+
+ RoadShield ParseRoadShield(std::string const & rawText) const override
+ {
+ if (rawText.size() > kMaxRoadShieldBytesSize)
+ return RoadShield();
+
+ return RoadShield(m_type, rawText);
+ }
+
+private:
+ RoadShieldType const m_type;
+};
+
class SimpleRoadShieldParser : public RoadShieldParser
{
public:
using ShieldTypes = std::unordered_map<char, RoadShieldType>;
SimpleRoadShieldParser(std::string const & baseRoadNumber, ShieldTypes const & types)
- : RoadShieldParser(baseRoadNumber)
- , m_types(types)
- {}
+ : RoadShieldParser(baseRoadNumber), m_types(types)
+ {
+ }
- RoadShield ParseRoadShield(std::string const & rawText) override
+ RoadShield ParseRoadShield(std::string const & rawText) const override
{
if (rawText.size() > kMaxRoadShieldBytesSize)
return RoadShield();
@@ -149,32 +229,38 @@ private:
ShieldTypes const m_types;
};
-class UKRoadShieldParser : public SimpleRoadShieldParser
+class NumericRoadShieldParser : public RoadShieldParser
{
public:
- UKRoadShieldParser(std::string const & baseRoadNumber)
- : SimpleRoadShieldParser(baseRoadNumber, {{'M', RoadShieldType::Generic_Blue}, {'A', RoadShieldType::UK_Highway}})
- {}
-};
+ // A map of {lower_bound, higher_bound} -> RoadShieldType.
+ using ShieldTypes =
+ std::vector<std::pair<std::pair<std::uint16_t, std::uint16_t>, RoadShieldType>>;
-class RussiaRoadShieldParser : public RoadShieldParser
-{
-public:
- RussiaRoadShieldParser(std::string const & baseRoadNumber)
- : RoadShieldParser(baseRoadNumber)
- {}
+ NumericRoadShieldParser(std::string const & baseRoadNumber, ShieldTypes const & types)
+ : RoadShieldParser(baseRoadNumber), m_types(types)
+ {
+ }
- RoadShield ParseRoadShield(std::string const & rawText) override
+ RoadShield ParseRoadShield(std::string const & rawText) const override
{
if (rawText.size() > kMaxRoadShieldBytesSize)
return RoadShield();
- strings::UniString s = strings::MakeUniString(rawText);
- if (s[0] == 'E' || s[0] == strings::UniChar(1045)) // Latin and cyrillic.
- return RoadShield(RoadShieldType::Generic_Green, rawText);
+ std::uint64_t ref;
+ if (strings::to_uint64(rawText, ref))
+ {
+ for (auto const & p : m_types)
+ {
+ if (p.first.first <= ref && ref <= p.first.second)
+ return RoadShield(p.second, rawText);
+ }
+ }
- return RoadShield(RoadShieldType::Generic_Blue, rawText);
+ return RoadShield(RoadShieldType::Default, rawText);
}
+
+private:
+ ShieldTypes const m_types;
};
class SimpleUnicodeRoadShieldParser : public RoadShieldParser
@@ -183,7 +269,7 @@ public:
struct Name
{
Name(std::string const & simpleName, string const & unicodeName)
- : m_simpleName(simpleName), m_unicodeName(strings::MakeUniString(unicodeName))
+ : m_simpleName(simpleName), m_unicodeName(strings::MakeUniString(unicodeName))
{
}
@@ -194,11 +280,11 @@ public:
using ShieldTypes = std::vector<std::pair<Name, RoadShieldType>>;
SimpleUnicodeRoadShieldParser(std::string const & baseRoadNumber, ShieldTypes const & types)
- : RoadShieldParser(baseRoadNumber), m_types(types)
+ : RoadShieldParser(baseRoadNumber), m_types(types)
{
}
- RoadShield ParseRoadShield(std::string const & rawText) override
+ RoadShield ParseRoadShield(std::string const & rawText) const override
{
uint32_t constexpr kMaxRoadShieldSymbolsSize = 4 * kMaxRoadShieldBytesSize;
@@ -215,7 +301,8 @@ public:
auto const rawUnicode = strings::MakeUniString(rawText);
auto const & unicodeName = name.m_unicodeName;
- auto const it = std::search(rawUnicode.begin(), rawUnicode.end(), unicodeName.begin(), unicodeName.end());
+ auto const it =
+ std::search(rawUnicode.begin(), rawUnicode.end(), unicodeName.begin(), unicodeName.end());
if (it != rawUnicode.end())
return RoadShield(type, rawText);
}
@@ -227,14 +314,56 @@ private:
ShieldTypes const m_types;
};
+// Implementations of "ref" parses for some countries.
+
+class RussiaRoadShieldParser : public DefaultTypeRoadShieldParser
+{
+public:
+ RussiaRoadShieldParser(std::string const & baseRoadNumber)
+ : DefaultTypeRoadShieldParser(baseRoadNumber, RoadShieldType::Generic_Blue)
+ {
+ }
+};
+
+class SpainRoadShieldParser : public DefaultTypeRoadShieldParser
+{
+public:
+ SpainRoadShieldParser(std::string const & baseRoadNumber)
+ : DefaultTypeRoadShieldParser(baseRoadNumber, RoadShieldType::Generic_Blue)
+ {
+ }
+};
+
+class UKRoadShieldParser : public SimpleRoadShieldParser
+{
+public:
+ UKRoadShieldParser(std::string const & baseRoadNumber)
+ : SimpleRoadShieldParser(
+ baseRoadNumber, {{'M', RoadShieldType::Generic_Blue}, {'A', RoadShieldType::UK_Highway}})
+ {
+ }
+};
+
class FranceRoadShieldParser : public SimpleRoadShieldParser
{
public:
FranceRoadShieldParser(std::string const & baseRoadNumber)
- : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Red},
- {'N', RoadShieldType::Generic_Red},
- {'E', RoadShieldType::Generic_Green},
- {'D', RoadShieldType::Generic_Orange}})
+ : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Red},
+ {'N', RoadShieldType::Generic_Red},
+ {'E', RoadShieldType::Generic_Green},
+ {'D', RoadShieldType::Generic_Orange}})
+ {
+ }
+};
+
+class GermanyRoadShieldParser : public SimpleRoadShieldParser
+{
+public:
+ GermanyRoadShieldParser(std::string const & baseRoadNumber)
+ : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Blue},
+ {'B', RoadShieldType::Generic_Orange},
+ {'L', RoadShieldType::Generic_White},
+ {'K', RoadShieldType::Generic_White}})
{
}
};
@@ -244,10 +373,11 @@ class UkraineRoadShieldParser : public SimpleUnicodeRoadShieldParser
public:
// The second parameter in the constructor is a cyrillic symbol.
UkraineRoadShieldParser(std::string const & baseRoadNumber)
- : SimpleUnicodeRoadShieldParser(baseRoadNumber, {{Name("M", "М"), RoadShieldType::Generic_Blue},
- {Name("H", "Н"), RoadShieldType::Generic_Blue},
- {Name("P", "Р"), RoadShieldType::Generic_Blue},
- {Name("E", "Е"), RoadShieldType::Generic_Green}})
+ : SimpleUnicodeRoadShieldParser(baseRoadNumber,
+ {{Name("M", "М"), RoadShieldType::Generic_Blue},
+ {Name("H", "Н"), RoadShieldType::Generic_Blue},
+ {Name("P", "Р"), RoadShieldType::Generic_Blue},
+ {Name("E", "Е"), RoadShieldType::Generic_Green}})
{
}
};
@@ -257,9 +387,10 @@ class BelarusRoadShieldParser : public SimpleUnicodeRoadShieldParser
public:
// The second parameter in the constructor is a cyrillic symbol.
BelarusRoadShieldParser(std::string const & baseRoadNumber)
- : SimpleUnicodeRoadShieldParser(baseRoadNumber, {{Name("M", "М"), RoadShieldType::Generic_Red},
- {Name("P", "Р"), RoadShieldType::Generic_Red},
- {Name("E", "Е"), RoadShieldType::Generic_Green}})
+ : SimpleUnicodeRoadShieldParser(baseRoadNumber,
+ {{Name("M", "М"), RoadShieldType::Generic_Red},
+ {Name("P", "Р"), RoadShieldType::Generic_Red},
+ {Name("E", "Е"), RoadShieldType::Generic_Green}})
{
}
};
@@ -268,9 +399,9 @@ class LatviaRoadShieldParser : public SimpleRoadShieldParser
{
public:
LatviaRoadShieldParser(std::string const & baseRoadNumber)
- : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Red},
- {'E', RoadShieldType::Generic_Green},
- {'P', RoadShieldType::Generic_Blue}})
+ : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Red},
+ {'E', RoadShieldType::Generic_Green},
+ {'P', RoadShieldType::Generic_Blue}})
{
}
};
@@ -279,20 +410,48 @@ class NetherlandsRoadShieldParser : public SimpleRoadShieldParser
{
public:
NetherlandsRoadShieldParser(std::string const & baseRoadNumber)
- : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Red},
- {'E', RoadShieldType::Generic_Green},
- {'N', RoadShieldType::Generic_Orange}})
- {}
+ : SimpleRoadShieldParser(baseRoadNumber, {{'A', RoadShieldType::Generic_Red},
+ {'E', RoadShieldType::Generic_Green},
+ {'N', RoadShieldType::Generic_Orange}})
+ {
+ }
+};
+
+class FinlandRoadShieldParser : public NumericRoadShieldParser
+{
+public:
+ FinlandRoadShieldParser(std::string const & baseRoadNumber)
+ : NumericRoadShieldParser(baseRoadNumber, {{{1, 30}, RoadShieldType::Generic_Red},
+ {{40, 99}, RoadShieldType::Generic_Orange},
+ {{100, 999}, RoadShieldType::Generic_White},
+ {{1000, 9999}, RoadShieldType::Generic_Blue},
+ {{10000, 60000}, RoadShieldType::Hidden}})
+ {
+ }
+};
+
+class EstoniaRoadShieldParser : public NumericRoadShieldParser
+{
+public:
+ EstoniaRoadShieldParser(std::string const & baseRoadNumber)
+ : NumericRoadShieldParser(baseRoadNumber, {{{1, 11}, RoadShieldType::Generic_Red},
+ {{12, 91}, RoadShieldType::Generic_Orange},
+ {{92, 92}, RoadShieldType::Generic_Red},
+ {{93, 95}, RoadShieldType::Generic_Orange},
+ {{96, 999}, RoadShieldType::Generic_White},
+ {{1000, 60000}, RoadShieldType::Hidden}})
+ {
+ }
};
} // namespace
namespace ftypes
{
-std::vector<RoadShield> GetRoadShields(FeatureType const & f)
+std::set<RoadShield> GetRoadShields(FeatureType const & f)
{
std::string const roadNumber = f.GetRoadNumber();
if (roadNumber.empty())
- return std::vector<RoadShield>();
+ return std::set<RoadShield>();
// Find out country name.
std::string mwmName = f.GetID().GetMwmName();
@@ -309,6 +468,10 @@ std::vector<RoadShield> GetRoadShields(FeatureType const & f)
return RussiaRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "France")
return FranceRoadShieldParser(roadNumber).GetRoadShields();
+ if (mwmName == "Germany")
+ return GermanyRoadShieldParser(roadNumber).GetRoadShields();
+ if (mwmName == "Spain")
+ return SpainRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Ukraine")
return UkraineRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Belarus")
@@ -317,7 +480,37 @@ std::vector<RoadShield> GetRoadShields(FeatureType const & f)
return LatviaRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Netherlands")
return NetherlandsRoadShieldParser(roadNumber).GetRoadShields();
+ if (mwmName == "Finland")
+ return FinlandRoadShieldParser(roadNumber).GetRoadShields();
+ if (mwmName == "Estonia")
+ return EstoniaRoadShieldParser(roadNumber).GetRoadShields();
return SimpleRoadShieldParser(roadNumber, SimpleRoadShieldParser::ShieldTypes()).GetRoadShields();
}
+
+std::string DebugPrint(RoadShieldType shieldType)
+{
+ using ftypes::RoadShieldType;
+ switch (shieldType)
+ {
+ case RoadShieldType::Default: return "default";
+ case RoadShieldType::Generic_White: return "white";
+ case RoadShieldType::Generic_Blue: return "blue";
+ case RoadShieldType::Generic_Green: return "green";
+ case RoadShieldType::Generic_Orange: return "orange";
+ case RoadShieldType::Generic_Red: return "red";
+ case RoadShieldType::US_Interstate: return "US interstate";
+ case RoadShieldType::US_Highway: return "US highway";
+ case RoadShieldType::UK_Highway: return "UK highway";
+ case RoadShieldType::Hidden: return "hidden";
+ case RoadShieldType::Count: CHECK(false, ("RoadShieldType::Count is not to be used as a type"));
+ }
+ return string();
+}
+
+std::string DebugPrint(RoadShield const & shield)
+{
+ return DebugPrint(shield.m_type) + "/" + shield.m_name +
+ (shield.m_additionalText.empty() ? "" : " (" + shield.m_additionalText + ")");
+}
} // namespace ftypes