diff --git a/map/framework.cpp b/map/framework.cpp index d5932d178d..f63743f6e5 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -709,13 +709,22 @@ void Framework::FillFeatureInfo(FeatureID const & fid, place_page::Info & info) FillInfoFromFeatureType(ft, info); // Fill countryId for place page info + uint32_t const placeContinentType = classif().GetTypeByPath({"place", "continent"}); + if (info.GetTypes().Has(placeContinentType)) + return; + info.m_countryId = m_infoGetter->GetRegionCountryId(info.GetMercator()); - uint32_t placeCountryType = classif().GetTypeByPath({"place", "country"}); - if (info.GetTypes().Has(placeCountryType)) + uint32_t const placeCountryType = classif().GetTypeByPath({"place", "country"}); + uint32_t const placeStateType = classif().GetTypeByPath({"place", "state"}); + + bool const isState = info.GetTypes().Has(placeStateType); + bool const isCountry = info.GetTypes().Has(placeCountryType); + if (isCountry || isState) { + size_t const level = isState ? 1 : 0; TCountriesVec countries; - Storage().GetTopmostNodesFor(info.m_countryId, countries); + Storage().GetTopmostNodesFor(info.m_countryId, countries, level); if (countries.size() == 1) info.m_countryId = countries.front(); } diff --git a/storage/storage.cpp b/storage/storage.cpp index 4a6e889ada..b217119dc0 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -1625,10 +1625,11 @@ void Storage::GetGroupNodePathToRoot(TCountryId const & groupNode, TCountriesVec path.push_back(m_countries.GetRoot().Value().Name()); } -void Storage::GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & nodes) const +void Storage::GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & nodes, + size_t level) const { nodes.clear(); - + vector treeNodes; m_countries.Find(countryId, treeNodes); if (treeNodes.empty()) @@ -1641,11 +1642,14 @@ void Storage::GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & n for (size_t i = 0; i < treeNodes.size(); ++i) { nodes[i] = countryId; + TCountriesVec path; ForEachAncestorExceptForTheRoot({treeNodes[i]}, - [&nodes, i](TCountryId const & id, TCountryTreeNode const &) + [&path](TCountryId const & id, TCountryTreeNode const &) { - nodes[i] = id; + path.emplace_back(id); }); + if (!path.empty() && level < path.size()) + nodes[i] = path[path.size() - 1 - level]; } } diff --git a/storage/storage.hpp b/storage/storage.hpp index 45ca9545d8..d6af12dade 100644 --- a/storage/storage.hpp +++ b/storage/storage.hpp @@ -358,8 +358,10 @@ public: void GetGroupNodePathToRoot(TCountryId const & groupNode, TCountriesVec & path) const; /// \brief Fills |nodes| with CountryIds of topmost nodes for this |countryId|. + /// \param level is distance from top level except root. /// For disputed territories all possible owners will be added. - void GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & nodes) const; + /// Puts |countryId| to |nodes| when |level| is greater than the level of |countyId|. + void GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & nodes, size_t level = 0) const; /// \brief Returns current version for mwms which are used by storage. inline int64_t GetCurrentDataVersion() const { return m_currentVersion; } @@ -648,7 +650,7 @@ void Storage::ForEachInSubtree(TCountryId const & root, ToDo && toDo) const /// Calls functor |toDo| with signature /// void(const TCountryId const & parentId, TCountriesVec const & descendantCountryId) -/// for each ancestor except for the main root of the tree. +/// for each ancestor except for the main root of the tree in order from the leaf to the root. /// Note. In case of disputable territories several nodes with the same name may be /// present in the country tree. In that case ForEachAncestorExceptForTheRoot calls /// |toDo| for parents of each way to the root in the country tree. In case of diamond