#include "indexer/feature_utils.hpp" #include "indexer/feature_visibility.hpp" #include "indexer/classificator.hpp" #include "indexer/feature_data.hpp" #include "indexer/scales.hpp" #include "geometry/point2d.hpp" #include "base/base.hpp" #include "std/vector.hpp" namespace feature { namespace impl { class FeatureEstimator { template static bool IsEqual(uint32_t t, uint32_t const (&arr)[N]) { for (size_t i = 0; i < N; ++i) if (arr[i] == t) return true; return false; } public: FeatureEstimator() { m_TypeContinent = GetType("place", "continent"); m_TypeCountry = GetType("place", "country"); m_TypeState = GetType("place", "state"); m_TypeCounty[0] = GetType("place", "region"); m_TypeCounty[1] = GetType("place", "county"); m_TypeCity = GetType("place", "city"); m_TypeCityCapital = GetType("place", "city", "capital"); m_TypeTown = GetType("place", "town"); m_TypeVillage[0] = GetType("place", "village"); m_TypeVillage[1] = GetType("place", "suburb"); m_TypeSmallVillage[0] = GetType("place", "hamlet"); m_TypeSmallVillage[1] = GetType("place", "locality"); m_TypeSmallVillage[2] = GetType("place", "farm"); } void CorrectScaleForVisibility(TypesHolder const & types, int & scale) const { pair const scaleR = GetDrawableScaleRangeForRules(types, RULE_ANY_TEXT); ASSERT_LESS_OR_EQUAL ( scaleR.first, scaleR.second, () ); // Result types can be without visible texts (matched by category). if (scaleR.first != -1) { if (scale < scaleR.first) scale = scaleR.first; else if (scale > scaleR.second) scale = scaleR.second; } } int GetViewportScale(TypesHolder const & types) const { int scale = GetDefaultScale(); if (types.GetGeoType() == GEOM_POINT) for (uint32_t t : types) scale = min(scale, GetScaleForType(t)); CorrectScaleForVisibility(types, scale); return scale; } private: static int GetDefaultScale() { return scales::GetUpperComfortScale(); } // Returns width and height (lon and lat) for a given type. int GetScaleForType(uint32_t const type) const { if (type == m_TypeContinent) return 2; /// @todo Load countries bounding rects. if (type == m_TypeCountry) return 4; if (type == m_TypeState) return 6; if (IsEqual(type, m_TypeCounty)) return 7; if (type == m_TypeCity || type == m_TypeCityCapital) return 9; if (type == m_TypeTown) return 9; if (IsEqual(type, m_TypeVillage)) return 12; if (IsEqual(type, m_TypeSmallVillage)) return 14; return GetDefaultScale(); } static uint32_t GetType(string const & s1, string const & s2 = string(), string const & s3 = string()) { vector path; path.push_back(s1); if (!s2.empty()) path.push_back(s2); if (!s3.empty()) path.push_back(s3); return classif().GetTypeByPath(path); } uint32_t m_TypeContinent; uint32_t m_TypeCountry; uint32_t m_TypeState; uint32_t m_TypeCounty[2]; uint32_t m_TypeCity; uint32_t m_TypeCityCapital; uint32_t m_TypeTown; uint32_t m_TypeVillage[2]; uint32_t m_TypeSmallVillage[3]; }; FeatureEstimator const & GetFeatureEstimator() { static FeatureEstimator const featureEstimator; return featureEstimator; } } // namespace feature::impl int GetFeatureViewportScale(TypesHolder const & types) { return impl::GetFeatureEstimator().GetViewportScale(types); } } // namespace feature