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:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2017-02-01 15:43:20 +0300
committerr.kuznetsov <r.kuznetsov@corp.mail.ru>2017-02-01 15:43:20 +0300
commit5013336567ac1c1d115745b99c471b17c2700ca6 (patch)
tree5700b066163d31e9eb37ae022f2305f37b9f819a /indexer
parente487db8556bc8fc775f4cd6c452493f6a220c7b8 (diff)
Added road shields rendering
Diffstat (limited to 'indexer')
-rw-r--r--indexer/drawing_rules.cpp17
-rw-r--r--indexer/drawing_rules.hpp2
-rw-r--r--indexer/ftypes_matcher.cpp191
-rw-r--r--indexer/ftypes_matcher.hpp29
4 files changed, 217 insertions, 22 deletions
diff --git a/indexer/drawing_rules.cpp b/indexer/drawing_rules.cpp
index 774743528a..2a8d66dd9e 100644
--- a/indexer/drawing_rules.cpp
+++ b/indexer/drawing_rules.cpp
@@ -95,11 +95,6 @@ text_type_t BaseRule::GetCaptionTextType(int) const
return text_type_name;
}
-CircleRuleProto const * BaseRule::GetCircle() const
-{
- return 0;
-}
-
ShieldRuleProto const * BaseRule::GetShield() const
{
return nullptr;
@@ -295,15 +290,6 @@ namespace
typedef CaptionT<CaptionRuleProto> Caption;
typedef CaptionT<PathTextRuleProto> PathText;
- class Circle : public BaseRule
- {
- CircleRuleProto m_circle;
- public:
- Circle(CircleRuleProto const & r) : m_circle(r) {}
-
- virtual CircleRuleProto const * GetCircle() const { return &m_circle; }
- };
-
class Shield : public BaseRule
{
ShieldRuleProto m_shield;
@@ -444,9 +430,6 @@ namespace
if (de.has_caption())
AddRule<Caption>(p, de.scale(), caption, de.caption(), apply_if);
- if (de.has_circle())
- AddRule<Circle>(p, de.scale(), circle, de.circle(), apply_if);
-
if (de.has_path_text())
AddRule<PathText>(p, de.scale(), pathtext, de.path_text(), apply_if);
diff --git a/indexer/drawing_rules.hpp b/indexer/drawing_rules.hpp
index 6870cb869e..317e971ed5 100644
--- a/indexer/drawing_rules.hpp
+++ b/indexer/drawing_rules.hpp
@@ -19,7 +19,6 @@ class LineDefProto;
class AreaRuleProto;
class SymbolRuleProto;
class CaptionDefProto;
-class CircleRuleProto;
class ShieldRuleProto;
class ContainerProto;
class FeatureType;
@@ -56,7 +55,6 @@ namespace drule
virtual SymbolRuleProto const * GetSymbol() const;
virtual CaptionDefProto const * GetCaption(int) const;
virtual text_type_t GetCaptionTextType(int) const;
- virtual CircleRuleProto const * GetCircle() const;
virtual ShieldRuleProto const * GetShield() const;
// Test feature by runtime feature style selector
diff --git a/indexer/ftypes_matcher.cpp b/indexer/ftypes_matcher.cpp
index ec939f1880..c327d50fae 100644
--- a/indexer/ftypes_matcher.cpp
+++ b/indexer/ftypes_matcher.cpp
@@ -4,9 +4,11 @@
#include "indexer/feature_data.hpp"
#include "indexer/classificator.hpp"
-#include "std/map.hpp"
-#include "std/sstream.hpp"
-#include "std/utility.hpp"
+#include <algorithm>
+#include <map>
+#include <sstream>
+#include <unordered_map>
+#include <utility>
namespace
{
@@ -543,4 +545,187 @@ bool IsTypeConformed(uint32_t type, StringIL const & path)
}
return true;
}
+
+class RoadShieldParser
+{
+public:
+ RoadShieldParser(std::string const & baseRoadNumber)
+ : m_baseRoadNumber(baseRoadNumber)
+ {}
+ virtual ~RoadShieldParser(){}
+ virtual RoadShield ParseRoadShield(std::string const & rawText) = 0;
+
+ std::vector<RoadShield> GetRoadShields()
+ {
+ std::vector<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));
+ }
+ return result;
+ }
+
+protected:
+ std::string const m_baseRoadNumber;
+};
+
+uint32_t constexpr kMaxRoadShieldTextSize = 8;
+
+class USRoadShieldParser : public RoadShieldParser
+{
+public:
+ USRoadShieldParser(std::string const & baseRoadNumber)
+ : RoadShieldParser(baseRoadNumber)
+ {}
+
+ RoadShield ParseRoadShield(std::string const & rawText) override
+ {
+ static std::vector<std::string> kStatesCode = {
+ "US", "SR", "FSR", "AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL", "GA",
+ "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS",
+ "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA",
+ "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY", "AS", "GU",
+ "MP", "PR", "VI", "UM", "FM", "MH", "PW",
+ };
+
+ static std::vector<std::string> kModifiers = {
+ "alt", "alternate", "bus", "business", "bypass", "historic", "connector", "loop",
+ "scenic", "spur", "temporary", "toll", "truck"
+ };
+
+ std::string shieldText = rawText;
+
+ std::replace(shieldText.begin(), shieldText.end(), '-', ' ');
+ auto const shieldParts = strings::Tokenize(shieldText, " ");
+
+ // Process long road shield titles to skip invalid data.
+ if (shieldText.size() > kMaxRoadShieldTextSize)
+ {
+ std::string lowerShieldText = shieldText;
+ strings::AsciiToLower(lowerShieldText);
+
+ bool modifierFound = false;
+ for (auto const & modifier : kModifiers)
+ {
+ if (lowerShieldText.find(modifier) != std::string::npos)
+ {
+ modifierFound = true;
+ break;
+ }
+ }
+ if (!modifierFound)
+ return RoadShield();
+ }
+
+ if (shieldParts.size() <= 1)
+ {
+ return RoadShield(RoadShieldType::Default, rawText);
+ }
+ else
+ {
+ std::string const & roadType = shieldParts[0]; // 'I' for interstates and kStatesCode for highways.
+ std::string roadNumber = shieldParts[1];
+ std::string additionalInfo;
+ if (shieldParts.size() >= 3)
+ {
+ additionalInfo = shieldParts[2];
+ // Process cases like "US Loop 16".
+ if (!strings::is_number(shieldParts[1]) && strings::is_number(shieldParts[2]))
+ {
+ roadNumber = shieldParts[2];
+ additionalInfo = shieldParts[1];
+ }
+ }
+ if (roadType == "I")
+ return RoadShield(RoadShieldType::US_Interstate, roadNumber, additionalInfo);
+ else if (std::find(kStatesCode.begin(), kStatesCode.end(), shieldParts[0]) !=kStatesCode.end())
+ return RoadShield(RoadShieldType::US_Highway, roadNumber, additionalInfo);
+
+ return RoadShield(RoadShieldType::Default, rawText);
+ }
+ }
+};
+
+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)
+ {}
+
+ RoadShield ParseRoadShield(std::string const & rawText) override
+ {
+ if (rawText.size() > kMaxRoadShieldTextSize)
+ return RoadShield();
+
+ for (auto const & p : m_types)
+ {
+ if (rawText.find(p.first) != std::string::npos)
+ return RoadShield(p.second, rawText);
+ }
+
+ return RoadShield(RoadShieldType::Default, rawText);
+ }
+
+private:
+ ShieldTypes const m_types;
+};
+
+class UKRoadShieldParser : public SimpleRoadShieldParser
+{
+public:
+ UKRoadShieldParser(std::string const & baseRoadNumber)
+ : SimpleRoadShieldParser(baseRoadNumber, {{'M', RoadShieldType::UK_Motorway},
+ {'A', RoadShieldType::UK_Highway}})
+ {}
+};
+
+class RussiaRoadShieldParser : public RoadShieldParser
+{
+public:
+ RussiaRoadShieldParser(std::string const & baseRoadNumber)
+ : RoadShieldParser(baseRoadNumber)
+ {}
+
+ RoadShield ParseRoadShield(std::string const & rawText) override
+ {
+ if (rawText.size() > kMaxRoadShieldTextSize)
+ return RoadShield();
+
+ strings::UniString s = strings::MakeUniString(rawText);
+ if (s[0] == 'E' || s[0] == strings::UniChar(1045)) // Latin and cyrillic.
+ return RoadShield(RoadShieldType::Russia_Motorway, rawText);
+
+ return RoadShield(RoadShieldType::Russia_Highway, rawText);
+ }
+};
+
+std::vector<RoadShield> GetRoadShields(FeatureType const & f)
+{
+ std::string const roadNumber = f.GetRoadNumber();
+ if (roadNumber.empty())
+ return std::vector<RoadShield>();
+
+ // Find out country name.
+ std::string mwmName = f.GetID().GetMwmName();
+ ASSERT_NOT_EQUAL(mwmName, FeatureID::kInvalidFileName, ());
+ auto const underlinePos = mwmName.find('_');
+ if (underlinePos != std::string::npos)
+ mwmName = mwmName.substr(0, underlinePos);
+
+ if (mwmName == "US")
+ return USRoadShieldParser(roadNumber).GetRoadShields();
+ if (mwmName == "UK")
+ return UKRoadShieldParser(roadNumber).GetRoadShields();
+ if (mwmName == "Russia")
+ return RussiaRoadShieldParser(roadNumber).GetRoadShields();
+
+ return std::vector<RoadShield>{RoadShield(RoadShieldType::Default, roadNumber)};
+}
} // namespace ftypes
diff --git a/indexer/ftypes_matcher.hpp b/indexer/ftypes_matcher.hpp
index c3d6e02d5d..a63267e7be 100644
--- a/indexer/ftypes_matcher.hpp
+++ b/indexer/ftypes_matcher.hpp
@@ -240,4 +240,33 @@ enum class HighwayClass
string DebugPrint(HighwayClass const cls);
HighwayClass GetHighwayClass(feature::TypesHolder const & types);
+
+enum class RoadShieldType
+{
+ Default = 0,
+ US_Interstate,
+ US_Highway,
+ UK_Motorway,
+ UK_Highway,
+ Russia_Motorway,
+ Russia_Highway,
+ Count
+};
+
+struct RoadShield
+{
+ RoadShieldType m_type;
+ std::string m_name;
+ std::string m_additionalText;
+
+ RoadShield() = default;
+ RoadShield(RoadShieldType const & type, std::string const & name)
+ : m_type(type), m_name(name)
+ {}
+ RoadShield(RoadShieldType const & type, std::string const & name, std::string const & additionalText)
+ : m_type(type), m_name(name), m_additionalText(additionalText)
+ {}
+};
+
+std::vector<RoadShield> GetRoadShields(FeatureType const & f);
} // namespace ftypes