diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index 8aba7ab405..f2c84f6987 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -136,7 +136,9 @@ bool FeatureBuilder1::RemoveInvalidTypes() if (!m_params.FinishAddingTypes()) return false; - return feature::RemoveNoDrawableTypes(m_params.m_Types, m_params.GetGeomType()); + return feature::RemoveNoDrawableTypes(m_params.m_Types, + m_params.GetGeomType(), + m_params.name.IsEmpty()); } bool FeatureBuilder1::FormatFullAddress(string & res) const diff --git a/generator/generator_tests/feature_builder_test.cpp b/generator/generator_tests/feature_builder_test.cpp index 880b027d96..6c8664ab7a 100644 --- a/generator/generator_tests/feature_builder_test.cpp +++ b/generator/generator_tests/feature_builder_test.cpp @@ -45,7 +45,7 @@ UNIT_TEST(FBuilder_ManyTypes) params.FinishAddingTypes(); params.AddHouseNumber("75"); params.AddHouseName("Best House"); - params.name.AddString(0, "Name"); + params.AddName("default", "Name"); fb1.SetParams(params); fb1.SetCenter(m2::PointD(0, 0)); @@ -125,8 +125,8 @@ UNIT_TEST(FBuilder_RemoveUselessNames) AddTypes(params, arr2); params.FinishAddingTypes(); - params.name.AddString(0, "Name"); - params.name.AddString(8, "Имя"); + params.AddName("default", "Name"); + params.AddName("ru", "Имя"); FeatureBuilder1 fb1; fb1.SetParams(params); @@ -145,3 +145,34 @@ UNIT_TEST(FBuilder_RemoveUselessNames) TEST(fb1.CheckValid(), ()); } + +UNIT_TEST(FBuilder_WithoutName) +{ + classificator::Load(); + char const * arr1[][1] = { { "amenity" } }; + + { + FeatureParams params; + AddTypes(params, arr1); + params.AddName("default", "Name"); + + FeatureBuilder1 fb; + fb.SetParams(params); + fb.SetCenter(m2::PointD(0, 0)); + + TEST(fb.PreSerialize(), ()); + TEST(fb.RemoveInvalidTypes(), ()); + } + + { + FeatureParams params; + AddTypes(params, arr1); + + FeatureBuilder1 fb; + fb.SetParams(params); + fb.SetCenter(m2::PointD(0, 0)); + + TEST(fb.PreSerialize(), ()); + TEST(!fb.RemoveInvalidTypes(), ()); + } +} diff --git a/indexer/classificator.cpp b/indexer/classificator.cpp index f66acc8589..dd9da03464 100644 --- a/indexer/classificator.cpp +++ b/indexer/classificator.cpp @@ -38,9 +38,9 @@ ClassifObject * ClassifObject::Add(string const & s) ClassifObject * ClassifObject::Find(string const & s) { - for (iter_t i = m_objs.begin(); i != m_objs.end(); ++i) - if ((*i).m_name == s) - return &(*i); + for (auto & obj : m_objs) + if (obj.m_name == s) + return &obj; return 0; } @@ -56,7 +56,7 @@ void ClassifObject::AddDrawRule(drule::Key const & k) ClassifObjectPtr ClassifObject::BinaryFind(string const & s) const { - const_iter_t i = lower_bound(m_objs.begin(), m_objs.end(), s, less_name_t()); + auto i = lower_bound(m_objs.begin(), m_objs.end(), s, less_name_t()); if ((i == m_objs.end()) || ((*i).m_name != s)) return ClassifObjectPtr(0, 0); else @@ -293,10 +293,10 @@ bool ClassifObject::IsDrawable(int scale) const bool ClassifObject::IsDrawableAny() const { - return (m_visibility != visible_mask_t() && !m_drawRule.empty()); + return (m_visibility != TVisibleMask() && !m_drawRule.empty()); } -bool ClassifObject::IsDrawableLike(feature::EGeomType ft) const +bool ClassifObject::IsDrawableLike(feature::EGeomType ft, bool emptyName) const { ASSERT(ft >= 0 && ft <= 2, ()); @@ -310,12 +310,14 @@ bool ClassifObject::IsDrawableLike(feature::EGeomType ft) const {0, 1, 0, 0, 0, 0, 0, 0} // farea (!!! key difference with GetSuitable !!!) }; - for (size_t i = 0; i < m_drawRule.size(); ++i) + for (auto const & k : m_drawRule) { - ASSERT ( m_drawRule[i].m_type < drule::count_of_rules, () ); - if (visible[ft][m_drawRule[i].m_type] == 1) + ASSERT_LESS(k.m_type, drule::count_of_rules, ()); + + // In case when feature name is empty we donn't take into account caption drawing rules. + if ((visible[ft][k.m_type] == 1) && + (!emptyName || (k.m_type != drule::caption && k.m_type != drule::pathtext))) { - /// @todo Check if rule's scale is reachable according to m_visibility (see GetSuitable algorithm). return true; } } diff --git a/indexer/classificator.hpp b/indexer/classificator.hpp index bec2aa1d2d..4ec893c923 100644 --- a/indexer/classificator.hpp +++ b/indexer/classificator.hpp @@ -84,7 +84,7 @@ public: bool IsDrawable(int scale) const; bool IsDrawableAny() const; - bool IsDrawableLike(feature::EGeomType ft) const; + bool IsDrawableLike(feature::EGeomType ft, bool emptyName = false) const; pair GetDrawScaleRange() const; @@ -110,10 +110,8 @@ public: } } - typedef bitset visible_mask_t; - visible_mask_t GetVisibilityMask() const { return m_visibility; } - void SetVisibilityMask(visible_mask_t mask) { m_visibility = mask; } - void SetVisibilityOnScale(const bool isVisible, const int scale) { m_visibility[scale] = isVisible; } + typedef bitset TVisibleMask; + void SetVisibilityOnScale(bool isVisible, int scale) { m_visibility[scale] = isVisible; } /// @name Policies for classificator tree serialization. //@{ @@ -146,10 +144,7 @@ private: string m_name; vector m_drawRule; vector m_objs; - visible_mask_t m_visibility; - - typedef vector::iterator iter_t; - typedef vector::const_iterator const_iter_t; + TVisibleMask m_visibility; }; inline void swap(ClassifObject & r1, ClassifObject & r2) diff --git a/indexer/feature_visibility.cpp b/indexer/feature_visibility.cpp index dbc22e3573..db93cb8fed 100644 --- a/indexer/feature_visibility.cpp +++ b/indexer/feature_visibility.cpp @@ -147,8 +147,8 @@ void GetDrawRule(vector const & types, int level, int geoType, DrawRuleGetter doRules(level, EGeomType(geoType), keys); - for (size_t i = 0; i < types.size(); ++i) - (void)c.ProcessObjects(types[i], doRules); + for (uint32_t t : types) + (void)c.ProcessObjects(t, doRules); } namespace @@ -176,17 +176,21 @@ namespace class IsDrawableLikeChecker { - EGeomType m_type; + EGeomType m_geomType; + bool m_emptyName; public: - IsDrawableLikeChecker(EGeomType type) : m_type(type) {} + IsDrawableLikeChecker(EGeomType geomType, bool emptyName = false) + : m_geomType(geomType), m_emptyName(emptyName) + { + } typedef bool ResultType; void operator() (ClassifObject const *) {} bool operator() (ClassifObject const * p, bool & res) { - if (p->IsDrawableLike(m_type)) + if (p->IsDrawableLike(m_geomType, m_emptyName)) { res = true; return true; @@ -218,11 +222,11 @@ namespace drule::KeysT keys; p->GetSuitable(m_scale, m_ft, keys); - for (size_t i = 0; i < keys.size(); ++i) + for (auto const & k : keys) { - if ((m_arr[0] && keys[i].m_type == drule::caption) || - (m_arr[1] && keys[i].m_type == drule::pathtext) || - (m_arr[2] && keys[i].m_type == drule::symbol)) + if ((m_arr[0] && k.m_type == drule::caption) || + (m_arr[1] && k.m_type == drule::pathtext) || + (m_arr[2] && k.m_type == drule::symbol)) { res = true; return true; @@ -259,13 +263,13 @@ bool IsDrawableAny(uint32_t type) return (TypeAlwaysExists(type) || classif().GetObject(type)->IsDrawableAny()); } -bool IsDrawableLike(vector const & types, EGeomType ft) +bool IsDrawableLike(vector const & types, EGeomType geomType) { Classificator const & c = classif(); - IsDrawableLikeChecker doCheck(ft); - for (size_t i = 0; i < types.size(); ++i) - if (c.ProcessObjects(types[i], doCheck)) + IsDrawableLikeChecker doCheck(geomType); + for (uint32_t t : types) + if (c.ProcessObjects(t, doCheck)) return true; return false; } @@ -302,42 +306,31 @@ bool IsDrawableForIndexClassifOnly(FeatureBase const & f, int level) return false; } -namespace +bool RemoveNoDrawableTypes(vector & types, EGeomType geomType, bool emptyName) { - class IsNonDrawableType + Classificator const & c = classif(); + + types.erase(remove_if(types.begin(), types.end(), [&] (uint32_t t) { - Classificator & m_c; - EGeomType m_type; + if (TypeAlwaysExists(t, geomType)) + return false; - public: - IsNonDrawableType(EGeomType ft) : m_c(classif()), m_type(ft) {} + IsDrawableLikeChecker doCheck(geomType, emptyName); + if (c.ProcessObjects(t, doCheck)) + return false; - bool operator() (uint32_t t) const - { - if (TypeAlwaysExists(t, m_type)) - return false; + // IsDrawableLikeChecker checks only unique area styles, + // so we need to take into account point styles too. + if (geomType == GEOM_AREA) + { + IsDrawableLikeChecker doCheck(GEOM_POINT, emptyName); + if (c.ProcessObjects(t, doCheck)) + return false; + } - IsDrawableLikeChecker doCheck(m_type); - if (m_c.ProcessObjects(t, doCheck)) - return false; + return true; + }), types.end()); - // IsDrawableLikeChecker checks only unique area styles, - // so we need to take into account point styles too. - if (m_type == GEOM_AREA) - { - IsDrawableLikeChecker doCheck(GEOM_POINT); - if (m_c.ProcessObjects(t, doCheck)) - return false; - } - - return true; - } - }; -} - -bool RemoveNoDrawableTypes(vector & types, EGeomType ft) -{ - types.erase(remove_if(types.begin(), types.end(), IsNonDrawableType(ft)), types.end()); return !types.empty(); } diff --git a/indexer/feature_visibility.hpp b/indexer/feature_visibility.hpp index 8e4df33ca1..c468140be6 100644 --- a/indexer/feature_visibility.hpp +++ b/indexer/feature_visibility.hpp @@ -28,9 +28,9 @@ namespace feature bool IsDrawableForIndexGeometryOnly(FeatureBase const & f, int level); /// For FEATURE_TYPE_AREA need to have at least one area-filling type. - bool IsDrawableLike(vector const & types, EGeomType ft); + bool IsDrawableLike(vector const & types, EGeomType geomType); /// For FEATURE_TYPE_AREA removes line-drawing only types. - bool RemoveNoDrawableTypes(vector & types, EGeomType ft); + bool RemoveNoDrawableTypes(vector & types, EGeomType geomType, bool emptyName = false); //@} int GetMinDrawableScale(FeatureBase const & f);