From 0744caab50179bdab2adf2ad5ef809f05eb8a593 Mon Sep 17 00:00:00 2001 From: tatiana-yan Date: Thu, 19 Mar 2020 15:18:01 +0300 Subject: [PATCH] [search] Unite MwmInfoWithType and KeyedMwmInfo. --- search/geocoder.cpp | 98 ++++++++++++++++++++++----------------------- search/geocoder.hpp | 29 ++++++++++---- 2 files changed, 68 insertions(+), 59 deletions(-) diff --git a/search/geocoder.cpp b/search/geocoder.cpp index 2d076dbe50..d4b19018d6 100644 --- a/search/geocoder.cpp +++ b/search/geocoder.cpp @@ -259,31 +259,6 @@ double GetDistanceMeters(m2::PointD const & pivot, m2::RectD const & rect) return distance; } -struct KeyedMwmInfo -{ - KeyedMwmInfo(shared_ptr const & info, optional const & position, - m2::RectD const & pivot, bool inViewport) - : m_info(info) - { - auto const & rect = m_info->m_bordersRect; - m_similarity = GetSimilarity(pivot, rect); - m_distance = GetDistanceMeters(pivot.Center(), rect); - if (!inViewport && position && rect.IsPointInside(*position)) - m_distance = 0.0; - } - - bool operator<(KeyedMwmInfo const & rhs) const - { - if (m_distance == 0.0 && rhs.m_distance == 0.0) - return m_similarity > rhs.m_similarity; - return m_distance < rhs.m_distance; - } - - shared_ptr m_info; - double m_similarity; - double m_distance; -}; - unique_ptr GetWorldContext(DataSource const & dataSource) { vector> infos; @@ -299,6 +274,15 @@ unique_ptr GetWorldContext(DataSource const & dataSource) SCOPE_GUARD(tracerGuard, [&] { m_resultTracer.LeaveMethod(ResultTracer::Branch::branch); }); } // namespace +// Geocoder::ExtendedMwmInfos::ExtendedMwmInfo ----------------------------------------------------- +bool Geocoder::ExtendedMwmInfos::ExtendedMwmInfo::operator<( + Geocoder::ExtendedMwmInfos::ExtendedMwmInfo const & rhs) const +{ + if (m_distance == 0.0 && rhs.m_distance == 0.0) + return m_similarity > rhs.m_similarity; + return m_distance < rhs.m_distance; +} + // Geocoder::Geocoder ------------------------------------------------------------------------------ Geocoder::Geocoder(DataSource const & dataSource, storage::CountryInfoGetter const & infoGetter, CategoriesHolder const & categories, @@ -440,15 +424,30 @@ void Geocoder::SetParamsForCategorialSearch(Params const & params) LOG(LDEBUG, (static_cast(m_params))); } -Geocoder::MwmInfosWithType Geocoder::OrderCountries(bool inViewport, +Geocoder::ExtendedMwmInfos::ExtendedMwmInfo Geocoder::GetExtendedMwmInfo( + shared_ptr const & info, bool inViewport, + function const &)> const & isMwmWithMatchedCity) const +{ + ExtendedMwmInfos::ExtendedMwmInfo extendedInfo; + extendedInfo.m_info = info; + + auto const & rect = info->m_bordersRect; + extendedInfo.m_type.m_viewportIntersected = m_params.m_pivot.IsIntersect(rect); + extendedInfo.m_type.m_containsUserPosition = + m_params.m_position && rect.IsPointInside(*m_params.m_position); + extendedInfo.m_type.m_containsMatchedCity = isMwmWithMatchedCity(info); + + extendedInfo.m_similarity = GetSimilarity(m_params.m_pivot, rect); + if (!inViewport && extendedInfo.m_type.m_containsUserPosition) + extendedInfo.m_distance = 0.0; + else + extendedInfo.m_distance = GetDistanceMeters(m_params.m_pivot.Center(), rect); + return extendedInfo; +} + +Geocoder::ExtendedMwmInfos Geocoder::OrderCountries(bool inViewport, vector> const & infos) { - vector keyedInfos; - keyedInfos.reserve(infos.size()); - for (auto const & info : infos) - keyedInfos.emplace_back(info, m_params.m_position, m_params.m_pivot, inViewport); - sort(keyedInfos.begin(), keyedInfos.end()); - set mwmsWithCities; if (!inViewport) { @@ -459,21 +458,18 @@ Geocoder::MwmInfosWithType Geocoder::OrderCountries(bool inViewport, } } - auto const getMwmType = [&](auto const & info) { - MwmType mwmType; - mwmType.m_viewportIntersected = m_params.m_pivot.IsIntersect(info->m_bordersRect); - mwmType.m_containsUserPosition = - m_params.m_position && info->m_bordersRect.IsPointInside(*m_params.m_position); - mwmType.m_containsMatchedCity = mwmsWithCities.count(info->GetCountryName()) != 0; - return mwmType; - }; + ExtendedMwmInfos res; + res.m_infos.reserve(infos.size()); + for (auto const & info : infos) + { + res.m_infos.push_back(GetExtendedMwmInfo(info, inViewport, [&mwmsWithCities](auto const & i) { + return mwmsWithCities.count(i->GetCountryName()) != 0; + })); + } + sort(res.m_infos.begin(), res.m_infos.end()); - MwmInfosWithType res; - for (auto const & info : keyedInfos) - res.m_infos.emplace_back(info.m_info, getMwmType(info.m_info)); - - auto const firstBatch = [&](auto const & infoWithType) { - return infoWithType.second.IsFirstBatchMwm(inViewport); + auto const firstBatch = [&](auto const & extendedInfo) { + return extendedInfo.m_type.IsFirstBatchMwm(inViewport); }; auto const sep = stable_partition(res.m_infos.begin(), res.m_infos.end(), firstBatch); res.m_firstBatchSize = distance(res.m_infos.begin(), sep); @@ -798,11 +794,11 @@ bool Geocoder::CityHasPostcode(BaseContext const & ctx) const } template -void Geocoder::ForEachCountry(MwmInfosWithType const & infosWithType, Fn && fn) +void Geocoder::ForEachCountry(ExtendedMwmInfos const & extendedInfos, Fn && fn) { - for (size_t i = 0; i < infosWithType.m_infos.size(); ++i) + for (size_t i = 0; i < extendedInfos.m_infos.size(); ++i) { - auto const & info = infosWithType.m_infos[i].first; + auto const & info = extendedInfos.m_infos[i].m_info; if (info->GetType() != MwmInfo::COUNTRY && info->GetType() != MwmInfo::WORLD) continue; if (info->GetType() == MwmInfo::COUNTRY && m_params.m_mode == Mode::Downloader) @@ -814,8 +810,8 @@ void Geocoder::ForEachCountry(MwmInfosWithType const & infosWithType, Fn && fn) auto & value = *handle.GetValue(); if (!value.HasSearchIndex() || !value.HasGeometryIndex()) continue; - bool const updatePreranker = i + 1 >= infosWithType.m_firstBatchSize; - auto const mwmType = infosWithType.m_infos[i].second; + bool const updatePreranker = i + 1 >= extendedInfos.m_firstBatchSize; + auto const & mwmType = extendedInfos.m_infos[i].m_type; if (fn(mwmType, make_unique(move(handle)), updatePreranker) == base::ControlFlow::Break) { diff --git a/search/geocoder.hpp b/search/geocoder.hpp index ce447e85ad..1880fab750 100644 --- a/search/geocoder.hpp +++ b/search/geocoder.hpp @@ -147,10 +147,19 @@ private: bool m_containsMatchedCity = false; }; - struct MwmInfosWithType + struct ExtendedMwmInfos { - using MwmInfoWithType = std::pair, MwmType>; - std::vector m_infos; + struct ExtendedMwmInfo + { + bool operator<(ExtendedMwmInfo const & rhs) const; + + std::shared_ptr m_info; + MwmType m_type; + double m_similarity; + double m_distance; + }; + + std::vector m_infos; size_t m_firstBatchSize = 0; }; @@ -203,7 +212,7 @@ private: bool CityHasPostcode(BaseContext const & ctx) const; template - void ForEachCountry(MwmInfosWithType const & infos, Fn && fn); + void ForEachCountry(ExtendedMwmInfos const & infos, Fn && fn); // Throws CancelException if cancelled. void BailIfCancelled() { ::search::BailIfCancelled(m_cancellable); } @@ -284,15 +293,19 @@ private: WARN_UNUSED_RESULT bool GetTypeInGeocoding(BaseContext const & ctx, uint32_t featureId, Model::Type & type); + ExtendedMwmInfos::ExtendedMwmInfo GetExtendedMwmInfo( + std::shared_ptr const & info, bool inViewport, + std::function const &)> const & isMwmWithMatchedCity) const; + // Reorders maps in a way that prefix consists of "best" maps to search and suffix consists of all - // other maps ordered by minimum distance from pivot. Returns MwmInfosWithType structure which + // other maps ordered by minimum distance from pivot. Returns ExtendedMwmInfos structure which // consists of vector of mwms with MwmType information and number of "best" maps to search. - // For viewport mode prefix consists of maps intersecting with pivot ordered by distance from pivot - // center. + // For viewport mode prefix consists of maps intersecting with pivot ordered by distance from + // pivot center. // For non-viewport search mode prefix consists of maps intersecting with pivot, map with user // location and maps with cities matched to the query, sorting prefers mwms that contain the // user's position. - MwmInfosWithType OrderCountries(bool inViewport, + ExtendedMwmInfos OrderCountries(bool inViewport, std::vector> const & infos); DataSource const & m_dataSource;