forked from organicmaps/organicmaps
[search] Temporary solution: sort results by it's real distance for AROUND_POSITION search mode.
This commit is contained in:
parent
7e8b40e59d
commit
4101361476
6 changed files with 72 additions and 29 deletions
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue