[search] Correct zoom for result and fix balloon point for streets.

This commit is contained in:
vng 2013-09-20 18:09:46 +03:00 committed by Alex Zolotarev
parent f0122d60b5
commit 6f2ad31c26
21 changed files with 270 additions and 210 deletions

View file

@ -223,7 +223,7 @@ Java_com_mapswithme_maps_SearchActivity_nativeGetResult(
jclass klass = env->FindClass("com/mapswithme/maps/SearchActivity$SearchAdapter$SearchResult");
ASSERT ( klass, () );
if (res->GetResultType() == search::Result::RESULT_FEATURE)
if (res->GetResultType() != search::Result::RESULT_SUGGESTION)
{
jmethodID methodID = env->GetMethodID(
klass, "<init>",

View file

@ -148,21 +148,13 @@ class FeatureType : public FeatureBase
{
typedef FeatureBase base_type;
/// @name This params define unique id for feature.
//@{
size_t m_mwmID;
uint32_t m_offset;
//@}
FeatureID m_id;
public:
void Deserialize(feature::LoaderBase * pLoader, BufferT buffer);
inline void SetID(size_t mwmID, uint32_t offset)
{
m_mwmID = mwmID;
m_offset = offset;
}
inline pair<size_t, uint32_t> GetID() const { return make_pair(m_mwmID, m_offset); }
inline void SetID(FeatureID const & id) { m_id = id; }
inline FeatureID GetID() const { return m_id; }
/// @name Parse functions. Do simple dispatching to m_pLoader.
//@{

View file

@ -1,4 +1,5 @@
#pragma once
#include "feature_decl.hpp"
#include "../coding/multilang_utf8_string.hpp"
#include "../coding/value_opt_string.hpp"

28
indexer/feature_decl.hpp Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include "../std/stdint.hpp"
struct FeatureID
{
size_t m_mwm;
uint32_t m_offset;
FeatureID() : m_mwm(-1) {}
FeatureID(size_t mwm, uint32_t offset) : m_mwm(mwm), m_offset(offset) {}
bool IsValid() const { return m_mwm != -1; }
inline bool operator < (FeatureID const & r) const
{
if (m_mwm == r.m_mwm)
return m_offset < r.m_offset;
else
return m_mwm < r.m_mwm;
}
inline bool operator == (FeatureID const & r) const
{
return (m_mwm == r.m_mwm && m_offset == r.m_offset);
}
};

View file

@ -66,27 +66,18 @@ public:
}
}
m2::RectD CorrectRectForScales(TypesHolder const & types, m2::RectD const & rect) const
int GetViewportScale(TypesHolder const & types) const
{
int const scale = scales::GetScaleLevel(rect);
int scaleNew = scale;
CorrectScaleForVisibility(types, scaleNew);
int scale = GetDefaultScale();
return ((scale != scaleNew) ? scales::GetRectForLevel(scaleNew, rect.Center()) : rect);
}
m2::RectD GetViewport(TypesHolder const & types, m2::RectD const & limitRect) const
{
if (types.GetGeoType() != GEOM_POINT)
return CorrectRectForScales(types, limitRect);
int const upperScale = scales::GetUpperScale();
int scale = upperScale;
for (size_t i = 0; i < types.Size(); ++i)
scale = min(scale, GetScaleForType(types[i]));
if (types.GetGeoType() == GEOM_POINT)
{
for (size_t i = 0; i < types.Size(); ++i)
scale = min(scale, GetScaleForType(types[i]));
}
CorrectScaleForVisibility(types, scale);
return scales::GetRectForLevel(scale, limitRect.Center());
return scale;
}
uint8_t GetSearchRank(TypesHolder const & types, m2::PointD const & pt, uint32_t population) const
@ -101,7 +92,8 @@ public:
population = max(population, static_cast<uint32_t>(10000));
else if (types[i] == m_TypeState)
{
m2::RectD usaRects[] = {
m2::RectD usaRects[] =
{
// Continental part of USA
m2::RectD(-125.73195962769162293, 25.168771674082393019,
-66.925073086214325713, 56.956377399113392812),
@ -152,6 +144,7 @@ public:
}
private:
static int GetDefaultScale() { return scales::GetUpperComfortScale(); }
// Returns width and height (lon and lat) for a given type.
int GetScaleForType(uint32_t const type) const
@ -181,7 +174,7 @@ private:
if (IsEqual(type, m_TypeSmallVillage))
return 14;
return scales::GetUpperScale();
return GetDefaultScale();
}
static uint32_t GetType(string const & s1,
@ -214,9 +207,9 @@ FeatureEstimator const & GetFeatureEstimator()
} // namespace feature::impl
m2::RectD GetFeatureViewport(TypesHolder const & types, m2::RectD const & limRect)
int GetFeatureViewportScale(TypesHolder const & types)
{
return impl::GetFeatureEstimator().GetViewport(types, limRect);
return impl::GetFeatureEstimator().GetViewportScale(types);
}
uint8_t GetSearchRank(TypesHolder const & types, m2::PointD const & pt, uint32_t population)

View file

@ -9,8 +9,8 @@ namespace feature
{
class TypesHolder;
/// Get viewport to show given feature. Used in search.
m2::RectD GetFeatureViewport(TypesHolder const & types, m2::RectD const & limRect);
/// Get viewport scale to show given feature. Used in search.
int GetFeatureViewportScale(TypesHolder const & types);
/// Get search rank for a feature.
/// Roughly, rank + 1 means that feature is 1.x times more popular.

View file

@ -119,7 +119,7 @@ private:
FeatureType feature;
m_V.Get(offset, feature);
feature.SetID(m_mwmID, offset);
feature.SetID(FeatureID(m_mwmID, offset));
m_F(feature);
}

View file

@ -90,6 +90,7 @@ HEADERS += \
feature_algo.hpp \
mwm_version.hpp \
drules_include.hpp \
feature_decl.hpp \
OTHER_FILES += drules_struct.proto

View file

@ -410,10 +410,8 @@ static void OnSearchResultCallback(search::Results const & res)
}
search::Result const & r = [[_searchResults objectAtIndex:scopeSection] getWithPosition:realRowIndex];
switch (r.GetResultType())
if (r.GetResultType() != search::Result::RESULT_SUGGESTION)
{
case search::Result::RESULT_FEATURE:
{
SearchCell * cell = (SearchCell *)[tableView dequeueReusableCellWithIdentifier:@"FeatureCell"];
if (!cell)
cell = [[[SearchCell alloc] initWithReuseIdentifier:@"FeatureCell"] autorelease];
@ -473,22 +471,14 @@ static void OnSearchResultCallback(search::Results const & res)
compass.angle = azimut;
}
return cell;
}
break;
case search::Result::RESULT_SUGGESTION:
{
}
else
{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"SuggestionCell"];
if (!cell)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SuggestionCell"] autorelease];
cell.textLabel.text = [NSString stringWithUTF8String:r.GetString()];
return cell;
}
break;
default:
ASSERT(false, ("Unsupported search result type"));
return nil;
}
}
@ -507,11 +497,8 @@ static void OnSearchResultCallback(search::Results const & res)
if (realRowIndex < (NSInteger)[[_searchResults objectAtIndex:scopeSection] getCount])
{
search::Result const & res = [[_searchResults objectAtIndex:scopeSection] getWithPosition:realRowIndex];
switch(res.GetResultType())
if (res.GetResultType() != search::Result::RESULT_SUGGESTION)
{
// Zoom to the feature
case search::Result::RESULT_FEATURE:
{
m_framework->ShowSearchResult(res);
search::AddressInfo info;
@ -527,14 +514,12 @@ static void OnSearchResultCallback(search::Results const & res)
[[MapsAppDelegate theApp].m_mapViewController showSearchResultAsBookmarkAtMercatorPoint:res.GetFeatureCenter() withInfo:info];
[self onCloseButton:nil];
}
break;
case search::Result::RESULT_SUGGESTION:
}
else
{
[self setSearchBoxText:[NSString stringWithUTF8String:res.GetSuggestionString()]];
// Remove blue selection from the row
[tableView deselectRowAtIndexPath: indexPath animated:YES];
break;
}
}
}
@ -628,7 +613,7 @@ void setSearchType(search::SearchParams & params)
UITableViewCell * cell = (UITableViewCell *)[cells objectAtIndex:i];
NSInteger realRowIndex = [m_table indexPathForCell:cell].row;
search::Result const & res = [[_searchResults objectAtIndex:scopeSection] getWithPosition:realRowIndex];
if (res.GetResultType() == search::Result::RESULT_FEATURE)
if (res.GetResultType() != search::Result::RESULT_SUGGESTION)
{
// Show compass only for cells without flags
if ([cell.accessoryView isKindOfClass:[CompassView class]])

View file

@ -91,7 +91,7 @@ void Drawer::drawSymbol(m2::PointD const & pt,
void Drawer::drawCircle(m2::PointD const & pt,
graphics::EPosition pos,
di::DrawRule const & rule,
di::FeatureInfo::FeatureID const & id)
FeatureID const & id)
{
graphics::Circle::Info ci;
ConvertStyle(rule.m_rule->GetCircle(), m_visualScale, ci);
@ -102,8 +102,8 @@ void Drawer::drawCircle(m2::PointD const & pt,
params.m_position = pos;
params.m_pivot = pt;
params.m_ci = ci;
params.m_userInfo.m_mwmID = id.first;
params.m_userInfo.m_offset = id.second;
params.m_userInfo.m_mwmID = id.m_mwm;
params.m_userInfo.m_offset = id.m_offset;
m_pScreen->drawCircle(params);
}
@ -111,7 +111,7 @@ void Drawer::drawCircle(m2::PointD const & pt,
void Drawer::drawSymbol(m2::PointD const & pt,
graphics::EPosition pos,
di::DrawRule const & rule,
di::FeatureInfo::FeatureID const & id)
FeatureID const & id)
{
graphics::Icon::Info info;
ConvertStyle(rule.m_rule->GetSymbol(), info);
@ -122,8 +122,8 @@ void Drawer::drawSymbol(m2::PointD const & pt,
params.m_pivot = pt;
params.m_info = info;
params.m_renderer = m_pScreen.get();
params.m_userInfo.m_mwmID = id.first;
params.m_userInfo.m_offset = id.second;
params.m_userInfo.m_mwmID = id.m_mwm;
params.m_userInfo.m_offset = id.m_offset;
m_pScreen->drawSymbol(params);
}
@ -204,7 +204,7 @@ void Drawer::drawText(m2::PointD const & pt,
graphics::EPosition pos,
di::FeatureStyler const & fs,
di::DrawRule const & rule,
di::FeatureInfo::FeatureID const & id)
FeatureID const & id)
{
graphics::FontDesc primaryFont;
m2::PointD primaryOffset;
@ -231,8 +231,8 @@ void Drawer::drawText(m2::PointD const & pt,
params.m_auxLogText = strings::MakeUniString(fs.m_secondaryText);
params.m_doSplit = true;
params.m_useAllParts = false;
params.m_userInfo.m_mwmID = id.first;
params.m_userInfo.m_offset = id.second;
params.m_userInfo.m_mwmID = id.m_mwm;
params.m_userInfo.m_offset = id.m_offset;
m_pScreen->drawTextEx(params);
}
@ -307,7 +307,7 @@ void Drawer::SetScale(int level)
void Drawer::Draw(di::FeatureInfo const & fi)
{
di::FeatureInfo::FeatureID const & id = fi.m_id;
FeatureID const & id = fi.m_id;
buffer_vector<di::DrawRule, 8> const & rules = fi.m_styler.m_rules;
buffer_vector<di::DrawRule, 8> pathRules;

View file

@ -43,12 +43,12 @@ protected:
void drawSymbol(m2::PointD const & pt,
graphics::EPosition pos,
di::DrawRule const & rule,
di::FeatureInfo::FeatureID const & id);
FeatureID const & id);
void drawCircle(m2::PointD const & pt,
graphics::EPosition pos,
di::DrawRule const & rule,
di::FeatureInfo::FeatureID const & id);
FeatureID const & id);
void drawPath(di::PathInfo const & path,
di::DrawRule const * rules,
@ -61,7 +61,7 @@ protected:
graphics::EPosition pos,
di::FeatureStyler const & fs,
di::DrawRule const & rule,
di::FeatureInfo::FeatureID const & id);
FeatureID const & id);
void drawPathText(di::PathInfo const & info,
di::FeatureStyler const & fs,

View file

@ -1,4 +1,6 @@
#include "feature_info.hpp"
#include "../indexer/feature.hpp"
namespace di
{

View file

@ -4,25 +4,21 @@
#include "path_info.hpp"
#include "area_info.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/feature_decl.hpp"
#include "../geometry/point2d.hpp"
#include "../std/list.hpp"
namespace graphics
{
class GlyphCache;
}
namespace graphics { class GlyphCache; }
class FeatureType;
class ScreenBase;
namespace di
{
struct FeatureInfo
{
typedef pair<size_t, uint32_t> FeatureID;
FeatureStyler m_styler;
FeatureID m_id;

View file

@ -16,7 +16,12 @@
#include "../indexer/categories_holder.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/scales.hpp"
/// @todo Probably it's better to join this functionality.
//@{
#include "../indexer/feature_algo.hpp"
#include "../indexer/feature_utils.hpp"
//@}
#include "../anim/controller.hpp"
@ -1224,15 +1229,41 @@ bool Framework::GetCurrentPosition(double & lat, double & lon) const
void Framework::ShowSearchResult(search::Result const & res)
{
int scale;
m2::PointD center;
switch (res.GetResultType())
{
case search::Result::RESULT_FEATURE:
{
FeatureID const id = res.GetFeatureID();
Index::FeaturesLoaderGuard guard(m_model.GetIndex(), id.m_mwm);
FeatureType ft;
guard.GetFeature(id.m_offset, ft);
scale = feature::GetFeatureViewportScale(feature::TypesHolder(ft));
center = feature::GetCenter(ft, scale);
break;
}
case search::Result::RESULT_LATLON:
scale = scales::GetUpperComfortScale();
center = res.GetFeatureCenter();
break;
default:
ASSERT(false, ());
return;
}
StopLocationFollow();
m2::RectD const rect = res.GetFeatureRect();
ShowRectExVisibleScale(rect);
ShowRectExVisibleScale(m_scales.GetRectForDrawScale(scale, center));
search::AddressInfo info;
info.MakeFrom(res);
m_balloonManager.ShowAddress(res.GetFeatureCenter(), info);
m_balloonManager.ShowAddress(center, info);
}
bool Framework::GetDistanceAndAzimut(m2::PointD const & point,

View file

@ -119,7 +119,7 @@ void SearchPanel::OnSearchResult(ResultsT * res)
m_pTable->setItem(rowCount, 1, create_item(QString::fromUtf8(e.GetString())));
m_pTable->setItem(rowCount, 2, create_item(QString::fromUtf8(e.GetRegionString())));
if (e.GetResultType() == ResultT::RESULT_FEATURE)
if (e.GetResultType() != ResultT::RESULT_SUGGESTION)
{
// For debug purposes: add bookmarks for search results
Bookmark bm(e.GetFeatureCenter(), e.GetString(), "placemark-red");
@ -163,8 +163,10 @@ void SearchPanel::OnSearchTextChanged(QString const & str)
void SearchPanel::OnSearchPanelItemClicked(int row, int)
{
disconnect(m_pDrawWidget, SIGNAL(ViewportChanged()), this, SLOT(OnViewportChanged()));
ASSERT_EQUAL(m_results.size(), static_cast<size_t>(m_pTable->rowCount()), ());
if (m_results[row].GetResultType() == ResultT::RESULT_FEATURE)
if (m_results[row].GetResultType() != ResultT::RESULT_SUGGESTION)
{
// center viewport on clicked item
m_pDrawWidget->ShowSearchResult(m_results[row]);
@ -175,6 +177,7 @@ void SearchPanel::OnSearchPanelItemClicked(int row, int)
string const suggestion = m_results[row].GetSuggestionString();
m_pEditor->setText(QString::fromUtf8(suggestion.c_str()));
}
connect(m_pDrawWidget, SIGNAL(ViewportChanged()), this, SLOT(OnViewportChanged()));
}

View file

@ -4,7 +4,6 @@
#include "../indexer/classificator.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/feature_utils.hpp"
#include "../indexer/mercator.hpp"
#include "../indexer/scales.hpp"
#include "../indexer/categories_holder.hpp"
@ -91,26 +90,42 @@ template <class T> bool LessDistanceT(T const & r1, T const & r2)
return (r1.m_distanceFromViewportCenter < r2.m_distanceFromViewportCenter);
}
PreResult1::PreResult1(uint32_t fID, uint8_t rank, m2::PointD const & center, size_t mwmID,
PreResult1::PreResult1(FeatureID const & fID, uint8_t rank, m2::PointD const & center,
m2::PointD const & pos, m2::RectD const & viewport, int8_t viewportID)
: m_center(center),
m_mwmID(mwmID),
m_featureID(fID),
: m_id(fID),
m_rank(rank),
m_viewportID(viewportID)
{
CalcParams(viewport, pos);
ASSERT(m_id.IsValid(), ());
CalcParams(center, viewport, pos);
}
void PreResult1::CalcParams(m2::RectD const & viewport, m2::PointD const & pos)
PreResult1::PreResult1(m2::PointD const & center, m2::PointD const & pos, m2::RectD const & viewport)
{
CalcParams(center, viewport, pos);
}
namespace
{
void AssertValid(m2::PointD const & p)
{
ASSERT ( my::between_s(-180.0, 180.0, p.x), (p.x) );
ASSERT ( my::between_s(-180.0, 180.0, p.y), (p.y) );
}
}
void PreResult1::CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos)
{
AssertValid(fCenter);
// Check if point is valid (see Query::empty_pos_value).
if (pos.x > -500 && pos.y > -500)
{
ASSERT ( my::between_s(-180.0, 180.0, pos.x), (pos.x) );
ASSERT ( my::between_s(-180.0, 180.0, pos.y), (pos.y) );
m_distance = ResultDistance(m_center, pos);
AssertValid(pos);
m_distance = ResultDistance(fCenter, pos);
}
else
{
@ -118,8 +133,8 @@ void PreResult1::CalcParams(m2::RectD const & viewport, m2::PointD const & pos)
m_distance = -1.0;
}
m_viewportDistance = ViewportDistance(viewport, m_center);
m_distanceFromViewportCenter = ResultDistance(m_center, viewport.Center());
m_viewportDistance = ViewportDistance(viewport, fCenter);
m_distanceFromViewportCenter = ResultDistance(fCenter, viewport.Center());
}
bool PreResult1::LessRank(PreResult1 const & r1, PreResult1 const & r2)
@ -138,10 +153,10 @@ bool PreResult1::LessViewportDistance(PreResult1 const & r1, PreResult1 const &
}
void PreResult2::CalcParams(m2::RectD const & viewport, m2::PointD const & pos)
void PreResult2::CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos)
{
// dummy object to avoid copy-paste
PreResult1 res(0, 0, m_center, 0, pos, viewport, -1);
PreResult1 res(fCenter, pos, viewport);
m_distance = res.m_distance;
m_distanceFromViewportCenter = res.m_distanceFromViewportCenter;
@ -151,24 +166,20 @@ void PreResult2::CalcParams(m2::RectD const & viewport, m2::PointD const & pos)
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_id(f.GetID()),
m_types(f),
m_str(displayName),
m_resultType(RESULT_FEATURE),
m_rank(rank)
{
ASSERT ( !m_types.Empty(), () );
ASSERT(m_id.IsValid(), ());
ASSERT(!m_types.Empty(), ());
m_types.SortBySpec();
m_featureRect = f.GetLimitRect(FeatureType::WORST_GEOMETRY);
m_center = m_featureRect.Center();
CalcParams(viewport, pos);
// get region info
if (!fileName.empty())
m_region.SetName(fileName);
else
m_region.SetPoint(m_center);
m2::PointD const fCenter = f.GetLimitRect(FeatureType::WORST_GEOMETRY).Center();
CalcParams(fCenter, viewport, pos);
m_region.SetParams(fileName, fCenter);
}
PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, double lat, double lon)
@ -176,14 +187,9 @@ PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, doubl
m_resultType(RESULT_LATLON),
m_rank(255)
{
m_center.x = MercatorBounds::LonToX(lon);
m_center.y = MercatorBounds::LatToY(lat);
m_featureRect.Add(m_center);
CalcParams(viewport, pos);
// get region info
m_region.SetPoint(m_center);
m2::PointD const fCenter(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat));
CalcParams(fCenter, viewport, pos);
m_region.SetParams(string(), fCenter);
}
PreResult2::PreResult2(string const & name, int penalty)
@ -246,15 +252,14 @@ Result PreResult2::GenerateFinalResult(
switch (m_resultType)
{
case RESULT_FEATURE:
return Result(m_str, info.m_name, info.m_flag, GetFeatureType(pCat, pTypes, lang)
return Result(m_id, GetCenter(), m_str, info.m_name, info.m_flag, GetFeatureType(pCat, pTypes, lang)
#ifdef DEBUG
+ ' ' + strings::to_string(static_cast<int>(m_rank))
#endif
, type, GetFinalViewport(), m_distance);
, type, m_distance);
case RESULT_LATLON:
return Result(m_str, info.m_name, info.m_flag, string(), 0,
scales::GetRectForLevel(scales::GetUpperScale(), m_center), m_distance);
return Result(GetCenter(), m_str, info.m_name, info.m_flag, m_distance);
default:
ASSERT_EQUAL ( m_resultType, RESULT_CATEGORY, () );
@ -282,7 +287,7 @@ bool PreResult2::StrictEqualF::operator() (PreResult2 const & r) const
if (m_r.m_resultType == r.m_resultType && m_r.m_resultType == RESULT_FEATURE)
{
if (m_r.m_str == r.m_str && m_r.GetBestType() == r.GetBestType())
return (ResultDistance(m_r.m_center, r.m_center) < DIST_EQUAL_RESULTS);
return (ResultDistance(m_r.GetCenter(), r.GetCenter()) < DIST_EQUAL_RESULTS);
}
return false;
@ -347,7 +352,7 @@ bool PreResult2::EqualLinearTypesF::operator() (PreResult2 const & r1, PreResult
// Otherwise we will skip the results for different parts of the map.
if (r1.m_resultType == r2.m_resultType && r1.m_str == r2.m_str &&
//r1.m_viewportDistance == r2.m_viewportDistance &&
ResultDistance(r1.m_center, r2.m_center) < DIST_SAME_STREET)
ResultDistance(r1.GetCenter(), r2.GetCenter()) < DIST_SAME_STREET)
{
// filter equal linear features
static IsLinearChecker checker;
@ -415,19 +420,12 @@ string PreResult2::GetFeatureType(CategoriesHolder const * pCat,
return classif().GetReadableObjectName(type);
}
m2::RectD PreResult2::GetFinalViewport() const
{
m2::RectD r = feature::GetFeatureViewport(m_types, m_featureRect);
r.SetCenter(m_center);
return r;
}
void PreResult2::RegionInfo::GetRegion(
storage::CountryInfoGetter const * pInfo, storage::CountryInfo & info) const
void PreResult2::RegionInfo::GetRegion(storage::CountryInfoGetter const * pInfo,
storage::CountryInfo & info) const
{
if (!m_file.empty())
pInfo->GetRegionInfo(m_file, info);
else if (m_valid)
else
pInfo->GetRegionInfo(m_point, info);
}

View file

@ -3,11 +3,6 @@
#include "../indexer/feature_data.hpp"
#include "../base/string_utils.hpp"
#include "../std/shared_ptr.hpp"
#include "../std/map.hpp"
class FeatureType;
class CategoriesHolder;
@ -27,7 +22,8 @@ template <class T> bool LessRankT(T const & r1, T const & r2);
template <class T> bool LessViewportDistanceT(T const & r1, T const & r2);
template <class T> bool LessDistanceT(T const & r1, T const & r2);
/// First results class. Objects are creating during search in trie.
/// First pass results class. Objects are creating during search in trie.
/// Works fast without feature loading and provide ranking.
class PreResult1
{
friend class PreResult2;
@ -35,34 +31,34 @@ class PreResult1
template <class T> friend bool LessViewportDistanceT(T const & r1, T const & r2);
template <class T> friend bool LessDistanceT(T const & r1, T const & r2);
m2::PointD m_center;
FeatureID m_id;
double m_distance, m_distanceFromViewportCenter;
size_t m_mwmID;
uint32_t m_featureID;
uint8_t m_viewportDistance;
uint8_t m_rank;
int8_t m_viewportID;
void CalcParams(m2::RectD const & viewportRect, m2::PointD const & pos);
void CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos);
public:
PreResult1(uint32_t fID, uint8_t rank, m2::PointD const & center, size_t mwmID,
PreResult1(FeatureID const & fID, uint8_t rank, m2::PointD const & center,
m2::PointD const & pos, m2::RectD const & viewport, int8_t viewportID);
PreResult1(m2::PointD const & center, m2::PointD const & pos, m2::RectD const & viewport);
static bool LessRank(PreResult1 const & r1, PreResult1 const & r2);
static bool LessDistance(PreResult1 const & r1, PreResult1 const & r2);
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; }
int8_t GetViewportID() const { return m_viewportID; }
inline FeatureID GetID() const { return m_id; }
inline uint8_t GetRank() const { return m_rank; }
inline int8_t GetViewportID() const { return m_viewportID; }
};
/// Second result class. Objects are creating during reading of features.
/// Read and fill needed info for ranking and getting final results.
class PreResult2
{
void CalcParams(m2::RectD const & viewport, m2::PointD const & pos);
void CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos);
public:
enum ResultType
@ -129,34 +125,31 @@ private:
string GetFeatureType(CategoriesHolder const * pCat,
set<uint32_t> const * pTypes,
int8_t lang) const;
m2::RectD GetFinalViewport() const;
FeatureID m_id;
feature::TypesHolder m_types;
uint32_t GetBestType(set<uint32_t> const * pPrefferedTypes = 0) const;
string m_str, m_completionString;
class RegionInfo
struct RegionInfo
{
string m_file;
m2::PointD m_point;
bool m_valid;
public:
RegionInfo() : m_valid(false) {}
void SetName(string const & s) { m_file = s; }
void SetPoint(m2::PointD const & p)
inline void SetParams(string const & file, m2::PointD const & pt)
{
m_point = p;
m_valid = true;
m_file = file;
m_point = pt;
}
void GetRegion(storage::CountryInfoGetter const * pInfo, storage::CountryInfo & info) const;
void GetRegion(storage::CountryInfoGetter const * pInfo,
storage::CountryInfo & info) const;
} m_region;
m2::RectD m_featureRect;
m2::PointD m_center;
m2::PointD GetCenter() const { return m_region.m_point; }
double m_distance, m_distanceFromViewportCenter;
ResultType m_resultType;
uint8_t m_rank;

View file

@ -4,13 +4,12 @@
namespace search
{
Result::Result(string const & str, string const & region,
Result::Result(FeatureID const & id, m2::PointD const & fCenter,
string const & str, string const & region,
string const & flag, string const & type,
uint32_t featureType, m2::RectD const & featureRect,
double distanceFromCenter)
: m_str(str), m_region(region), m_flag(flag), m_type(type),
m_featureRect(featureRect), m_featureType(featureType),
m_distanceFromCenter(distanceFromCenter)
uint32_t featureType, double distance)
: m_id(id), m_center(fCenter), m_str(str), m_region(region),
m_flag(flag), m_type(type), m_featureType(featureType), m_distance(distance)
{
// Features with empty names can be found after suggestion.
if (m_str.empty())
@ -20,6 +19,14 @@ Result::Result(string const & str, string const & region,
}
}
Result::Result(m2::PointD const & fCenter,
string const & str, string const & region,
string const & flag, double distance)
: m_center(fCenter), m_str(str), m_region(region),
m_flag(flag), m_distance(distance)
{
}
Result::Result(string const & str, string const & suggestionStr)
: m_str(str), m_suggestionStr(suggestionStr)
{
@ -29,25 +36,28 @@ Result::ResultType Result::GetResultType() const
{
if (!m_suggestionStr.empty())
return RESULT_SUGGESTION;
return RESULT_FEATURE;
if (m_id.IsValid())
return RESULT_FEATURE;
else
return RESULT_LATLON;
}
m2::RectD Result::GetFeatureRect() const
FeatureID Result::GetFeatureID() const
{
ASSERT_EQUAL(GetResultType(), RESULT_FEATURE, ());
return m_featureRect;
return m_id;
}
double Result::GetDistance() const
{
ASSERT_NOT_EQUAL(GetResultType(), RESULT_SUGGESTION, ());
return m_distance;
}
m2::PointD Result::GetFeatureCenter() const
{
ASSERT_EQUAL(GetResultType(), RESULT_FEATURE, ());
return m_featureRect.Center();
}
double Result::GetDistanceFromCenter() const
{
ASSERT_EQUAL(GetResultType(), RESULT_FEATURE, ());
return m_distanceFromCenter;
ASSERT_NOT_EQUAL(GetResultType(), RESULT_SUGGESTION, ());
return m_center;
}
char const * Result::GetSuggestionString() const
@ -60,7 +70,7 @@ bool Result::operator== (Result const & r) const
{
return (m_str == r.m_str && m_region == r.m_region && m_featureType == r.m_featureType &&
GetResultType() == r.GetResultType() &&
my::AlmostEqual(m_distanceFromCenter, r.m_distanceFromCenter));
my::AlmostEqual(m_distance, r.m_distance));
}
void Results::AddResultCheckExisting(Result const & r)
@ -75,7 +85,7 @@ void Results::AddResultCheckExisting(Result const & r)
void AddressInfo::MakeFrom(Result const & res)
{
ASSERT_EQUAL ( res.GetResultType(), Result::RESULT_FEATURE, () );
ASSERT_NOT_EQUAL(res.GetResultType(), Result::RESULT_SUGGESTION, ());
// push the feature type (may be empty for coordinates result)
string const type = res.GetFeatureType();

View file

@ -1,8 +1,12 @@
#pragma once
#include "../indexer/feature_decl.hpp"
#include "../geometry/point2d.hpp"
#include "../geometry/rect2d.hpp"
#include "../std/string.hpp"
namespace search
{
@ -13,43 +17,59 @@ public:
enum ResultType
{
RESULT_FEATURE,
RESULT_LATLON,
RESULT_SUGGESTION
};
Result(string const & str, string const & region,
/// For RESULT_FEATURE.
Result(FeatureID const & id, m2::PointD const & fCenter,
string const & str, string const & region,
string const & flag, string const & type,
uint32_t featureType, m2::RectD const & featureRect,
double distanceFromCenter);
uint32_t featureType, double distance);
/// For RESULT_LATLON.
Result(m2::PointD const & fCenter,
string const & str, string const & region,
string const & flag, double distance);
/// For RESULT_SUGGESTION.
Result(string const & str, string const & suggestionStr);
// String that is displayed in the GUI.
/// Strings that is displayed in the GUI.
//@{
char const * GetString() const { return m_str.c_str(); }
char const * GetRegionString() const { return m_region.c_str(); }
char const * GetRegionFlag() const { return m_flag.empty() ? 0 : m_flag.c_str(); }
char const * GetFeatureType() const { return m_type.c_str(); }
//@}
// Type of the result.
/// Type of the result.
ResultType GetResultType() const;
// Rect of a feature, if GetResultType() == RESULT_FEATURE.
m2::RectD GetFeatureRect() const;
/// Feature id in mwm.
/// @precondition GetResultType() == RESULT_FEATURE
FeatureID GetFeatureID() const;
// Center point of a feature, if GetResultType() == RESULT_FEATURE.
/// Center point of a feature.
/// @precondition GetResultType() != RESULT_SUGGESTION
m2::PointD GetFeatureCenter() const;
// Distance from the center of the screen, if GetResultType() == RESULT_FEATURE.
double GetDistanceFromCenter() const;
/// Distance from the current position or -1 if location is not detected.
/// @precondition GetResultType() != RESULT_SUGGESTION
double GetDistance() const;
// String to write in the search box.
/// String to write in the search box.
/// @precondition GetResultType() == RESULT_SUGGESTION
char const * GetSuggestionString() const;
bool operator== (Result const & r) const;
private:
FeatureID m_id;
m2::PointD m_center;
string m_str, m_region, m_flag, m_type;
m2::RectD m_featureRect;
uint32_t m_featureType;
double m_distanceFromCenter;
double m_distance;
string m_suggestionStr;
};

View file

@ -193,12 +193,19 @@ namespace
{
bool LessByDistance(Result const & r1, Result const & r2)
{
Result::ResultType const t1 = r1.GetResultType();
bool const isSuggest1 = r1.GetResultType() == Result::RESULT_SUGGESTION;
bool const isNotSuggest2 = r2.GetResultType() != Result::RESULT_SUGGESTION;
if (t1 == r2.GetResultType() && t1 == Result::RESULT_FEATURE)
return (r1.GetDistanceFromCenter() < r2.GetDistanceFromCenter());
else if (t1 == Result::RESULT_SUGGESTION)
return true;
if (isSuggest1)
{
// suggestions should always be on top
return isNotSuggest2;
}
else if (isNotSuggest2)
{
// we can't call GetDistance for suggestions
return (r1.GetDistance() < r2.GetDistance());
}
else
return false;
}

View file

@ -432,13 +432,13 @@ namespace impl
scoped_ptr<Index::FeaturesLoaderGuard> m_pFV;
// For the best performance, incoming id's should be sorted by id.first (mwm file id).
void LoadFeature(pair<size_t, uint32_t> const & id,
FeatureType & f, string & name, string & country)
void LoadFeature(FeatureID const & id, FeatureType & f, string & name, string & country)
{
if (m_pFV.get() == 0 || m_pFV->GetID() != id.first)
m_pFV.reset(new Index::FeaturesLoaderGuard(*m_query.m_pIndex, id.first));
if (m_pFV.get() == 0 || m_pFV->GetID() != id.m_mwm)
m_pFV.reset(new Index::FeaturesLoaderGuard(*m_query.m_pIndex, id.m_mwm));
m_pFV->GetFeature(id.second, f);
m_pFV->GetFeature(id.m_offset, f);
f.SetID(id);
m_query.GetBestMatchName(f, name);
@ -466,7 +466,7 @@ namespace impl
name, country);
}
impl::PreResult2 * operator() (pair<size_t, uint32_t> const & id)
impl::PreResult2 * operator() (FeatureID const & id)
{
FeatureType feature;
string name, country;
@ -575,7 +575,7 @@ namespace
void Query::AddResultFromTrie(TrieValueT const & val, size_t mwmID, int8_t viewportID)
{
impl::PreResult1 res(val.m_featureId, val.m_rank, val.m_pt, mwmID,
impl::PreResult1 res(FeatureID(mwmID, val.m_featureId), val.m_rank, val.m_pt,
GetPosition(viewportID), GetViewport(viewportID), viewportID);
for (size_t i = 0; i < m_qCount; ++i)
@ -1834,7 +1834,7 @@ void Query::SearchAllInViewport(m2::RectD const & viewport, Results & res, unsig
{
if (m_cancel) break;
AddPreResult2(maker(make_pair(i, offsets[i][j])), indV);
AddPreResult2(maker(FeatureID(i, offsets[i][j])), indV);
}
}