diff --git a/search/house_detector.cpp b/search/house_detector.cpp index 95498df05e..4425071c8c 100644 --- a/search/house_detector.cpp +++ b/search/house_detector.cpp @@ -669,7 +669,7 @@ void HouseDetector::ReadHouse(FeatureType const & f, Street * st, ProjectionCalc m2::PointD const pt = isNew ? f.GetLimitRect(FeatureType::BEST_GEOMETRY).Center() : it->second->GetPosition(); HouseProjection pr; - if (calc.GetProjection(pt, pr)) + if (calc.GetProjection(pt, pr) && pr.m_distMeters <= m_houseOffsetM) { pr.m_streetDistance = st->GetPrefixLength(pr.m_segIndex) + st->m_points[pr.m_segIndex].Length(pr.m_proj); @@ -692,15 +692,15 @@ void HouseDetector::ReadHouse(FeatureType const & f, Street * st, ProjectionCalc } } -void HouseDetector::ReadHouses(Street * st, double offsetMeters) +void HouseDetector::ReadHouses(Street * st) { if (st->m_housesReaded) return; //offsetMeters = max(HN_MIN_READ_OFFSET_M, min(GetApprLengthMeters(st->m_number) / 2, offsetMeters)); - ProjectionOnStreetCalculator calc(st->m_points, offsetMeters); - m_loader.ForEachInRect(st->GetLimitRect(offsetMeters), + ProjectionOnStreetCalculator calc(st->m_points); + m_loader.ForEachInRect(st->GetLimitRect(m_houseOffsetM), bind(&HouseDetector::ReadHouse, this, _1, st, ref(calc))); st->m_length = st->GetLength(); @@ -711,13 +711,13 @@ void HouseDetector::ReadAllHouses(double offsetMeters) { m_houseOffsetM = offsetMeters; - for (StreetMapT::iterator it = m_id2st.begin(); it != m_id2st.end(); ++it) - ReadHouses(it->second, offsetMeters); + for (auto const & e : m_id2st) + ReadHouses(e.second); - for (size_t i = 0; i < m_streets.size(); ++i) + for (auto & st : m_streets) { - if (!m_streets[i].IsHousesReaded()) - m_streets[i].FinishReadingHouses(); + if (!st.IsHousesReaded()) + st.FinishReadingHouses(); } } diff --git a/search/house_detector.hpp b/search/house_detector.hpp index d13258dc1a..cbd8131475 100644 --- a/search/house_detector.hpp +++ b/search/house_detector.hpp @@ -245,7 +245,7 @@ class HouseDetector template void ReadHouse(FeatureType const & f, Street * st, ProjectionCalcT & calc); - void ReadHouses(Street * st, double offsetMeters); + void ReadHouses(Street * st); void SetMetres2Mercator(double factor); @@ -259,7 +259,7 @@ public: /// @return number of different joined streets. int MergeStreets(); - static int const DEFAULT_OFFSET_M = ProjectionOnStreetCalculator::kDefaultMaxDistMeters; + static int const DEFAULT_OFFSET_M = 200; void ReadAllHouses(double offsetMeters = DEFAULT_OFFSET_M); void GetHouseForName(string const & houseNumber, vector & res); diff --git a/search/projection_on_street.cpp b/search/projection_on_street.cpp index 6af1a1bb51..492e65bd3a 100644 --- a/search/projection_on_street.cpp +++ b/search/projection_on_street.cpp @@ -4,14 +4,9 @@ #include "geometry/robust_orientation.hpp" -#include "base/assert.hpp" - namespace search { -namespace -{ -} // namespace // ProjectionOnStreet ------------------------------------------------------------------------------ ProjectionOnStreet::ProjectionOnStreet() @@ -20,11 +15,15 @@ ProjectionOnStreet::ProjectionOnStreet() } // ProjectionOnStreetCalculator -------------------------------------------------------------------- -ProjectionOnStreetCalculator::ProjectionOnStreetCalculator(vector const & points, - double maxDistMeters) - : m_maxDistMeters(maxDistMeters) +ProjectionOnStreetCalculator::ProjectionOnStreetCalculator(vector const & points) { - Init(points); + size_t const count = points.size(); + if (count < 2) + return; + + m_segProjs.resize(count - 1); + for (size_t i = 0; i + 1 != count; ++i) + m_segProjs[i].SetBounds(points[i], points[i + 1]); } bool ProjectionOnStreetCalculator::GetProjection(m2::PointD const & point, @@ -49,17 +48,7 @@ bool ProjectionOnStreetCalculator::GetProjection(m2::PointD const & point, } } - return (proj.m_segIndex < kInvalidIndex && proj.m_distMeters <= m_maxDistMeters); + return (proj.m_segIndex < kInvalidIndex); } -void ProjectionOnStreetCalculator::Init(vector const & points) -{ - size_t const count = points.size(); - if (count < 2) - return; - - m_segProjs.resize(count - 1); - for (size_t i = 0; i + 1 != count; ++i) - m_segProjs[i].SetBounds(points[i], points[i + 1]); -} } // namespace search diff --git a/search/projection_on_street.hpp b/search/projection_on_street.hpp index c62629c90b..bd89d3530d 100644 --- a/search/projection_on_street.hpp +++ b/search/projection_on_street.hpp @@ -29,9 +29,7 @@ struct ProjectionOnStreet class ProjectionOnStreetCalculator { public: - static int constexpr kDefaultMaxDistMeters = 200; - - ProjectionOnStreetCalculator(vector const & points, double maxDistMeters); + explicit ProjectionOnStreetCalculator(vector const & points); // Finds nearest point on the street to the |point|. If such point // is located within |m_maxDistMeters|, stores projection in |proj| @@ -40,9 +38,6 @@ public: bool GetProjection(m2::PointD const & point, ProjectionOnStreet & proj) const; private: - void Init(vector const & points); - vector> m_segProjs; - double const m_maxDistMeters; }; } // namespace search diff --git a/search/v2/features_layer_matcher.cpp b/search/v2/features_layer_matcher.cpp index b638bc1077..475d8058b0 100644 --- a/search/v2/features_layer_matcher.cpp +++ b/search/v2/features_layer_matcher.cpp @@ -10,8 +10,6 @@ namespace search { namespace v2 { -// static -double const FeaturesLayerMatcher::kBuildingRadiusMeters = 50; FeaturesLayerMatcher::FeaturesLayerMatcher(Index & index, my::Cancellable const & cancellable) : m_context(nullptr) diff --git a/search/v2/features_layer_matcher.hpp b/search/v2/features_layer_matcher.hpp index 2ea2bf50ec..0505203cce 100644 --- a/search/v2/features_layer_matcher.hpp +++ b/search/v2/features_layer_matcher.hpp @@ -57,7 +57,8 @@ class FeaturesLayerMatcher { public: static uint32_t const kInvalidId = numeric_limits::max(); - static double const kBuildingRadiusMeters; + static int const kMatchPoiToBuildingRadiusMeters = 50; + static int const kMatchPoiToStreetRadiusMeters = 100; FeaturesLayerMatcher(Index & index, my::Cancellable const & cancellable); void SetContext(MwmContext * context); @@ -84,7 +85,7 @@ public: break; case SearchModel::SEARCH_TYPE_STREET: ASSERT(child.m_type == SearchModel::SEARCH_TYPE_POI || - child.m_type == SearchModel::SEARCH_TYPE_BUILDING, + child.m_type == SearchModel::SEARCH_TYPE_BUILDING, ("Invalid child layer type:", child.m_type)); if (child.m_type == SearchModel::SEARCH_TYPE_POI) MatchPOIsWithStreets(child, parent, forward(fn)); @@ -138,7 +139,7 @@ private: continue; double const distMeters = feature::GetMinDistanceMeters(buildingFt, poiCenters[j]); - if (distMeters <= kBuildingRadiusMeters) + if (distMeters <= kMatchPoiToBuildingRadiusMeters) { fn(pois[j], buildings[i]); isPOIProcessed[j] = true; @@ -161,13 +162,13 @@ private: for (size_t i = 0; i < pois.size(); ++i) { m_context->ForEachFeature( - MercatorBounds::RectByCenterXYAndSizeInMeters(poiCenters[i], kBuildingRadiusMeters), + MercatorBounds::RectByCenterXYAndSizeInMeters(poiCenters[i], kMatchPoiToBuildingRadiusMeters), [&](FeatureType & ft) { if (HouseNumbersMatch(strings::MakeUniString(ft.GetHouseNumber()), queryTokens)) { double const distanceM = MercatorBounds::DistanceOnEarth(feature::GetCenter(ft), poiCenters[i]); - if (distanceM < kBuildingRadiusMeters) + if (distanceM < kMatchPoiToBuildingRadiusMeters) fn(pois[i], ft.GetID().m_index); } }); @@ -191,6 +192,9 @@ private: { for (auto const & street : GetNearbyStreets(poiId)) { + if (street.m_distanceMeters > kMatchPoiToStreetRadiusMeters) + break; + uint32_t const streetId = street.m_id.m_index; if (binary_search(streets.begin(), streets.end(), streetId)) fn(poiId, streetId); @@ -202,7 +206,8 @@ private: for (uint32_t streetId : streets) { BailIfCancelled(m_cancellable); - m_loader.ForEachInVicinity(streetId, pois, bind(fn, _1, streetId)); + m_loader.ForEachInVicinity(streetId, pois, kMatchPoiToStreetRadiusMeters, + bind(fn, _1, streetId)); } } @@ -308,11 +313,12 @@ private: // house-to-street table was generated by using high-precision // centers of features. m2::PointD const center = feature::GetCenter(feature); - if (!calculator.GetProjection(center, proj)) - continue; - - if (GetMatchingStreet(houseId, feature) == streetId) + if (calculator.GetProjection(center, proj) && + proj.m_distMeters <= ReverseGeocoder::kLookupRadiusM && + GetMatchingStreet(houseId, feature) == streetId) + { fn(houseId, streetId); + } } } } diff --git a/search/v2/street_vicinity_loader.cpp b/search/v2/street_vicinity_loader.cpp index 331b8eddcf..5f88ba1302 100644 --- a/search/v2/street_vicinity_loader.cpp +++ b/search/v2/street_vicinity_loader.cpp @@ -69,7 +69,7 @@ void StreetVicinityLoader::LoadStreet(uint32_t featureId, Street & street) interval.first, interval.second, m_scale); } - street.m_calculator = make_unique(points, m_offsetMeters); + street.m_calculator = make_unique(points); } } // namespace v2 } // namespace search diff --git a/search/v2/street_vicinity_loader.hpp b/search/v2/street_vicinity_loader.hpp index 64e57de815..ea3f32b7dd 100644 --- a/search/v2/street_vicinity_loader.hpp +++ b/search/v2/street_vicinity_loader.hpp @@ -49,8 +49,12 @@ public: // Calls |fn| on each index in |sortedIds| where sortedIds[index] // belongs to the street's vicinity. template - void ForEachInVicinity(uint32_t streetId, vector const & sortedIds, TFn const & fn) + void ForEachInVicinity(uint32_t streetId, vector const & sortedIds, + double offsetMeters, TFn const & fn) { + // Passed offset param should be less than the cached one, or the cache is invalid otherwise. + ASSERT_LESS_OR_EQUAL(offsetMeters, m_offsetMeters, ()); + Street const & street = GetStreet(streetId); if (street.IsEmpty()) return; @@ -65,10 +69,12 @@ public: FeatureType ft; m_context->GetFeature(id, ft); - if (!calculator.GetProjection(feature::GetCenter(ft, FeatureType::WORST_GEOMETRY), proj)) - continue; - fn(id); + if (calculator.GetProjection(feature::GetCenter(ft, FeatureType::WORST_GEOMETRY), proj) && + proj.m_distMeters <= offsetMeters) + { + fn(id); + } } }