[search] Temporary solution: sort results by it's real distance for AROUND_POSITION search mode.

This commit is contained in:
vng 2013-01-11 19:24:35 +03:00 committed by Alex Zolotarev
parent 7e8b40e59d
commit 4101361476
6 changed files with 72 additions and 29 deletions

View file

@ -133,25 +133,31 @@ bool PreResult1::LessViewportDistance(PreResult1 const & r1, PreResult1 const &
}
void PreResult2::CalcParams(m2::RectD const & viewport, m2::PointD const & pos)
{
// dummy object to avoid copy-paste
PreResult1 res(0, 0, m_center, 0, pos, viewport);
PreResult2::PreResult2(FeatureType const & f, PreResult1 const & res,
m_distance = res.m_distance;
m_distanceFromViewportCenter = res.m_distanceFromViewportCenter;
m_viewportDistance = res.m_viewportDistance;
}
PreResult2::PreResult2(FeatureType const & f, uint8_t rank,
m2::RectD const & viewport, m2::PointD const & pos,
string const & displayName, string const & fileName)
: m_types(f),
m_str(displayName),
m_featureRect(f.GetLimitRect(FeatureType::WORST_GEOMETRY)),
m_center(res.m_center),
m_distance(res.m_distance),
m_distanceFromViewportCenter(res.m_distanceFromViewportCenter),
m_resultType(RESULT_FEATURE),
m_rank(res.m_rank),
m_viewportDistance(res.m_viewportDistance)
m_rank(rank)
{
ASSERT ( !m_types.Empty(), () );
m_types.SortBySpec();
// It's better to get exact center for point feature.
if (f.GetFeatureType() == feature::GEOM_POINT)
m_center = m_featureRect.Center();
m_featureRect = f.GetLimitRect(FeatureType::WORST_GEOMETRY);
m_center = m_featureRect.Center();
CalcParams(viewport, pos);
// get region info
if (!fileName.empty())
@ -160,19 +166,16 @@ PreResult2::PreResult2(FeatureType const & f, PreResult1 const & res,
m_region.SetPoint(m_center);
}
PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos,
double lat, double lon)
PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, double lat, double lon)
: m_str("(" + strings::to_string(lat) + ", " + strings::to_string(lon) + ")"),
m_resultType(RESULT_LATLON), m_rank(255)
m_resultType(RESULT_LATLON),
m_rank(255)
{
// dummy object to avoid copy-paste
PreResult1 res(0, 0, m2::PointD(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat)),
0, pos, viewport);
m_center.x = MercatorBounds::LonToX(lon);
m_center.y = MercatorBounds::LatToY(lat);
m_featureRect.Add(m_center);
m_center = res.m_center;
m_distance = res.m_distance;
m_distanceFromViewportCenter = res.m_distanceFromViewportCenter;
m_viewportDistance = res.m_viewportDistance;
CalcParams(viewport, pos);
// get region info
m_region.SetPoint(m_center);

View file

@ -53,12 +53,15 @@ public:
static bool LessViewportDistance(PreResult1 const & r1, PreResult1 const & r2);
inline pair<size_t, uint32_t> GetID() const { return make_pair(m_mwmID, m_featureID); }
uint8_t GetRank() const { return m_rank; }
};
/// Second result class. Objects are creating during reading of features.
class PreResult2
{
void CalcParams(m2::RectD const & viewport, m2::PointD const & pos);
public:
enum ResultType
{
@ -68,7 +71,8 @@ public:
};
// For RESULT_FEATURE.
PreResult2(FeatureType const & f, PreResult1 const & res,
PreResult2(FeatureType const & f, uint8_t rank,
m2::RectD const & viewport, m2::PointD const & pos,
string const & displayName, string const & fileName);
// For RESULT_LATLON.

View file

@ -34,7 +34,7 @@ namespace search
};
void SetSearchMode(int mode) { m_searchMode = mode; }
bool NeedSearch(SearchModeT mode) const { return ((m_searchMode & mode) != 0);}
bool NeedSearch(SearchModeT mode) const { return ((m_searchMode & mode) != 0); }
//@}
void SetPosition(double lat, double lon);

View file

@ -100,6 +100,11 @@ public:
{
m_vec.swap(rhs.m_vec);
}
template <class LessT> void Sort(LessT lessFn)
{
sort(m_vec.begin(), m_vec.end(), lessFn);
}
};
}

View file

@ -185,6 +185,35 @@ void Engine::SetViewportAsync(m2::RectD const & viewport, m2::RectD const & near
m_pQuery->SetViewport(arrRects, ARRAY_SIZE(arrRects));
}
namespace
{
bool LessByDistance(Result const & r1, Result const & r2)
{
Result::ResultType const t1 = r1.GetResultType();
if (t1 == r2.GetResultType() && t1 == Result::RESULT_FEATURE)
return (r1.GetDistanceFromCenter() < r2.GetDistanceFromCenter());
else if (t1 == Result::RESULT_SUGGESTION)
return true;
else
return false;
}
/// @todo Temporary solution to ensure that results are sorted by distance only for AROUND_POSITION mode.
void EmitResults(SearchParams const & params, Results & res)
{
if (params.IsValidPosition() &&
params.NeedSearch(SearchParams::AROUND_POSITION) &&
!params.NeedSearch(SearchParams::IN_VIEWPORT) &&
!params.NeedSearch(SearchParams::SEARCH_WORLD))
{
res.Sort(&LessByDistance);
}
params.m_callback(res);
}
}
void Engine::SearchAsync()
{
{
@ -287,7 +316,7 @@ void Engine::SearchAsync()
// Emit results even if search was canceled and we have something.
size_t const count = res.GetCount();
if (!m_pQuery->IsCanceled() || count > 0)
params.m_callback(res);
EmitResults(params, res);
// Make additional search in whole mwm when not enough results (only for non-empty query).
if (!emptyQuery && !m_pQuery->IsCanceled() && count < RESULTS_COUNT)
@ -304,7 +333,7 @@ void Engine::SearchAsync()
// Emit if we have more results.
if (res.GetCount() > count)
params.m_callback(res);
EmitResults(params, res);
}
// Emit finish marker to client.

View file

@ -462,7 +462,9 @@ namespace impl
string name, country;
LoadFeature(res.GetID(), feature, name, country);
return new impl::PreResult2(feature, res, name, country);
return new impl::PreResult2(feature, res.GetRank(),
m_query.GetViewport(), m_query.GetPosition(),
name, country);
}
impl::PreResult2 * operator() (pair<size_t, uint32_t> const & id)
@ -473,10 +475,10 @@ namespace impl
if (!name.empty() && !country.empty())
{
// this results will be with equal rank
impl::PreResult1 res(0, 0, feature.GetLimitRect(FeatureType::WORST_GEOMETRY).Center(),
0, m_query.m_position, m_query.GetViewport());
return new impl::PreResult2(feature, res, name, country);
// this results will be with equal rank == 0
return new impl::PreResult2(feature, 0,
m_query.GetViewport(), m_query.GetPosition(),
name, country);
}
else
return 0;