diff --git a/search/mwm_traits.cpp b/search/mwm_traits.cpp index c9f3b10d37..2f15e2b897 100644 --- a/search/mwm_traits.cpp +++ b/search/mwm_traits.cpp @@ -10,11 +10,7 @@ MwmTraits::SearchIndexFormat MwmTraits::GetSearchIndexFormat() const { if (m_versionFormat < version::v7) return SearchIndexFormat::FeaturesWithRankAndCenter; - if (m_versionFormat == version::v7) - return SearchIndexFormat::CompressedBitVector; - - LOG(LWARNING, ("Unknown search index format.")); - return SearchIndexFormat::Unknown; + return SearchIndexFormat::CompressedBitVector; } MwmTraits::HouseToStreetTableFormat MwmTraits::GetHouseToStreetTableFormat() const @@ -32,8 +28,6 @@ string DebugPrint(MwmTraits::SearchIndexFormat format) return "FeaturesWithRankAndCenter"; case MwmTraits::SearchIndexFormat::CompressedBitVector: return "CompressedBitVector"; - case MwmTraits::SearchIndexFormat::Unknown: - return "Unknown"; } } diff --git a/search/mwm_traits.hpp b/search/mwm_traits.hpp index eb90a87e9e..2d30443937 100644 --- a/search/mwm_traits.hpp +++ b/search/mwm_traits.hpp @@ -22,10 +22,6 @@ public: // stored behind every node of the search trie. // This format corresponds to ValueList. CompressedBitVector, - - // The format of the search index is unknown. Most - // likely, an error has occured. - Unknown }; enum class HouseToStreetTableFormat diff --git a/search/projection_on_street.cpp b/search/projection_on_street.cpp index 92a88a9d29..1e27f0f24d 100644 --- a/search/projection_on_street.cpp +++ b/search/projection_on_street.cpp @@ -21,18 +21,20 @@ ProjectionOnStreetCalculator::ProjectionOnStreetCalculator(vector co double maxDistMeters) : m_points(points), m_maxDistMeters(maxDistMeters) { - if (m_points.empty()) - return; + Init(); +} - m_segProjs.resize(m_points.size() - 1); - for (size_t i = 0; i + 1 != m_points.size(); ++i) - m_segProjs[i].SetBounds(m_points[i], m_points[i + 1]); +ProjectionOnStreetCalculator::ProjectionOnStreetCalculator(vector && points, + double maxDistMeters) + : m_points(move(points)), m_maxDistMeters(maxDistMeters) +{ + Init(); } bool ProjectionOnStreetCalculator::GetProjection(m2::PointD const & point, - ProjectionOnStreet & proj) + ProjectionOnStreet & proj) const { - static size_t const kInvalidIndex = m_points.size(); + size_t const kInvalidIndex = m_segProjs.size(); m2::PointD bestProj; size_t bestIndex = kInvalidIndex; @@ -59,4 +61,14 @@ bool ProjectionOnStreetCalculator::GetProjection(m2::PointD const & point, proj.m_projSign = m2::GetOrientation(m_points[bestIndex], m_points[bestIndex + 1], point); return true; } + +void ProjectionOnStreetCalculator::Init() +{ + if (m_points.empty()) + return; + + m_segProjs.resize(m_points.size() - 1); + for (size_t i = 0; i + 1 != m_points.size(); ++i) + m_segProjs[i].SetBounds(m_points[i], m_points[i + 1]); +} } // namespace search diff --git a/search/projection_on_street.hpp b/search/projection_on_street.hpp index f82039b592..db7a9bb626 100644 --- a/search/projection_on_street.hpp +++ b/search/projection_on_street.hpp @@ -32,15 +32,18 @@ public: static int constexpr kDefaultMaxDistMeters = 200; ProjectionOnStreetCalculator(vector const & points, double maxDistMeters); + ProjectionOnStreetCalculator(vector && points, double maxDistMeters); // Finds nearest point on the street to the |point|. If such point // is located within |m_maxDistMeters|, stores projection in |proj| // and returns true. Otherwise, returns false and does not modify // |proj|. - bool GetProjection(m2::PointD const & point, ProjectionOnStreet & proj); + bool GetProjection(m2::PointD const & point, ProjectionOnStreet & proj) const; private: - vector const & m_points; + void Init(); + + vector const m_points; vector> m_segProjs; double const m_maxDistMeters; }; diff --git a/search/search_integration_tests/search_query_v2_test.cpp b/search/search_integration_tests/search_query_v2_test.cpp index 017536bba7..139fdf5008 100644 --- a/search/search_integration_tests/search_query_v2_test.cpp +++ b/search/search_integration_tests/search_query_v2_test.cpp @@ -82,7 +82,7 @@ UNIT_TEST(SearchQueryV2_Smoke) "1 unit 1", *feynmanStreet, "en"); auto const bohrHouse = make_shared(m2::PointD(10, 10), "Bohr house", "1 unit 1", *bohrStreet, "en"); - auto const gilbertHouse = make_shared(m2::PointD(10.0005, 10.0005), "Gilbert house", + auto const hilbertHouse = make_shared(m2::PointD(10.0005, 10.0005), "Hilbert house", "1 unit 2", *bohrStreet, "en"); { @@ -97,7 +97,7 @@ UNIT_TEST(SearchQueryV2_Smoke) builder.Add(*bohrStreet); builder.Add(*feynmanHouse); builder.Add(*bohrHouse); - builder.Add(*gilbertHouse); + builder.Add(*hilbertHouse); } auto const regResult = engine.RegisterMap(map); @@ -158,7 +158,7 @@ UNIT_TEST(SearchQueryV2_Smoke) request.Wait(); vector> rules = { make_shared(regResult.first, bohrHouse), - make_shared(regResult.first, gilbertHouse)}; + make_shared(regResult.first, hilbertHouse)}; TEST(MatchResults(engine, rules, request.Results()), ()); } diff --git a/search/search_tests_support/test_feature.cpp b/search/search_tests_support/test_feature.cpp index a4ec7a21ad..eddd3f6bf0 100644 --- a/search/search_tests_support/test_feature.cpp +++ b/search/search_tests_support/test_feature.cpp @@ -88,7 +88,7 @@ void TestStreet::Serialize(FeatureBuilder1 & fb) const { CHECK(fb.AddName(m_lang, m_name), ("Can't set feature name:", m_name, "(", m_lang, ")")); if (m_lang != "default") - CHECK(fb.AddName("default", m_name), ("Can't set feature name:", m_name, "( default ")); + CHECK(fb.AddName("default", m_name), ("Can't set feature name:", m_name, "( default )")); auto const & classificator = classif(); fb.SetType(classificator.GetTypeByPath({"highway", "living_street"})); @@ -136,7 +136,7 @@ void TestBuilding::Serialize(FeatureBuilder1 & fb) const bool TestBuilding::Matches(FeatureType const & feature) const { - static ftypes::IsBuildingChecker const & checker = ftypes::IsBuildingChecker::Instance(); + auto const & checker = ftypes::IsBuildingChecker::Instance(); if (!checker(feature)) return false; return TestFeature::Matches(feature) && m_houseNumber == feature.GetHouseNumber(); diff --git a/search/v2/features_layer_path_finder.cpp b/search/v2/features_layer_path_finder.cpp index 0e5d26f986..32f32bf31b 100644 --- a/search/v2/features_layer_path_finder.cpp +++ b/search/v2/features_layer_path_finder.cpp @@ -8,12 +8,8 @@ namespace search { namespace v2 { -FeaturesLayerPathFinder::FeaturesLayerPathFinder(FeaturesLayerMatcher & matcher) - : m_matcher(matcher) -{ -} - -void FeaturesLayerPathFinder::BuildGraph(vector const & layers) +void FeaturesLayerPathFinder::BuildGraph(FeaturesLayerMatcher & matcher, + vector const & layers) { m_graph.clear(); @@ -30,7 +26,7 @@ void FeaturesLayerPathFinder::BuildGraph(vector const & layers) { m_graph[to].push_back(from); }; - m_matcher.Match(child, parent, addEdges); + matcher.Match(child, parent, addEdges); } } diff --git a/search/v2/features_layer_path_finder.hpp b/search/v2/features_layer_path_finder.hpp index d2851edb0e..ad184f0ba5 100644 --- a/search/v2/features_layer_path_finder.hpp +++ b/search/v2/features_layer_path_finder.hpp @@ -21,15 +21,14 @@ public: using TAdjList = vector; using TLayerGraph = unordered_map; - FeaturesLayerPathFinder(FeaturesLayerMatcher & matcher); - template - void ForEachReachableVertex(vector const & layers, TFn && fn) + void ForEachReachableVertex(FeaturesLayerMatcher & matcher, + vector const & layers, TFn && fn) { if (layers.empty()) return; - BuildGraph(layers); + BuildGraph(matcher, layers); m_visited.clear(); for (uint32_t featureId : (*layers.back()).m_sortedFeatures) @@ -43,11 +42,10 @@ public: } private: - void BuildGraph(vector const & layers); + void BuildGraph(FeaturesLayerMatcher & matcher, vector const & layers); void Dfs(uint32_t u); - FeaturesLayerMatcher & m_matcher; TLayerGraph m_graph; unordered_set m_visited; }; diff --git a/search/v2/geocoder.cpp b/search/v2/geocoder.cpp index fee93786e7..b00edaae5c 100644 --- a/search/v2/geocoder.cpp +++ b/search/v2/geocoder.cpp @@ -2,7 +2,6 @@ #include "search/retrieval.hpp" #include "search/v2/features_layer_matcher.hpp" -#include "search/v2/features_layer_path_finder.hpp" #include "search/search_delimiters.hpp" #include "search/search_string_utils.hpp" @@ -99,7 +98,6 @@ void Geocoder::Go(vector & results) MY_SCOPE_GUARD(cleanup, [&]() { - m_finder.reset(); m_matcher.reset(); m_loader.reset(); m_cache.clear(); @@ -109,7 +107,6 @@ void Geocoder::Go(vector & results) m_loader.reset(new Index::FeaturesLoaderGuard(m_index, m_mwmId)); m_matcher.reset( new FeaturesLayerMatcher(m_index, m_mwmId, *m_value, m_loader->GetFeaturesVector())); - m_finder.reset(new FeaturesLayerPathFinder(*m_matcher)); DoGeocoding(0 /* curToken */); } @@ -269,7 +266,7 @@ void Geocoder::FindPaths() sortedLayers.push_back(&layer); sort(sortedLayers.begin(), sortedLayers.end(), compareByType); - m_finder->ForEachReachableVertex(sortedLayers, [this](uint32_t featureId) + m_finder.ForEachReachableVertex(*m_matcher, sortedLayers, [this](uint32_t featureId) { m_results->emplace_back(m_mwmId, featureId); }); diff --git a/search/v2/geocoder.hpp b/search/v2/geocoder.hpp index b0ea4769e3..d9cd5f9d3b 100644 --- a/search/v2/geocoder.hpp +++ b/search/v2/geocoder.hpp @@ -2,6 +2,7 @@ #include "search/search_query_params.hpp" #include "search/v2/features_layer.hpp" +#include "search/v2/features_layer_path_finder.hpp" #include "search/v2/search_model.hpp" #include "indexer/mwm_set.hpp" @@ -35,7 +36,6 @@ class RankTable; namespace v2 { class FeaturesLayerMatcher; -class FeaturesLayerPathFinder; class SearchModel; // This class is used to retrieve all features corresponding to a @@ -122,7 +122,7 @@ private: unique_ptr m_matcher; // Path finder for interpretations. - unique_ptr m_finder; + FeaturesLayerPathFinder m_finder; // Search query params prepared for retrieval. SearchQueryParams m_retrievalParams; diff --git a/search/v2/house_to_street_table.hpp b/search/v2/house_to_street_table.hpp index 7c89bac4ac..af06a4bd46 100644 --- a/search/v2/house_to_street_table.hpp +++ b/search/v2/house_to_street_table.hpp @@ -16,9 +16,8 @@ public: static unique_ptr Load(MwmValue & value); - // Returns an order number for a street corresponding to |houseId|. - // The order number is an index of a street in a list returned - // by ReverseGeocoder::GetNearbyStreets(). + // Returns an index number of a correct street corresponding to a + // house in a list of streets generated by ReverseGeocoder. virtual uint32_t Get(uint32_t houseId) const = 0; }; } // namespace v2 diff --git a/search/v2/street_vicinity_loader.cpp b/search/v2/street_vicinity_loader.cpp index 66aa027beb..8088c83e9d 100644 --- a/search/v2/street_vicinity_loader.cpp +++ b/search/v2/street_vicinity_loader.cpp @@ -6,6 +6,8 @@ #include "geometry/mercator.hpp" +#include "geometry/point2d.hpp" + #include "base/math.hpp" #include "base/stl_add.hpp" @@ -39,9 +41,10 @@ void StreetVicinityLoader::LoadStreet(uint32_t featureId, Street & street) if (feature.GetFeatureType() != feature::GEOM_LINE) return; - feature.ForEachPoint(MakeBackInsertFunctor(street.m_points), FeatureType::BEST_GEOMETRY); + vector points; + feature.ForEachPoint(MakeBackInsertFunctor(points), FeatureType::BEST_GEOMETRY); - for (auto const & point : street.m_points) + for (auto const & point : points) street.m_rect.Add(MercatorBounds::RectByCenterXYAndSizeInMeters(point, m_offsetMeters)); covering::CoveringGetter coveringGetter(street.m_rect, covering::ViewportWithLowLevels); @@ -49,5 +52,8 @@ void StreetVicinityLoader::LoadStreet(uint32_t featureId, Street & street) for (auto const & interval : intervals) m_index.ForEachInIntervalAndScale(MakeBackInsertFunctor(street.m_features), interval.first, interval.second, m_scale); + + if (!points.empty()) + street.m_calculator = make_unique(move(points), m_offsetMeters); } } // namespace search diff --git a/search/v2/street_vicinity_loader.hpp b/search/v2/street_vicinity_loader.hpp index dc2ffdb02c..54b175e64e 100644 --- a/search/v2/street_vicinity_loader.hpp +++ b/search/v2/street_vicinity_loader.hpp @@ -27,11 +27,11 @@ public: Street() = default; Street(Street && street) = default; - inline bool IsEmpty() const { return m_points.empty() || m_rect.IsEmptyInterior(); } + inline bool IsEmpty() const { return !m_calculator || m_rect.IsEmptyInterior(); } - vector m_points; vector m_features; m2::RectD m_rect; + unique_ptr m_calculator; DISALLOW_COPY(Street); }; @@ -48,9 +48,8 @@ public: if (street.IsEmpty()) return; - ProjectionOnStreetCalculator calculator(street.m_points, m_offsetMeters); + ProjectionOnStreetCalculator const & calculator = *street.m_calculator; ProjectionOnStreet proj; - for (uint32_t id : street.m_features) { // Load center and check projection only when |id| is in |sortedIds|. @@ -73,9 +72,8 @@ public: if (street.IsEmpty()) return; - ProjectionOnStreetCalculator calculator(street.m_points, m_offsetMeters); + ProjectionOnStreetCalculator const & calculator = *street.m_calculator; ProjectionOnStreet proj; - for (uint32_t id : street.m_features) { FeatureType ft;