diff --git a/iphone/Maps/Classes/SearchVC.mm b/iphone/Maps/Classes/SearchVC.mm index a9bd75165e..a8ff3d003f 100644 --- a/iphone/Maps/Classes/SearchVC.mm +++ b/iphone/Maps/Classes/SearchVC.mm @@ -16,17 +16,17 @@ volatile int g_queryId = 0; @interface Wrapper : NSObject { - search::Result * m_result; + search::Results * m_result; } -- (id)initWithResult:(search::Result const &) res; -- (search::Result const *)get; +- (id)initWithResult:(search::Results const &) res; +- (search::Results const *)get; @end @implementation Wrapper -- (id)initWithResult:(search::Result const &) res +- (id)initWithResult:(search::Results const &) res { if ((self = [super init])) - m_result = new search::Result(res); + m_result = new search::Results(res); return self; } @@ -36,25 +36,21 @@ volatile int g_queryId = 0; [super dealloc]; } -- (search::Result const *)get +- (search::Results const *)get { return m_result; } @end -static void OnSearchResultCallback(search::Result const & res, int queryId) +static void OnSearchResultCallback(search::Results const & res, int queryId) { if (g_searchVC && queryId == g_queryId) { - // end marker means that the search is finished - if (!res.IsEndMarker()) - { - Wrapper * w = [[Wrapper alloc] initWithResult:res]; - [g_searchVC performSelectorOnMainThread:@selector(addResult:) - withObject:w - waitUntilDone:NO]; - [w release]; - } + Wrapper * w = [[Wrapper alloc] initWithResult:res]; + [g_searchVC performSelectorOnMainThread:@selector(addResult:) + withObject:w + waitUntilDone:NO]; + [w release]; } } @@ -100,17 +96,15 @@ static void OnSearchResultCallback(search::Result const & res, int queryId) - (void)enableRadarMode { m_radarButton.selected = YES; - // @TODO add code for search engine - // or add additional parameter to query by checking if (m_radarButton.selected) - // m_framework->GetSearchEngine()-> + + m_framework->GetSearchEngine()->EnablePositionTrack(true); } - (void)disableRadarMode { m_radarButton.selected = NO; - // @TODO add code for search engine - // or add additional parameter to query by checking if (m_radarButton.selected) - // m_framework->GetSearchEngine()-> + + m_framework->GetSearchEngine()->EnablePositionTrack(false); } - (void)onRadarButtonClicked:(id)button @@ -390,7 +384,11 @@ static void OnSearchResultCallback(search::Result const & res, int queryId) - (void)addResult:(id)result { - m_results.push_back(*[result get]); + /// @todo Temporary, for test. + m_results.clear(); + + search::Results const * r = [result get]; + m_results.insert(m_results.end(), r->Begin(), r->End()); [m_table reloadData]; } @@ -404,6 +402,8 @@ static void OnSearchResultCallback(search::Result const & res, int queryId) - (void)onGpsUpdate:(location::GpsInfo const &)info { + m_framework->UpdateGpsInfo(info); + NSArray * cells = [m_table visibleCells]; for (NSUInteger i = 0; i < cells.count; ++i) { diff --git a/map/framework.cpp b/map/framework.cpp index c646afe469..3fca78afb0 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -7,6 +7,7 @@ #include "../platform/settings.hpp" #include "../platform/preferred_languages.hpp" +#include "../platform/location.hpp" #include "../yg/rendercontext.hpp" @@ -676,12 +677,15 @@ void Framework::Search(string const & text, SearchCallbackT callback) m2::RectD const viewport = m_navigator.Screen().ClipRect(); pSearchEngine->SetViewport(viewport); - pSearchEngine->SetPosition(m_locationState.IsValidPosition() ? - m_locationState.Position() : viewport.Center()); pSearchEngine->Search(text, callback); } +void Framework::UpdateGpsInfo(location::GpsInfo const & info) +{ + GetSearchEngine()->SetPosition(info.m_latitude, info.m_longitude); +} + void Framework::SetRenderPolicy(RenderPolicy * renderPolicy) { if (renderPolicy) diff --git a/map/framework.hpp b/map/framework.hpp index 61b8fca4b5..9ed192b694 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -52,8 +52,8 @@ namespace search { class Engine; } struct BenchmarkRectProvider; -namespace search { class Result; } -typedef function SearchCallbackT; +namespace search { class Results; } +typedef function SearchCallbackT; class DrawerYG; class RenderPolicy; @@ -146,8 +146,9 @@ public: int scaleLevel, bool isTiling); - void Search(string const & text, SearchCallbackT callback); search::Engine * GetSearchEngine(); + void Search(string const & text, SearchCallbackT callback); + void UpdateGpsInfo(location::GpsInfo const & info); void SetMaxWorldRect(); diff --git a/map/location_state.cpp b/map/location_state.cpp index 145e6c62df..19ef69db8d 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -21,8 +21,7 @@ namespace location m2::RectD const errorRectXY = MercatorBounds::MetresToXY(info.m_longitude, info.m_latitude, info.m_horizontalAccuracy); - m_errorRadiusMercator = sqrt((errorRectXY.SizeX() * errorRectXY.SizeX() - + errorRectXY.SizeY() * errorRectXY.SizeY()) / 4); + m_errorRadiusMercator = sqrt(my::sq(errorRectXY.SizeX()) + my::sq(errorRectXY.SizeY())) / 4; } void State::UpdateCompass(CompassInfo const & info) diff --git a/map/location_state.hpp b/map/location_state.hpp index ce4f255ad4..27e61b4654 100644 --- a/map/location_state.hpp +++ b/map/location_state.hpp @@ -18,6 +18,8 @@ namespace location double m_headingRad; double m_headingAccuracyRad; + int m_flags; ///< stores flags from SymbolType + public: enum SymbolType { @@ -33,8 +35,6 @@ namespace location /// @return GPS center point in mercator m2::PointD Position() const { return m_positionMercator; } - bool IsValidPosition() const { return ((m_flags & EGps) != 0); } - void TurnOff() { m_flags = ENone; } void UpdateGps(GpsInfo const & info); void UpdateCompass(CompassInfo const & info); @@ -45,9 +45,5 @@ namespace location { return m_flags; } - - private: - /// stores flags from SymbolType - int m_flags; }; } diff --git a/search/result.cpp b/search/result.cpp index 768046bc28..07c8957d10 100644 --- a/search/result.cpp +++ b/search/result.cpp @@ -19,13 +19,6 @@ Result::Result(string const & str, string const & suggestionStr) { } -Result Result::GetEndResult() -{ - Result result("", ""); - ASSERT(result.IsEndMarker(), ()); - return result; -} - Result::ResultType Result::GetResultType() const { if (!m_suggestionStr.empty()) diff --git a/search/result.hpp b/search/result.hpp index 6d3b5e71b9..fd8e7a0741 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -21,9 +21,6 @@ public: double distanceFromCenter, double directionFromCenter); Result(string const & str, string const & suggestionStr); - static Result GetEndResult(); - bool IsEndMarker() const { return m_str.empty(); } - // String that is displayed in the GUI. char const * GetString() const { return m_str.c_str(); } char const * GetRegionString() const { return m_region.c_str(); } @@ -59,4 +56,16 @@ private: string m_suggestionStr; }; +class Results +{ + vector m_vec; + +public: + void AddResult(Result const & r) { m_vec.push_back(r); } + + typedef vector::const_iterator IterT; + IterT Begin() const { return m_vec.begin(); } + IterT End() const { return m_vec.end(); } +}; + } diff --git a/search/search_engine.cpp b/search/search_engine.cpp index fc5cf7f51d..a42f11eecc 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -8,6 +8,9 @@ #include "../indexer/categories_holder.hpp" #include "../indexer/search_delimiters.hpp" #include "../indexer/search_string_utils.hpp" +#include "../indexer/mercator.hpp" + +#include "../geometry/distance_on_sphere.hpp" #include "../base/logging.hpp" @@ -35,7 +38,7 @@ public: Engine::Engine(IndexType const * pIndex, CategoriesHolder * pCategories, ModelReaderPtr polyR, ModelReaderPtr countryR) - : m_pIndex(pIndex), m_pData(new EngineData(polyR, countryR)) + : m_pIndex(pIndex), m_pData(new EngineData(polyR, countryR)), m_trackEnable(false) { if (pCategories) { @@ -83,12 +86,51 @@ void Engine::InitializeCategoriesAndSuggestStrings(CategoriesHolder const & cate void Engine::SetViewport(m2::RectD const & viewport) { - m_pQuery->SetViewport(viewport); + m_savedViewport = viewport; + + if (!m_trackEnable) + m_pQuery->SetViewport(viewport); } -void Engine::SetPosition(m2::PointD const & pos) +void Engine::SetPosition(double lat, double lon) { - m_pQuery->SetPosition(pos); + m2::PointD const oldPos = m_pQuery->GetPosition(); + + if (m_trackEnable && + ms::DistanceOnEarth(MercatorBounds::YToLat(oldPos.y), + MercatorBounds::XToLon(oldPos.x), + lat, lon) > 10.0) + { + LOG(LINFO, ("Update after Position: ", oldPos, lon, lat)); + + m_pQuery->SetPosition(m2::PointD(MercatorBounds::LonToX(lon), + MercatorBounds::LatToY(lat))); + + m_pQuery->SetViewport(MercatorBounds::MetresToXY(lon, lat, 25000)); + + RepeatSearch(); + } +} + +void Engine::EnablePositionTrack(bool enable) +{ + m_trackEnable = enable; + + if (m_trackEnable) + { + LOG(LINFO, ("Enable tracking")); + + m_savedViewport = m_pQuery->GetViewport(); + } + else + { + LOG(LINFO, ("Disable tracking")); + + m_pQuery->SetPosition(m_savedViewport.Center()); + m_pQuery->SetViewport(m_savedViewport); + + RepeatSearch(); + } } void Engine::SetPreferredLanguage(string const & lang) @@ -96,11 +138,23 @@ void Engine::SetPreferredLanguage(string const & lang) m_pQuery->SetPreferredLanguage(lang); } -void Engine::Search(string const & queryText, function const & f) +void Engine::Search(string const & queryText, SearchCallbackT const & f) { LOG(LDEBUG, (queryText)); - m_pQuery->Search(queryText, f); - f(Result::GetEndResult()); + + m_callback = f; + m_queryText = queryText; + + Results res; + m_pQuery->Search(queryText, res); + + f(res); +} + +void Engine::RepeatSearch() +{ + if (!m_queryText.empty() && !m_callback.empty()) + Search(m_queryText, m_callback); } string Engine::GetCountryFile(m2::PointD const & pt) const diff --git a/search/search_engine.hpp b/search/search_engine.hpp index 093072627a..a95a6e4fb3 100644 --- a/search/search_engine.hpp +++ b/search/search_engine.hpp @@ -22,12 +22,14 @@ namespace search struct CategoryInfo; class Query; -class Result; +class Results; class EngineData; class Engine { + typedef function SearchCallbackT; + public: typedef Index IndexType; @@ -37,16 +39,26 @@ public: ~Engine(); void SetViewport(m2::RectD const & viewport); - void SetPosition(m2::PointD const & pos); + void SetPosition(double lat, double lon); void SetPreferredLanguage(string const & lang); - void Search(string const & query, function const & f); + void EnablePositionTrack(bool enable); + + void Search(string const & query, SearchCallbackT const & f); string GetCountryFile(m2::PointD const & pt) const; private: void InitializeCategoriesAndSuggestStrings(CategoriesHolder const & categories); + void RepeatSearch(); + + SearchCallbackT m_callback; + string m_queryText; + m2::RectD m_savedViewport; + + bool m_trackEnable; + Index const * m_pIndex; scoped_ptr m_pQuery; scoped_ptr m_pData; diff --git a/search/search_query.cpp b/search/search_query.cpp index ce10f7e253..aea3183e8b 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -35,7 +35,8 @@ Query::Query(Index const * pIndex, m_pInfoGetter(pInfoGetter), m_preferredLanguage(StringUtf8Multilang::GetLangIndex("en")), m_viewport(m2::RectD::GetEmptyRect()), m_viewportExtended(m2::RectD::GetEmptyRect()), - m_bOffsetsCacheIsValid(false) + m_bOffsetsCacheIsValid(false), + m_position(-1000000, -1000000) // initialize as empty point { } @@ -57,13 +58,6 @@ void Query::SetViewport(m2::RectD const & viewport) } } -void Query::SetPosition(m2::PointD const & pos) -{ - m_position = pos; - - // TODO: Add search mode and recalc m_viewport for new position with "near me" mode. -} - void Query::SetPreferredLanguage(string const & lang) { m_preferredLanguage = StringUtf8Multilang::GetLangIndex(lang); @@ -143,9 +137,7 @@ namespace }; } -void Query::Search(string const & query, - function const & f, - unsigned int resultsNeeded) +void Query::Search(string const & query, Results & res, unsigned int resultsNeeded) { // Initialize. { @@ -194,7 +186,7 @@ void Query::Search(string const & query, SearchFeatures(); - FlushResults(f); + FlushResults(res); } namespace @@ -304,7 +296,7 @@ namespace } } -void Query::FlushResults(function const & f) +void Query::FlushResults(Results & res) { vector indV; @@ -352,7 +344,7 @@ void Query::FlushResults(function const & f) for (size_t i = 0; i < indV.size(); ++i) { LOG(LDEBUG, (indV[i])); - f(indV[i].get()->GenerateFinalResult(m_pInfoGetter)); + res.AddResult(indV[i].get()->GenerateFinalResult(m_pInfoGetter)); } } diff --git a/search/search_query.hpp b/search/search_query.hpp index 28e0d6c6d4..be09ba309c 100644 --- a/search/search_query.hpp +++ b/search/search_query.hpp @@ -7,7 +7,6 @@ #include "../base/limited_priority_queue.hpp" #include "../base/string_utils.hpp" -#include "../std/function.hpp" #include "../std/map.hpp" #include "../std/scoped_ptr.hpp" #include "../std/shared_ptr.hpp" @@ -44,12 +43,13 @@ public: ~Query(); void SetViewport(m2::RectD const & viewport); - void SetPosition(m2::PointD const & pos); + inline void SetPosition(m2::PointD const & pos) { m_position = pos; } void SetPreferredLanguage(string const & lang); - void Search(string const & query, - function const & f, - unsigned int resultsNeeded = 10); + inline m2::PointD GetPosition() const { return m_position; } + inline m2::RectD GetViewport() const { return m_viewport; } + + void Search(string const & query, Results & res, unsigned int resultsNeeded = 10); void ClearCache(); @@ -63,7 +63,7 @@ private: void AddResult(ValueT const & result); void AddFeatureResult(FeatureType const & f, string const & fName); - void FlushResults(function const & f); + void FlushResults(Results & res); void UpdateViewportOffsets(); void SearchFeatures(); void SearchFeatures(vector > const & tokens,