From a22150b215d7a88ac67cd6f48335249751583773 Mon Sep 17 00:00:00 2001 From: vng Date: Tue, 28 May 2013 17:15:24 +0300 Subject: [PATCH] [generator] Remove invisible types and texts in World.mwm features. --- generator/feature_builder.cpp | 18 +++++++++----- generator/feature_builder.hpp | 9 +++++++ generator/feature_merger.cpp | 32 +++++++++++++++++++++++++ generator/feature_merger.hpp | 7 +++++- generator/world_map_generator.hpp | 39 ++++++++++++++++++++++++++----- indexer/feature_visibility.hpp | 4 ++-- 6 files changed, 94 insertions(+), 15 deletions(-) diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index 5b1011ce18..de9de8bfdc 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -210,16 +210,22 @@ bool FeatureBuilder1::PreSerialize() } // Clear name for features with invisible texts. - int64_t dummy; - if (!m_Params.name.IsEmpty() && !GetCoastCell(dummy) && - (GetDrawableScaleRangeForRules(GetFeatureBase(), RULE_TEXT).first == -1)) - { - m_Params.name.Clear(); - } + RemoveNameIfInvisible(); return true; } +void FeatureBuilder1::RemoveNameIfInvisible(int minS, int maxS) +{ + int64_t dummy; + if (!m_Params.name.IsEmpty() && !GetCoastCell(dummy)) + { + pair const range = GetDrawableScaleRangeForRules(GetFeatureBase(), RULE_TEXT); + if (range.first > maxS || range.second < minS) + m_Params.name.Clear(); + } +} + bool FeatureBuilder1::operator == (FeatureBuilder1 const & fb) const { if (!(m_Params == fb.m_Params)) return false; diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp index 922749493b..ad9ddcaaa0 100644 --- a/generator/feature_builder.hpp +++ b/generator/feature_builder.hpp @@ -51,6 +51,15 @@ public: void DoCorrectForType(feature::EGeomType type); bool DoCorrect(); + /// Clear name if it's not visible in scale range [minS, maxS]. + void RemoveNameIfInvisible(int minS = 0, int maxS = 1000); + + template void RemoveTypesIf(FnT fn) + { + m_Params.m_Types.erase(remove_if(m_Params.m_Types.begin(), m_Params.m_Types.end(), fn), + m_Params.m_Types.end()); + } + typedef vector buffer_t; /// @name Serialization. diff --git a/generator/feature_merger.cpp b/generator/feature_merger.cpp index 80d204bcce..e75af41a2c 100644 --- a/generator/feature_merger.cpp +++ b/generator/feature_merger.cpp @@ -1,6 +1,7 @@ #include "feature_merger.hpp" #include "../indexer/feature.hpp" +#include "../indexer/feature_visibility.hpp" #include "../indexer/point_to_int64.hpp" #include "../indexer/classificator.hpp" @@ -301,8 +302,39 @@ MergedFeatureBuilder1 * FeatureTypesProcessor::operator() (FeatureBuilder1 const p->ForEachChangeTypes(do_change_types(*this)); + // do preprocessing after types correction + feature::PreprocessForWorldMap(*p); + // zero all additional params for world merged features (names, ranks, ...) p->ZeroParams(); return p; } + + +namespace feature +{ + +class IsInvisibleFn +{ + int m_upperScale; +public: + IsInvisibleFn(int scale) : m_upperScale(scale) {} + bool operator() (uint32_t type) const + { + int const startScale = feature::GetDrawableScaleRange(type).first; + // Actually it should not be equal to -1, but leave for safety reasons. + return (startScale == -1 || startScale > m_upperScale); + } +}; + +void PreprocessForWorldMap(FeatureBuilder1 & fb) +{ + int const upperScale = scales::GetUpperWorldScale(); + + fb.RemoveTypesIf(IsInvisibleFn(upperScale)); + + fb.RemoveNameIfInvisible(0, upperScale); +} + +} diff --git a/generator/feature_merger.hpp b/generator/feature_merger.hpp index c0c029ef6c..9ef0c72cc1 100644 --- a/generator/feature_merger.hpp +++ b/generator/feature_merger.hpp @@ -104,7 +104,7 @@ class FeatureTypesProcessor }; public: - /// For example: highway-motorway_link => highway-motorway. + /// For example: highway-motorway_link-* => highway-motorway. void SetMappingTypes(char const * arr1[2], char const * arr2[2]); /// Leave original types, for example: boundary-administrative-2. @@ -115,3 +115,8 @@ public: MergedFeatureBuilder1 * operator() (FeatureBuilder1 const & fb); }; + +namespace feature +{ + void PreprocessForWorldMap(FeatureBuilder1 & fb); +} diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp index db6b573167..fade53f844 100644 --- a/generator/world_map_generator.hpp +++ b/generator/world_map_generator.hpp @@ -24,14 +24,17 @@ class WorldMapGenerator { } + /// This function is called after merging linear features. virtual void operator() (FeatureBuilder1 const & fb) { + // do additional check for suitable size of feature if (NeedPushToWorld(fb) && scales::IsGoodForLevel(scales::GetUpperWorldScale(), fb.GetLimitRect())) PushSure(fb); } bool NeedPushToWorld(FeatureBuilder1 const & fb) const { + // GetMinFeatureDrawScale also checks suitable size for AREA features return (scales::GetUpperWorldScale() >= fb.GetMinFeatureDrawScale()); } @@ -49,27 +52,51 @@ public: { // Do not strip last types for given tags, // for example, do not cut 'admin_level' in 'boundary-administrative-XXX'. - char const * arr3[][3] = { + char const * arr1[][3] = { { "boundary", "administrative", "2" }, { "boundary", "administrative", "3" }, { "boundary", "administrative", "4" } }; - for (size_t i = 0; i < ARRAY_SIZE(arr3); ++i) - m_typesCorrector.SetDontNormalizeType(arr3[i]); + for (size_t i = 0; i < ARRAY_SIZE(arr1); ++i) + m_typesCorrector.SetDontNormalizeType(arr1[i]); - char const * arr4[] = { "boundary", "administrative", "4", "state" }; - m_typesCorrector.SetDontNormalizeType(arr4); + char const * arr2[] = { "boundary", "administrative", "4", "state" }; + m_typesCorrector.SetDontNormalizeType(arr2); + + /// @todo It's not obvious to integrate link->way conversion. + /// Review it in future. + /* + char const * arr3[][2] = { + { "highway", "motorway_link" }, + { "highway", "primary_link" }, + { "highway", "secondary_link" }, + { "highway", "trunk_link" } + }; + char const * arr4[][2] = { + { "highway", "motorway" }, + { "highway", "primary" }, + { "highway", "secondary" }, + { "highway", "trunk" } + }; + STATIS_ASSERT(ARRAY_SIZE(arr3) == ARRAY_SIZE(arr4)); + + for (size_t i = 0; i < ARRAY_SIZE(arr3); ++i) + m_typesCorrector.SetMappingTypes(arr3[i], arr4[i]); + */ } - void operator()(FeatureBuilder1 const & fb) + void operator()(FeatureBuilder1 fb) { if (m_worldBucket.NeedPushToWorld(fb)) { if (fb.GetGeomType() == feature::GEOM_LINE) m_merger(m_typesCorrector(fb)); else + { + feature::PreprocessForWorldMap(fb); m_worldBucket.PushSure(fb); + } } } diff --git a/indexer/feature_visibility.hpp b/indexer/feature_visibility.hpp index 1b5ee5e6b1..403710075b 100644 --- a/indexer/feature_visibility.hpp +++ b/indexer/feature_visibility.hpp @@ -37,13 +37,13 @@ namespace feature int GetMinDrawableScale(FeatureBase const & f); - /// @return [-1, -1] if no any text exists + /// @return [-1, -1] if range is not drawable //@{ /// @name Get scale range when feature is visible. pair GetDrawableScaleRange(uint32_t type); pair GetDrawableScaleRange(TypesHolder const & types); - /// @name Get scale range when feature's text is visible. + /// @name Get scale range when feature's text or symbol is visible. enum { RULE_TEXT = 1, RULE_SYMBOL = 2