diff --git a/base/stl_add.hpp b/base/stl_add.hpp index c901003d23..95e4430483 100644 --- a/base/stl_add.hpp +++ b/base/stl_add.hpp @@ -154,6 +154,13 @@ struct IdFunctor } }; +template struct EqualFunctor +{ + T const & m_t; + explicit EqualFunctor(T const & t) : m_t(t) {} + inline bool operator() (T const & t) const { return (t == m_t); } +}; + template IterT NextIterInCycle(IterT it, IterT beg, IterT end) { if (++it == end) diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index e235ed0f35..b152408fb0 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -212,10 +212,31 @@ bool FeatureBuilder1::PreSerialize() // AlexZ: Commented this line to enable captions on subway exits, which // are not drawn but should be visible in balloons and search results //RemoveNameIfInvisible(); + RemoveUselessNames(); return true; } +void FeatureBuilder1::RemoveUselessNames() +{ + int64_t dummy; + if (!m_Params.name.IsEmpty() && !GetCoastCell(dummy)) + { + using namespace feature; + + char const * arr[] = { "boundary", "administrative" }; + static TypeSetChecker checkBoundary(arr, ARRAY_SIZE(arr)); + + TypesHolder types(GetFeatureBase()); + if (types.RemoveIf(bind(&TypeSetChecker::IsEqual, cref(checkBoundary), _1))) + { + pair const range = GetDrawableScaleRangeForRules(types, RULE_ANY_TEXT); + if (range.first == -1) + m_Params.name.Clear(); + } + } +} + void FeatureBuilder1::RemoveNameIfInvisible(int minS, int maxS) { int64_t dummy; diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp index 0a4120c5cf..9c150b862a 100644 --- a/generator/feature_builder.hpp +++ b/generator/feature_builder.hpp @@ -52,6 +52,7 @@ public: /// Clear name if it's not visible in scale range [minS, maxS]. void RemoveNameIfInvisible(int minS = 0, int maxS = 1000); + void RemoveUselessNames(); template bool RemoveTypesIf(FnT fn) { @@ -148,10 +149,10 @@ public: else return false; } - inline string GetName() const + inline string GetName(int8_t lang = StringUtf8Multilang::DEFAULT_CODE) const { string s; - m_Params.name.GetString(0, s); + m_Params.name.GetString(lang, s); return s; } diff --git a/generator/generator_tests/feature_builder_test.cpp b/generator/generator_tests/feature_builder_test.cpp index 02db1b53c0..8db865eaba 100644 --- a/generator/generator_tests/feature_builder_test.cpp +++ b/generator/generator_tests/feature_builder_test.cpp @@ -81,3 +81,36 @@ UNIT_TEST(FVisibility_RemoveNoDrawableTypes) TEST(feature::RemoveNoDrawableTypes(types, feature::FEATURE_TYPE_AREA), ()); TEST_EQUAL(types.size(), 2, ()); } + +UNIT_TEST(FBuilder_RemoveUselessNames) +{ + classificator::Load(); + + FeatureParams params; + + char const * arr3[][3] = { { "boundary", "administrative", "2" } }; + AddTypes(params, arr3); + char const * arr2[][2] = { { "barrier", "fence" } }; + AddTypes(params, arr2); + params.FinishAddingTypes(); + + params.name.AddString(0, "Name"); + params.name.AddString(8, "Имя"); + + FeatureBuilder1 fb1; + fb1.SetParams(params); + + fb1.AddPoint(m2::PointD(0, 0)); + fb1.AddPoint(m2::PointD(1, 1)); + fb1.SetLinear(); + + TEST(!fb1.GetName(0).empty(), ()); + TEST(!fb1.GetName(8).empty(), ()); + + fb1.RemoveUselessNames(); + + TEST(fb1.GetName(0).empty(), ()); + TEST(fb1.GetName(8).empty(), ()); + + TEST(fb1.CheckValid(), ()); +} diff --git a/indexer/feature_data.cpp b/indexer/feature_data.cpp index 4acb1b697d..b7ebab168a 100644 --- a/indexer/feature_data.cpp +++ b/indexer/feature_data.cpp @@ -3,7 +3,8 @@ #include "classificator.hpp" #include "feature.hpp" -#include "../std/algorithm.hpp" +#include "../base/stl_add.hpp" + #include "../std/bind.hpp" @@ -31,12 +32,7 @@ string TypesHolder::DebugPrint() const void TypesHolder::Remove(uint32_t t) { - if (m_size > 0) - { - uint32_t * e = m_types + m_size; - if (std::remove(m_types, e, t) != e) - --m_size; - } + (void) RemoveIf(EqualFunctor(t)); } namespace diff --git a/indexer/feature_data.hpp b/indexer/feature_data.hpp index eaec4371b1..af9230fec6 100644 --- a/indexer/feature_data.hpp +++ b/indexer/feature_data.hpp @@ -9,6 +9,7 @@ #include "../std/string.hpp" #include "../std/vector.hpp" +#include "../std/algorithm.hpp" class FeatureBase; @@ -92,7 +93,21 @@ namespace feature } //@} + template bool RemoveIf(FnT fn) + { + if (m_size > 0) + { + size_t const oldSize = m_size; + + uint32_t * e = remove_if(m_types, m_types + m_size, fn); + m_size = distance(m_types, e); + + return (m_size != oldSize); + } + return false; + } void Remove(uint32_t t); + string DebugPrint() const; /// Sort types by it's specification (more detailed type goes first).