[search] Expose user position to Geocoder.

This commit is contained in:
Yuri Gorshenin 2015-12-24 19:32:40 +03:00 committed by Sergey Yershov
parent 7ad477761d
commit 9911aa68bd
6 changed files with 61 additions and 17 deletions

View file

@ -233,6 +233,12 @@ void Engine::DoSearch(SearchParams const & params, m2::RectD const & viewport,
}
SetRankPivot(params, viewport, viewportSearch);
if (params.IsValidPosition())
m_query->SetPosition(MercatorBounds::FromLatLon(params.m_lat, params.m_lon));
else
m_query->SetPosition(viewport.Center());
m_query->SetSearchInWorld(params.HasSearchMode(SearchParams::SEARCH_WORLD));
m_query->SetInputLocale(params.m_inputLocale);

View file

@ -222,6 +222,7 @@ Query::Query(Index & index, CategoriesHolder const & categories, vector<Suggest>
#ifdef FIND_LOCALITY_TEST
, m_locality(&index)
#endif
, m_position(0, 0)
, m_worldSearch(true)
, m_keepHouseNumberInQuery(false)
{

View file

@ -84,6 +84,7 @@ public:
void SetViewport(m2::RectD const & viewport, bool forceUpdate);
void SetRankPivot(m2::PointD const & pivot);
inline string const & GetPivotRegion() const { return m_region; }
inline void SetPosition(m2::PointD const & position) { m_position = position; }
inline void SetSearchInWorld(bool b) { m_worldSearch = b; }
@ -231,6 +232,7 @@ protected:
m2::RectD m_viewport[COUNT_V];
m2::PointD m_pivot;
m2::PointD m_position;
bool m_worldSearch;
Retrieval m_retrieval;

View file

@ -34,9 +34,6 @@ namespace v2
{
namespace
{
// 50km maximum viewport radius.
double const kMaxViewportRadiusM = 50.0 * 1000;
void JoinQueryTokens(SearchQueryParams const & params, size_t curToken, size_t endToken,
string const & sep, string & res)
{
@ -78,7 +75,7 @@ MwmSet::MwmHandle FindWorld(Index & index, vector<shared_ptr<MwmInfo>> & infos)
} // namespace
// Geocoder::Params --------------------------------------------------------------------------------
Geocoder::Params::Params() : m_maxNumResults(0) {}
Geocoder::Params::Params() : m_position(0, 0), m_maxNumResults(0) {}
// Geocoder::Geocoder ------------------------------------------------------------------------------
Geocoder::Geocoder(Index & index)
@ -301,18 +298,54 @@ void Geocoder::DoGeocodingWithLocalities()
void Geocoder::DoGeocodingWithoutLocalities()
{
// TODO (@y, @m, @vng): consider to add user position here, to
// inflate viewport if too small number of results is found, etc.
// Limits viewport by kMaxViewportRadiusM.
m2::RectD const viewportLimit = MercatorBounds::RectByCenterXYAndSizeInMeters(
m_params.m_viewport.Center(), kMaxViewportRadiusM);
m2::RectD rect = m_params.m_viewport;
rect.Intersect(viewportLimit);
if (rect.IsEmptyInterior())
return;
// 50km maximum viewport radius.
double constexpr kMaxViewportRadiusM = 50.0 * 1000;
m_filter.SetFilter(Retrieval::RetrieveGeometryFeatures(
m_context->m_value, static_cast<my::Cancellable const &>(*this), rect, m_params.m_scale));
// 50km radius around position.
double constexpr kMaxPositionRadiusM = 50.0 * 1000;
double constexpr kEps = 1.0e-5;
m2::RectD const & viewport = m_params.m_viewport;
m2::PointD const & position = m_params.m_position;
// Extracts features in viewport.
unique_ptr<coding::CompressedBitVector> viewportFeatures;
{
// Limits viewport by kMaxViewportRadiusM.
m2::RectD const viewportLimit =
MercatorBounds::RectByCenterXYAndSizeInMeters(viewport.Center(), kMaxViewportRadiusM);
m2::RectD rect = viewport;
rect.Intersect(viewportLimit);
if (!rect.IsEmptyInterior())
{
viewportFeatures = Retrieval::RetrieveGeometryFeatures(
m_context->m_value, static_cast<my::Cancellable const &>(*this), rect, m_params.m_scale);
}
}
// Extracts features around user position.
unique_ptr<coding::CompressedBitVector> positionFeatures;
if (!position.EqualDxDy(viewport.Center(), kEps))
{
m2::RectD const rect =
MercatorBounds::RectByCenterXYAndSizeInMeters(position, kMaxPositionRadiusM);
positionFeatures = Retrieval::RetrieveGeometryFeatures(
m_context->m_value, static_cast<my::Cancellable const &>(*this), rect, m_params.m_scale);
}
if (coding::CompressedBitVector::IsEmpty(viewportFeatures) &&
coding::CompressedBitVector::IsEmpty(positionFeatures))
{
return;
}
if (coding::CompressedBitVector::IsEmpty(viewportFeatures))
m_filter.SetFilter(move(positionFeatures));
else if (coding::CompressedBitVector::IsEmpty(positionFeatures))
m_filter.SetFilter(move(viewportFeatures));
else
m_filter.SetFilter(coding::CompressedBitVector::Union(*viewportFeatures, *positionFeatures));
// Filter will be applied only for large bit vectors.
m_filter.SetThreshold(m_params.m_maxNumResults);
@ -497,8 +530,8 @@ void Geocoder::FindPaths()
m_finder.ForEachReachableVertex(*m_matcher, sortedLayers, [this](uint32_t featureId)
{
m_results->emplace_back(m_context->m_id, featureId);
});
m_results->emplace_back(m_context->m_id, featureId);
});
}
} // namespace v2
} // namespace search

View file

@ -62,6 +62,7 @@ public:
Params();
m2::RectD m_viewport;
m2::PointD m_position;
size_t m_maxNumResults;
};

View file

@ -40,6 +40,7 @@ void SearchQueryV2::Search(Results & res, size_t resCount)
Geocoder::Params params;
InitParams(false /* localitySearch */, params);
params.m_viewport = m_viewport[CURRENT_V];
params.m_position = m_position;
params.m_maxNumResults = max(resCount, kPreResultsCount);
m_geocoder.SetParams(params);