[search] Add PrepareSearch to calculate feature offsets in thread while GUI is loading.

This commit is contained in:
vng 2012-02-07 15:01:11 +03:00 committed by Alex Zolotarev
parent 0fe193a38d
commit e723d1ea67
6 changed files with 78 additions and 30 deletions

View file

@ -97,12 +97,38 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
@implementation SearchVC
+ (BOOL)isLocationValid:(CLLocation *)l
{
if (l == nil) return false;
// do not use too old locations
static NSTimeInterval const SECONDS_TO_EXPIRE = 300.0;
// timeIntervalSinceNow returns negative value - because of "since now"
return [l.timestamp timeIntervalSinceNow] > (-SECONDS_TO_EXPIRE);
}
- (id)initWithFramework:(Framework *)framework andLocationManager:(LocationManager *)lm
{
if ((self = [super initWithNibName:nil bundle:nil]))
{
m_framework = framework;
m_locationManager = lm;
// get current location if needed
bool radarMode = false;
Settings::Get(RADAR_MODE_SETTINGS_KEY, radarMode);
CLLocation * l = m_locationManager.lastLocation;
double lat, lon;
if (radarMode && [SearchVC isLocationValid:l])
{
lat = l.coordinate.latitude;
lon = l.coordinate.longitude;
}
m_framework->PrepareSearch(radarMode, lat, lon);
}
return self;
}
@ -117,23 +143,19 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
m_radarButton.selected = NO;
}
+ (BOOL)isTimestampTooOld:(NSDate *)time
{
static NSTimeInterval const SECONDS_TO_EXPIRE = -300.0;
return [time timeIntervalSinceNow] < SECONDS_TO_EXPIRE;
}
- (void)fillSearchParams:(search::SearchParams &)params withText:(NSString *)queryString
{
params.m_query = [[queryString precomposedStringWithCompatibilityMapping] UTF8String];
params.m_callback = bind(&OnSearchResultCallback, _1, g_queryId);
bool radarEnabled = m_radarButton.selected == YES;
CLLocation * l = m_locationManager.lastLocation;
// Do not use too old locations
if (l == nil || [SearchVC isTimestampTooOld:l.timestamp])
radarEnabled = false;
else
if ([SearchVC isLocationValid:l])
params.SetPosition(l.coordinate.latitude, l.coordinate.longitude);
else
radarEnabled = false;
params.SetNearMeMode(radarEnabled);
}

View file

@ -687,10 +687,14 @@ search::Engine * Framework::GetSearchEngine()
return m_pSearchEngine.get();
}
void Framework::PrepareSearch(bool nearMe, double lat, double lon)
{
GetSearchEngine()->PrepareSearch(m_navigator.Screen().ClipRect(), nearMe, lat, lon);
}
void Framework::Search(search::SearchParams const & params)
{
search::Engine * pSearchEngine = GetSearchEngine();
pSearchEngine->Search(params, m_navigator.Screen().ClipRect());
GetSearchEngine()->Search(params);
}
bool Framework::GetCurrentPosition(double & lat, double & lon)

View file

@ -141,6 +141,7 @@ public:
private:
search::Engine * GetSearchEngine();
public:
void PrepareSearch(bool nearMe, double lat = 0.0, double lon = 0.0);
void Search(search::SearchParams const & params);
bool GetCurrentPosition(double & lat, double & lon);

View file

@ -346,6 +346,8 @@ void MainWindow::OnSearchButtonClicked()
{
if (m_pSearchAction->isChecked())
{
m_pDrawWidget->GetFramework().PrepareSearch(false);
m_Docks[2]->show();
m_Docks[2]->widget()->setFocus();
}

View file

@ -90,30 +90,47 @@ void Engine::InitializeCategoriesAndSuggestStrings(CategoriesHolder const & cate
m_pData->m_stringsToSuggest.assign(stringsToSuggest.begin(), stringsToSuggest.end());
}
void Engine::Search(SearchParams const & params, m2::RectD const & viewport)
{
{
threads::MutexGuard guard(m_updateMutex);
m_params = params;
m_viewport = viewport;
}
// bind does copy of 'query' and 'callback'
GetPlatform().RunAsync(bind(&Engine::SearchAsync, this));
}
namespace
{
m2::PointD GetViewportXY(double lat, double lon)
{
return m2::PointD(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat));
}
m2::RectD GetViewportRect(double lat, double lon, double radius)
m2::RectD GetViewportRect(double lat, double lon, double radius = 20000)
{
return MercatorBounds::MetresToXY(lon, lat, radius);
}
}
void Engine::PrepareSearch(m2::RectD const & viewport, bool nearMe,
double lat, double lon)
{
// bind does copy of viewport
m2::RectD const r = (nearMe ? GetViewportRect(lat, lon) : viewport);
GetPlatform().RunAsync(bind(&Engine::SetViewportAsync, this, r));
}
void Engine::Search(SearchParams const & params)
{
{
threads::MutexGuard guard(m_updateMutex);
m_params = params;
}
GetPlatform().RunAsync(bind(&Engine::SearchAsync, this));
}
void Engine::SetViewportAsync(m2::RectD const & viewport)
{
// First of all - cancel previous query.
m_pQuery->DoCancel();
// Enter to run new search.
threads::MutexGuard searchGuard(m_searchMutex);
m_pQuery->SetViewport(viewport);
}
void Engine::SearchAsync()
{
// First of all - cancel previous query.
@ -123,19 +140,19 @@ void Engine::SearchAsync()
threads::MutexGuard searchGuard(m_searchMutex);
// Get current search params.
m2::RectD viewport;
SearchParams params;
{
threads::MutexGuard updateGuard(m_updateMutex);
params = m_params;
viewport = m_viewport;
}
// Initialize query.
bool const isNearMe = params.IsNearMeMode();
m_pQuery->SetViewport(isNearMe ? GetViewportRect(params.m_lat, params.m_lon, 20000) : viewport);
if (isNearMe)
{
m_pQuery->SetViewport(GetViewportRect(params.m_lat, params.m_lon));
m_pQuery->SetPosition(GetViewportXY(params.m_lat, params.m_lon));
}
else
m_pQuery->NullPosition();

View file

@ -40,19 +40,21 @@ public:
string const & lang);
~Engine();
void Search(SearchParams const & params, m2::RectD const & viewport);
void PrepareSearch(m2::RectD const & viewport, bool nearMe,
double lat, double lon);
void Search(SearchParams const & params);
string GetCountryFile(m2::PointD const & pt) const;
private:
void InitializeCategoriesAndSuggestStrings(CategoriesHolder const & categories);
void SetViewportAsync(m2::RectD const & viewport);
void SearchAsync();
threads::Mutex m_searchMutex, m_updateMutex;
SearchParams m_params;
m2::RectD m_viewport;
Index const * m_pIndex;
scoped_ptr<search::Query> m_pQuery;