diff --git a/drape_frontend/stylist.cpp b/drape_frontend/stylist.cpp index 5abe9f113d..cd97a096e2 100644 --- a/drape_frontend/stylist.cpp +++ b/drape_frontend/stylist.cpp @@ -437,18 +437,38 @@ bool InitStylist(FeatureType & f, int8_t deviceLang, int const zoomLevel, bool b aggregator.m_rules.push_back(aggregator.m_captionRule); else { - // Use building-address' caption drule to display house numbers. - static auto const addressType = cl.GetTypeByPath({"building", "address"}); - drule::KeysT addressKeys; - cl.GetObject(addressType)->GetSuitable(zoomLevel, geomType, addressKeys); - if (!addressKeys.empty()) + bool isGood = true; + if (zoomLevel < scales::GetUpperStyleScale()) { - // A caption drule exists for this zoom level. - ASSERT(addressKeys.size() == 1 && addressKeys[0].m_type == drule::caption, - ("building-address should contain a caption drule only")); - drule::BaseRule const * const dRule = drule::rules().Find(addressKeys[0]); - ASSERT(dRule != nullptr, ()); - aggregator.m_rules.push_back({ dRule, static_cast(addressKeys[0].m_priority), false }); + if (geomType == feature::GeomType::Area) + { + // Don't display housenumbers when an area (e.g. a building) is too small. + m2::RectD const r = f.GetLimitRect(zoomLevel); + isGood = std::min(r.SizeX(), r.SizeY()) > scales::GetEpsilonForHousenumbers(zoomLevel); + } + else + { + // Limit point housenumbers display to detailed zooms only (z18-). + ASSERT_EQUAL(geomType, feature::GeomType::Point, ()); + isGood = zoomLevel >= scales::GetPointHousenumbersScale(); + } + } + + if (isGood) + { + // Use building-address' caption drule to display house numbers. + static auto const addressType = cl.GetTypeByPath({"building", "address"}); + drule::KeysT addressKeys; + cl.GetObject(addressType)->GetSuitable(zoomLevel, geomType, addressKeys); + if (!addressKeys.empty()) + { + // A caption drule exists for this zoom level. + ASSERT(addressKeys.size() == 1 && addressKeys[0].m_type == drule::caption, + ("building-address should contain a caption drule only")); + drule::BaseRule const * const dRule = drule::rules().Find(addressKeys[0]); + ASSERT(dRule != nullptr, ()); + aggregator.m_rules.push_back({ dRule, static_cast(addressKeys[0].m_priority), false }); + } } } } diff --git a/indexer/scales.cpp b/indexer/scales.cpp index 6ec1075fd2..53856b4185 100644 --- a/indexer/scales.cpp +++ b/indexer/scales.cpp @@ -66,6 +66,19 @@ namespace scales return GetEpsilonImpl(level, 1.3); } + double GetEpsilonForHousenumbers(int level) + { + // Constant pixelTolerance leads to housenumbers either not fitting into buildings on zl16 + // or big looking buildings on z18 not getting a housenumber, + // because buildings sizes changes 2x times for each zoom, but font size changes very little. + double pixelTolerance = 30; + if (level == 17) + pixelTolerance = 18; + else if (level >= 18) + pixelTolerance = 14; + return GetEpsilonImpl(level, pixelTolerance); + } + bool IsGoodForLevel(int level, m2::RectD const & r) { ASSERT(level >= 0 && level <= GetUpperScale(), (level)); diff --git a/indexer/scales.hpp b/indexer/scales.hpp index 4277bfdb91..52cdec87bb 100644 --- a/indexer/scales.hpp +++ b/indexer/scales.hpp @@ -28,6 +28,8 @@ namespace scales constexpr int GetPedestrianNavigation3dScale() { return UPPER_STYLE_SCALE - 2; } /// Default scale in adding-new-place mode. constexpr int GetAddNewPlaceScale() { return 18; } + /// Lower scale when standalone point housenumbers (of building-address type) become visible. + constexpr int GetPointHousenumbersScale() { return 18; } int GetMinAllowableIn3dScale(); @@ -38,6 +40,7 @@ namespace scales double GetEpsilonForLevel(int level); double GetEpsilonForSimplify(int level); + double GetEpsilonForHousenumbers(int level); bool IsGoodForLevel(int level, m2::RectD const & r); using Points = std::vector;