[search] Refactored search API.

This commit is contained in:
Yuri Gorshenin 2016-08-03 13:53:12 +03:00
parent ca03f82cad
commit b72a10679c
38 changed files with 511 additions and 355 deletions

View file

@ -7,6 +7,8 @@
#include "map/user_mark.hpp"
#include "search/everywhere_search_params.hpp"
#include "storage/storage_helpers.hpp"
#include "drape_frontend/visual_params.hpp"
@ -307,10 +309,10 @@ void Framework::Scale(m2::PointD const & centerPt, int targetZoom, bool animate)
return &m_work;
}
bool Framework::Search(search::SearchParams const & params)
bool Framework::Search(search::EverywhereSearchParams const & params)
{
m_searchQuery = params.m_query;
return m_work.Search(params);
return m_work.SearchEverywhere(params);
}
void Framework::AddLocalMaps()

View file

@ -27,6 +27,11 @@
#include "std/unique_ptr.hpp"
#include "std/cstdint.hpp"
namespace search
{
struct EverywhereSearchParams;
}
namespace android
{
class Framework
@ -101,7 +106,7 @@ namespace android
void Touch(int action, Finger const & f1, Finger const & f2, uint8_t maskedPointer);
bool Search(search::SearchParams const & params);
bool Search(search::EverywhereSearchParams const & params);
string GetLastSearchQuery() { return m_searchQuery; }
void ClearLastSearchQuery() { m_searchQuery.clear(); }

View file

@ -1,7 +1,12 @@
#include "Framework.hpp"
#include "base/thread.hpp"
#include "search/everywhere_search_params.hpp"
#include "search/mode.hpp"
#include "search/result.hpp"
#include "search/viewport_search_params.hpp"
#include "base/thread.hpp"
#include "std/atomic.hpp"
#include "std/mutex.hpp"
@ -183,17 +188,14 @@ extern "C"
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_search_SearchEngine_nativeRunSearch(JNIEnv * env, jclass clazz, jbyteArray bytes, jstring lang,
jlong timestamp, jboolean force, jboolean hasPosition, jdouble lat, jdouble lon)
jlong timestamp, jboolean hasPosition, jdouble lat, jdouble lon)
{
search::SearchParams params;
search::EverywhereSearchParams params;
params.m_query = jni::ToNativeString(env, bytes);
params.SetInputLocale(ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang)));
params.SetForceSearch(force);
if (hasPosition)
params.SetPosition(lat, lon);
params.m_inputLocale = ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang));
params.m_onResults = bind(&OnResults, _1, timestamp, false, hasPosition, lat, lon);
bool const searchStarted = g_framework->NativeFramework()->Search(params);
bool const searchStarted = g_framework->NativeFramework()->SearchEverywhere(params);
if (searchStarted)
g_queryTimestamp = timestamp;
return searchStarted;
@ -203,16 +205,20 @@ extern "C"
Java_com_mapswithme_maps_search_SearchEngine_nativeRunInteractiveSearch(JNIEnv * env, jclass clazz, jbyteArray bytes,
jstring lang, jlong timestamp, jboolean isMapAndTable)
{
search::SearchParams params;
params.m_query = jni::ToNativeString(env, bytes);
params.SetInputLocale(ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang)));
search::ViewportSearchParams vparams;
vparams.m_query = jni::ToNativeString(env, bytes);
vparams.m_inputLocale = ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang));
g_framework->NativeFramework()->StartInteractiveSearch(params);
g_framework->NativeFramework()->SearchInViewport(vparams);
if (isMapAndTable)
{
params.m_onResults = bind(&OnResults, _1, timestamp, isMapAndTable, false /* hasPosition */, 0.0, 0.0);
if (g_framework->NativeFramework()->Search(params))
search::EverywhereSearchParams eparams;
eparams.m_query = vparams.m_query;
eparams.m_inputLocale = vparams.m_inputLocale;
eparams.m_onResults = bind(&OnResults, _1, timestamp, isMapAndTable, false /* hasPosition */,
0.0 /* lat */, 0.0 /* lon */);
if (g_framework->NativeFramework()->SearchEverywhere(eparams))
g_queryTimestamp = timestamp;
}
}
@ -256,7 +262,7 @@ extern "C"
{
GetPlatform().RunOnGuiThread([]()
{
g_framework->NativeFramework()->CancelInteractiveSearch();
g_framework->NativeFramework()->CancelSearch(search::Mode::Viewport);
});
}
} // extern "C"

View file

@ -93,14 +93,13 @@ public enum SearchEngine implements NativeSearchListener,
/**
* @param timestamp Search results are filtered according to it after multiple requests.
* @param force Should be false for repeating requests with the same query.
* @return whether search was actually started.
*/
public static boolean search(String query, long timestamp, boolean force, boolean hasLocation, double lat, double lon)
public static boolean search(String query, long timestamp, boolean hasLocation, double lat, double lon)
{
try
{
return nativeRunSearch(query.getBytes("utf-8"), Language.getKeyboardLocale(), timestamp, force, hasLocation, lat, lon);
return nativeRunSearch(query.getBytes("utf-8"), Language.getKeyboardLocale(), timestamp, hasLocation, lat, lon);
} catch (UnsupportedEncodingException ignored) { }
return false;
@ -155,7 +154,7 @@ public enum SearchEngine implements NativeSearchListener,
/**
* @param bytes utf-8 formatted bytes of query.
*/
private static native boolean nativeRunSearch(byte[] bytes, String language, long timestamp, boolean force, boolean hasLocation, double lat, double lon);
private static native boolean nativeRunSearch(byte[] bytes, String language, long timestamp, boolean hasLocation, double lat, double lon);
/**
* @param bytes utf-8 formatted query bytes

View file

@ -412,7 +412,7 @@ public class SearchFragment extends BaseMwmFragment
}
else
{
if (!SearchEngine.search(getQuery(), mLastQueryTimestamp, true, mLastPosition.valid, mLastPosition.lat, mLastPosition.lon))
if (!SearchEngine.search(getQuery(), mLastQueryTimestamp, mLastPosition.valid, mLastPosition.lat, mLastPosition.lon))
return;
}

View file

@ -72,4 +72,4 @@ public class SearchResult
this.description = description;
this.highlightRanges = highlightRanges;
}
}
}

View file

@ -5,8 +5,8 @@
#include "Framework.h"
#include "search/params.hpp"
#include "search/query_saver.hpp"
#include "search/search_params.hpp"
namespace
{

View file

@ -12,12 +12,13 @@
#include "routing/routing_algorithm.hpp"
#include "search/engine.hpp"
#include "search/everywhere_search_params.hpp"
#include "search/geometry_utils.hpp"
#include "search/interactive_search_callback.hpp"
#include "search/intermediate_result.hpp"
#include "search/processor_factory.hpp"
#include "search/result.hpp"
#include "search/reverse_geocoder.hpp"
#include "search/viewport_search_params.hpp"
#include "storage/storage_helpers.hpp"
@ -138,8 +139,7 @@ void ParseSetGpsTrackMinAccuracyCommand(string const & query)
// Cancels search query by |handle|.
void CancelQuery(weak_ptr<search::ProcessorHandle> & handle)
{
auto queryHandle = handle.lock();
if (queryHandle)
if (auto queryHandle = handle.lock())
queryHandle->Cancel();
handle.reset();
}
@ -504,8 +504,7 @@ bool Framework::OnCountryFileDelete(storage::TCountryId const & countryId, stora
if (countryId == m_lastReportedCountry)
m_lastReportedCountry = kInvalidCountryId;
if (auto handle = m_lastProcessorHandle.lock())
handle->Cancel();
CancelAllSearches();
m2::RectD rect = MercatorBounds::FullRect();
@ -1045,37 +1044,6 @@ void Framework::InvalidateRect(m2::RectD const & rect)
CallDrapeFunction(bind(&df::DrapeEngine::InvalidateRect, _1, rect));
}
void Framework::StartInteractiveSearch(search::SearchParams const & params)
{
auto const originalOnResults = params.m_onResults;
auto setMode = [this]() {
SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, true /* show */);
};
auto onResults = [this, originalOnResults](search::Results const & results) {
if (!results.IsEndMarker())
{
GetPlatform().RunOnGuiThread([this, results]() {
if (IsInteractiveSearchActive())
FillSearchResultsMarks(results);
});
}
if (originalOnResults)
originalOnResults(results);
};
m_lastInteractiveSearchParams = params;
m_lastInteractiveSearchParams.SetForceSearch(false);
m_lastInteractiveSearchParams.SetMode(search::Mode::Viewport);
m_lastInteractiveSearchParams.SetSuggestsEnabled(false);
m_lastInteractiveSearchParams.m_onResults =
search::InteractiveSearchCallback(move(setMode), move(onResults));
UpdateUserViewportChanged();
}
void Framework::ClearAllCaches()
{
m_model.ClearCaches();
@ -1109,43 +1077,12 @@ void Framework::SetCurrentCountryChangedListener(TCurrentCountryChanged const &
void Framework::UpdateUserViewportChanged()
{
if (IsInteractiveSearchActive())
{
(void)GetCurrentPosition(m_lastInteractiveSearchParams.m_lat,
m_lastInteractiveSearchParams.m_lon);
Search(m_lastInteractiveSearchParams);
}
}
if (!IsViewportSearchActive())
return;
bool Framework::Search(search::SearchParams const & params)
{
#ifdef FIXED_LOCATION
search::SearchParams rParams(params);
if (params.IsValidPosition())
{
m_fixedPos.GetLat(rParams.m_lat);
m_fixedPos.GetLon(rParams.m_lon);
}
#else
search::SearchParams const & rParams = params;
#endif
ParseSetGpsTrackMinAccuracyCommand(params.m_query);
if (ParseEditorDebugCommand(params))
return true;
m2::RectD const viewport = GetCurrentViewport();
if (QueryMayBeSkipped(rParams, viewport))
return false;
m_lastQueryParams = rParams;
m_lastQueryViewport = viewport;
// Cancels previous search request (if any) and initiates new search request.
CancelQuery(m_lastProcessorHandle);
m_lastProcessorHandle = m_searchEngine->Search(m_lastQueryParams, m_lastQueryViewport);
return true;
auto & params = m_searchIntents[static_cast<size_t>(search::Mode::Viewport)].m_params;
SetCurrentPositionIfPossible(params);
Search(params);
}
bool Framework::GetGroupCountryIdFromFeature(FeatureType const & ft, string & name) const
@ -1164,25 +1101,67 @@ bool Framework::GetGroupCountryIdFromFeature(FeatureType const & ft, string & na
return false;
}
bool Framework::SearchEverywhere(search::EverywhereSearchParams const & params)
{
search::SearchParams p;
p.m_query = params.m_query;
p.SetInputLocale(params.m_inputLocale);
p.SetForceSearch(true);
p.SetMode(search::Mode::Everywhere);
p.SetSuggestsEnabled(true);
p.m_onResults = [params](search::Results const & results) {
if (params.m_onResults)
GetPlatform().RunOnGuiThread([params, results]() { params.m_onResults(results); });
};
SetCurrentPositionIfPossible(p);
return Search(p);
}
bool Framework::SearchInViewport(search::ViewportSearchParams const & params)
{
search::SearchParams p;
p.m_query = params.m_query;
p.SetInputLocale(params.m_inputLocale);
p.SetForceSearch(false);
p.SetMode(search::Mode::Viewport);
p.SetSuggestsEnabled(false);
p.m_onStarted = [params]() {
if (params.m_onStarted)
GetPlatform().RunOnGuiThread([params]() { params.m_onStarted(); });
};
p.m_onResults = search::ViewportSearchCallback(
static_cast<search::ViewportSearchCallback::Delegate &>(*this),
[params](search::Results const & results) {
if (results.IsEndMarker() && params.m_onCompleted)
GetPlatform().RunOnGuiThread([params]() { params.m_onCompleted(); });
});
SetCurrentPositionIfPossible(p);
return Search(p);
}
bool Framework::SearchInDownloader(DownloaderSearchParams const & params)
{
search::SearchParams searchParam;
searchParam.m_query = params.m_query;
searchParam.m_inputLocale = params.m_inputLocale;
searchParam.SetMode(search::Mode::World);
searchParam.SetSuggestsEnabled(false);
searchParam.SetForceSearch(true);
searchParam.m_onResults = [this, params](search::Results const & results)
search::SearchParams p;
p.m_query = params.m_query;
p.m_inputLocale = params.m_inputLocale;
p.SetMode(search::Mode::Downloader);
p.SetSuggestsEnabled(false);
p.SetForceSearch(true);
p.m_onResults = [this, params](search::Results const & results)
{
DownloaderSearchResults downloaderSearchResults;
for (auto it = results.Begin(); it != results.End(); ++it)
for (auto const & result : results)
{
if (!it->HasPoint())
if (!result.HasPoint())
continue;
if (it->GetResultType() != search::Result::RESULT_LATLON)
if (result.GetResultType() != search::Result::RESULT_LATLON)
{
FeatureID const & fid = it->GetFeatureID();
FeatureID const & fid = result.GetFeatureID();
Index::FeaturesLoaderGuard loader(m_model.GetIndex(), fid.m_mwmId);
FeatureType ft;
if (!loader.GetFeatureByIndex(fid.m_index, ft))
@ -1199,25 +1178,51 @@ bool Framework::SearchInDownloader(DownloaderSearchParams const & params)
if (GetGroupCountryIdFromFeature(ft, groupFeatureName))
{
downloaderSearchResults.m_results.emplace_back(groupFeatureName,
it->GetString() /* m_matchedName */);
result.GetString() /* m_matchedName */);
continue;
}
}
}
auto const & mercator = it->GetFeatureCenter();
auto const & mercator = result.GetFeatureCenter();
TCountryId const & countryId = CountryInfoGetter().GetRegionCountryId(mercator);
if (countryId == kInvalidCountryId)
continue;
downloaderSearchResults.m_results.emplace_back(countryId,
it->GetString() /* m_matchedName */);
result.GetString() /* m_matchedName */);
}
downloaderSearchResults.m_query = params.m_query;
downloaderSearchResults.m_endMarker = results.IsEndMarker();
params.m_onResults(downloaderSearchResults);
if (params.m_onResults)
{
GetPlatform().RunOnGuiThread(
[params, downloaderSearchResults]() { params.m_onResults(downloaderSearchResults); });
}
};
return Search(searchParam);
return Search(p);
}
void Framework::CancelSearch(search::Mode mode)
{
ASSERT_NOT_EQUAL(mode, search::Mode::Count, ());
if (mode == search::Mode::Viewport)
{
ClearSearchResultsMarks();
SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, false /* show */);
}
auto & intent = m_searchIntents[static_cast<size_t>(mode)];
intent.m_params.Clear();
CancelQuery(intent.m_handle);
}
void Framework::CancelAllSearches()
{
for (size_t i = 0; i < static_cast<size_t>(search::Mode::Count); ++i)
CancelSearch(static_cast<search::Mode>(i));
}
void Framework::MemoryWarning()
@ -1307,21 +1312,64 @@ string Framework::GetCountryName(m2::PointD const & pt) const
return info.m_name;
}
bool Framework::QueryMayBeSkipped(search::SearchParams const & params,
bool Framework::Search(search::SearchParams const & params)
{
auto const mode = params.GetMode();
auto & intent = m_searchIntents[static_cast<size_t>(mode)];
#ifdef FIXED_LOCATION
search::SearchParams rParams(params);
if (params.IsValidPosition())
{
m_fixedPos.GetLat(rParams.m_lat);
m_fixedPos.GetLon(rParams.m_lon);
}
#else
search::SearchParams const & rParams = params;
#endif
ParseSetGpsTrackMinAccuracyCommand(params.m_query);
if (ParseEditorDebugCommand(params))
return true;
m2::RectD const viewport = GetCurrentViewport();
if (QueryMayBeSkipped(intent, rParams, viewport))
return false;
intent.m_params = rParams;
intent.m_viewport = viewport;
// Cancels previous search request (if any) and initiates new search request.
CancelQuery(intent.m_handle);
intent.m_handle = m_searchEngine->Search(intent.m_params, intent.m_viewport);
return true;
}
void Framework::SetCurrentPositionIfPossible(search::SearchParams & params)
{
double lat;
double lon;
if (GetCurrentPosition(lat, lon))
params.SetPosition(lat, lon);
}
bool Framework::QueryMayBeSkipped(SearchIntent const & intent, search::SearchParams const & params,
m2::RectD const & viewport) const
{
auto const & lastParams = intent.m_params;
auto const & lastViewport = intent.m_viewport;
if (params.IsForceSearch())
return false;
if (!m_lastQueryParams.IsEqualCommon(params))
if (!lastParams.IsEqualCommon(params))
return false;
if (!m_lastQueryViewport.IsValid() ||
!search::IsEqualMercator(m_lastQueryViewport, viewport, kDistEqualQuery))
{
if (!lastViewport.IsValid() || !search::IsEqualMercator(lastViewport, viewport, kDistEqualQuery))
return false;
}
if (!m_lastQueryParams.IsSearchAroundPosition() ||
ms::DistanceOnEarth(m_lastQueryParams.m_lat, m_lastQueryParams.m_lon, params.m_lat,
params.m_lon) <= kDistEqualQuery)
if (!lastParams.IsSearchAroundPosition() ||
ms::DistanceOnEarth(lastParams.m_lat, lastParams.m_lon, params.m_lat, params.m_lon) <=
kDistEqualQuery)
{
return false;
}
@ -1330,7 +1378,7 @@ bool Framework::QueryMayBeSkipped(search::SearchParams const & params,
void Framework::ShowSearchResult(search::Result const & res)
{
CancelInteractiveSearch();
CancelAllSearches();
StopLocationFollow();
alohalytics::LogEvent("searchShowResult", {{"pos", strings::to_string(res.GetPositionInResults())},
@ -1435,7 +1483,6 @@ void Framework::FillSearchResultsMarks(search::Results const & results)
UserMarkControllerGuard guard(m_bmManager, UserMarkType::SEARCH_MARK);
guard.m_controller.SetIsVisible(true);
guard.m_controller.SetIsDrawable(true);
guard.m_controller.Clear();
size_t const count = results.GetCount();
for (size_t i = 0; i < count; ++i)
@ -1455,15 +1502,9 @@ void Framework::FillSearchResultsMarks(search::Results const & results)
}
}
void Framework::CancelInteractiveSearch()
void Framework::ClearSearchResultsMarks()
{
UserMarkControllerGuard(m_bmManager, UserMarkType::SEARCH_MARK).m_controller.Clear();
if (IsInteractiveSearchActive())
{
m_lastInteractiveSearchParams.Clear();
SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, false /* show */);
CancelQuery(m_lastProcessorHandle);
}
}
bool Framework::GetDistanceAndAzimut(m2::PointD const & point,

View file

@ -25,7 +25,9 @@
#include "editor/user_stats.hpp"
#include "search/engine.hpp"
#include "search/mode.hpp"
#include "search/query_saver.hpp"
#include "search/viewport_search_callback.hpp"
#include "storage/downloader_search_params.hpp"
#include "storage/downloading_policy.hpp"
@ -33,6 +35,7 @@
#include "platform/country_defines.hpp"
#include "platform/location.hpp"
#include "platform/platform.hpp"
#include "routing/router.hpp"
#include "routing/routing_session.hpp"
@ -58,9 +61,11 @@ class EditableMapObject;
namespace search
{
class Result;
class Results;
struct AddressInfo;
class Result;
class Results;
struct AddressInfo;
struct EverywhereSearchParams;
struct ViewportSearchParams;
}
namespace storage
@ -82,7 +87,7 @@ namespace df
/// build version for screenshots.
//#define FIXED_LOCATION
class Framework
class Framework : public search::ViewportSearchCallback::Delegate
{
DISALLOW_COPY(Framework);
@ -271,6 +276,27 @@ public:
BookmarkAndCategory FindBookmark(UserMark const * mark) const;
BookmarkManager & GetBookmarkManager() { return m_bmManager; }
protected:
// search::ViewportSearchCallback::Delegate overrides:
void RunUITask(function<void()> fn) override { GetPlatform().RunOnGuiThread(move(fn)); }
void SetHotelDisplacementMode() override
{
SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, true /* show */);
}
bool IsViewportSearchActive() const override
{
return !m_searchIntents[static_cast<size_t>(search::Mode::Viewport)].m_params.m_query.empty();
}
void ShowViewportSearchResults(search::Results const & results) override
{
FillSearchResultsMarks(results);
}
void ClearViewportSearchResults() override { ClearSearchResultsMarks(); }
private:
void ActivateMapSelection(bool needAnimation,
df::SelectionShape::ESelectedObject selectionType,
@ -386,37 +412,44 @@ public:
void SetDisplacementMode(DisplacementModeManager::Slot slot, bool show);
private:
struct SearchIntent
{
search::SearchParams m_params;
weak_ptr<search::ProcessorHandle> m_handle;
m2::RectD m_viewport;
};
void InitCountryInfoGetter();
void InitSearchEngine();
DisplacementModeManager m_displacementModeManager;
// Last search query params for the interactive search.
search::SearchParams m_lastInteractiveSearchParams;
bool m_connectToGpsTrack; // need to connect to tracker when Drape is being constructed
void Search(SearchIntent const & intent);
void SetCurrentPositionIfPossible(search::SearchParams & params);
void FillSearchResultsMarks(search::Results const & results);
void ClearSearchResultsMarks();
void OnUpdateCurrentCountry(m2::PointF const & pt, int zoomLevel);
storage::TCountryId m_lastReportedCountry;
TCurrentCountryChanged m_currentCountryChanged;
// Search query params and viewport for the latest search
// query. These fields are used to check whether a new search query
// can be skipped. Note that these fields are not guarded by a mutex
// because we're assuming that they will be accessed only from the
// UI thread.
search::SearchParams m_lastQueryParams;
m2::RectD m_lastQueryViewport;
// Descriptions of last search queries for different modes. May be
// used for search requests skipping. This field is not guarded
// because it must be used from the UI thread only.
SearchIntent m_searchIntents[static_cast<size_t>(search::Mode::Count)];
// A handle for the latest search processor.
weak_ptr<search::ProcessorHandle> m_lastProcessorHandle;
bool Search(search::SearchParams const & params);
// Returns true when |params| and |viewport| are almost the same as
// the latest search query's params and viewport.
bool QueryMayBeSkipped(search::SearchParams const & params, m2::RectD const & viewport) const;
// the latest search query's params and viewport in the |intent|.
bool QueryMayBeSkipped(SearchIntent const & intent, search::SearchParams const & params,
m2::RectD const & viewport) const;
void OnUpdateGpsTrackPointsCallback(vector<pair<size_t, location::GpsTrackInfo>> && toAdd,
pair<size_t, size_t> const & toRemove);
@ -427,21 +460,23 @@ public:
void UpdateUserViewportChanged();
/// Call this function before entering search GUI.
/// While it's loading, we can cache features in viewport.
bool Search(search::SearchParams const & params);
/// Searches for mwm based on |params|.
/// Calling |params::m_onResults| for returning the result.
/// Search everywhere.
bool SearchEverywhere(search::EverywhereSearchParams const & params);
/// Search in the viewport.
bool SearchInViewport(search::ViewportSearchParams const & params);
/// Search for maps by countries or cities.
bool SearchInDownloader(storage::DownloaderSearchParams const & params);
void CancelSearch(search::Mode mode);
void CancelAllSearches();
bool GetCurrentPosition(double & lat, double & lon) const;
void ShowSearchResult(search::Result const & res);
size_t ShowSearchResults(search::Results const & results);
void StartInteractiveSearch(search::SearchParams const & params);
bool IsInteractiveSearchActive() const { return !m_lastInteractiveSearchParams.m_query.empty(); }
void CancelInteractiveSearch();
list<TSearchRequest> const & GetLastSearchQueries() const { return m_searchQuerySaver.Get(); }
void SaveSearchQuery(TSearchRequest const & query) { m_searchQuerySaver.Add(query); }
void ClearSearchHistory() { m_searchQuerySaver.Clear(); }

View file

@ -458,13 +458,9 @@ void DrawWidget::wheelEvent(QWheelEvent * e)
m_framework->Scale(exp(e->delta() / 360.0), m2::PointD(L2D(e->x()), L2D(e->y())), false);
}
bool DrawWidget::Search(search::SearchParams params)
bool DrawWidget::Search(search::EverywhereSearchParams const & params)
{
double lat, lon;
if (m_framework->GetCurrentPosition(lat, lon))
params.SetPosition(lat, lon);
return m_framework->Search(params);
return m_framework->SearchEverywhere(params);
}
string DrawWidget::GetDistance(search::Result const & res) const

View file

@ -4,13 +4,15 @@
#include "map/framework.hpp"
#include "search/everywhere_search_params.hpp"
#include "drape_frontend/gui/skin.hpp"
#include "drape_frontend/drape_engine.hpp"
#include "std/unique_ptr.hpp"
#include "std/mutex.hpp"
#include "std/condition_variable.hpp"
#include "std/mutex.hpp"
#include "std/unique_ptr.hpp"
#include <QtWidgets/QOpenGLWidget>
@ -52,7 +54,7 @@ namespace qt
void SetScaleControl(QScaleSlider * pScale);
bool Search(search::SearchParams params);
bool Search(search::EverywhereSearchParams const & params);
string GetDistance(search::Result const & res) const;
void ShowSearchResult(search::Result const & res);

View file

@ -117,10 +117,8 @@ void SearchPanel::OnSearchResult(ResultsT * results)
{
ClearResults();
for (ResultsT::IterT i = results->Begin(); i != results->End(); ++i)
for (auto const & res : *results)
{
ResultT const & res = *i;
QString const name = QString::fromStdString(res.GetString());
QString strHigh;
int pos = 0;
@ -298,7 +296,7 @@ void SearchPanel::OnSearchTextChanged(QString const & str)
{
ClearResults();
m_pDrawWidget->GetFramework().CancelInteractiveSearch();
m_pDrawWidget->GetFramework().CancelSearch(search::Mode::Everywhere);
// hide X button
m_pClearButton->setVisible(false);
@ -324,7 +322,7 @@ void SearchPanel::OnSearchPanelItemClicked(int row, int)
void SearchPanel::hideEvent(QHideEvent *)
{
m_pDrawWidget->GetFramework().CancelInteractiveSearch();
m_pDrawWidget->GetFramework().CancelSearch(search::Mode::Everywhere);
}
void SearchPanel::OnAnimationTimer()

View file

@ -1,7 +1,7 @@
#pragma once
#include "search/result.hpp"
#include "search/params.hpp"
#include "search/everywhere_search_params.hpp"
#include "std/vector.hpp"
@ -37,7 +37,7 @@ class SearchPanel : public QWidget
typedef search::Result ResultT;
vector<ResultT> m_results;
search::SearchParams m_params;
search::EverywhereSearchParams m_params;
Q_OBJECT

View file

@ -1,8 +1,8 @@
#include "search/engine.hpp"
#include "search/geometry_utils.hpp"
#include "search/params.hpp"
#include "search/processor.hpp"
#include "search/search_params.hpp"
#include "storage/country_info_getter.hpp"

View file

@ -1,9 +1,9 @@
#pragma once
#include "params.hpp"
#include "processor_factory.hpp"
#include "result.hpp"
#include "suggest.hpp"
#include "search/processor_factory.hpp"
#include "search/result.hpp"
#include "search/search_params.hpp"
#include "search/suggest.hpp"
#include "indexer/categories_holder.hpp"

View file

@ -0,0 +1,16 @@
#pragma once
#include "search/search_params.hpp"
#include "std/string.hpp"
namespace search
{
struct EverywhereSearchParams
{
string m_query;
string m_inputLocale;
SearchParams::TOnResults m_onResults;
};
} // namespace search

View file

@ -411,6 +411,7 @@ void UniteCBVs(vector<CBV> & cbvs)
// Geocoder::Params --------------------------------------------------------------------------------
Geocoder::Params::Params() : m_mode(Mode::Everywhere) {}
// Geocoder::Geocoder ------------------------------------------------------------------------------
Geocoder::Geocoder(Index const & index, storage::CountryInfoGetter const & infoGetter,
PreRanker & preRanker, my::Cancellable const & cancellable)
@ -850,7 +851,7 @@ void Geocoder::ForEachCountry(vector<shared_ptr<MwmInfo>> const & infos, TFn &&
auto const & info = infos[i];
if (info->GetType() != MwmInfo::COUNTRY && info->GetType() != MwmInfo::WORLD)
continue;
if (info->GetType() == MwmInfo::COUNTRY && m_params.m_mode == Mode::World)
if (info->GetType() == MwmInfo::COUNTRY && m_params.m_mode == Mode::Downloader)
continue;
auto handle = m_index.GetMwmHandleById(MwmSet::MwmId(info));

View file

@ -1,25 +0,0 @@
#include "search/interactive_search_callback.hpp"
#include "search/result.hpp"
namespace search
{
InteractiveSearchCallback::InteractiveSearchCallback(TSetDisplacementMode && setMode,
TOnResults && onResults)
: m_setMode(move(setMode)), m_onResults(move(onResults)), m_hotelsModeSet(false)
{
}
void InteractiveSearchCallback::operator()(search::Results const & results)
{
m_hotelsClassif.AddBatch(results);
if (!m_hotelsModeSet && m_hotelsClassif.IsHotelQuery())
{
m_setMode();
m_hotelsModeSet = true;
}
m_onResults(results);
}
} // namespace search

View file

@ -1,32 +0,0 @@
#pragma once
#include "search/hotels_classifier.hpp"
#include "search/params.hpp"
#include "std/function.hpp"
namespace search
{
class Results;
// An on-results-callback that should be used for interactive search.
//
// *NOTE* the class is NOT thread safe.
class InteractiveSearchCallback
{
public:
using TSetDisplacementMode = function<void()>;
using TOnResults = search::TOnResults;
InteractiveSearchCallback(TSetDisplacementMode && setMode, TOnResults && onResults);
void operator()(search::Results const & results);
private:
TSetDisplacementMode m_setMode;
TOnResults m_onResults;
search::HotelsClassifier m_hotelsClassif;
bool m_hotelsModeSet;
};
} // namespace search

View file

@ -6,9 +6,10 @@ string DebugPrint(Mode mode)
{
switch (mode)
{
case Mode::Viewport: return "Viewport";
case Mode::Everywhere: return "Everywhere";
case Mode::World: return "World";
case Mode::Viewport: return "Viewport";
case Mode::Downloader: return "Downloader";
case Mode::Count: return "Count";
}
return "Unknown";
}

View file

@ -6,9 +6,10 @@ namespace search
{
enum class Mode
{
Viewport,
Everywhere,
World
Viewport,
Downloader,
Count
};
string DebugPrint(Mode mode);

View file

@ -1,70 +0,0 @@
#pragma once
#include "search/mode.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "std/function.hpp"
#include "std/string.hpp"
namespace search
{
class Results;
using TOnStarted = function<void()>;
using TOnResults = function<void (Results const &)>;
class SearchParams
{
public:
SearchParams();
/// @name Force run search without comparing with previous search params.
//@{
void SetForceSearch(bool b) { m_forceSearch = b; }
bool IsForceSearch() const { return m_forceSearch; }
//@}
inline void SetMode(Mode mode) { m_mode = mode; }
inline Mode GetMode() const { return m_mode; }
void SetPosition(double lat, double lon);
inline bool IsValidPosition() const { return m_validPos; }
inline bool IsSearchAroundPosition() const
{
return (m_searchRadiusM > 0 && IsValidPosition());
}
inline void SetSearchRadiusMeters(double radiusM) { m_searchRadiusM = radiusM; }
bool GetSearchRect(m2::RectD & rect) const;
/// @param[in] locale can be "fr", "en-US", "ru_RU" etc.
inline void SetInputLocale(string const & locale) { m_inputLocale = locale; }
inline void SetSuggestsEnabled(bool enabled) { m_suggestsEnabled = enabled; }
inline bool GetSuggestsEnabled() const { return m_suggestsEnabled; }
bool IsEqualCommon(SearchParams const & rhs) const;
inline void Clear() { m_query.clear(); }
TOnStarted m_onStarted;
TOnResults m_onResults;
string m_query;
string m_inputLocale;
double m_lat, m_lon;
friend string DebugPrint(SearchParams const & params);
private:
double m_searchRadiusM;
Mode m_mode;
bool m_forceSearch;
bool m_validPos;
bool m_suggestsEnabled;
};
} // namespace search

View file

@ -1,10 +1,10 @@
#pragma once
#include "search/geocoder.hpp"
#include "search/mode.hpp"
#include "search/params.hpp"
#include "search/pre_ranker.hpp"
#include "search/ranker.hpp"
#include "search/rank_table_cache.hpp"
#include "search/ranker.hpp"
#include "search/search_params.hpp"
#include "search/search_trie.hpp"
#include "search/suggest.hpp"
#include "search/token_slice.hpp"
@ -84,7 +84,7 @@ public:
inline void SetMode(Mode mode) { m_mode = mode; }
inline void SetSuggestsEnabled(bool enabled) { m_suggestsEnabled = enabled; }
inline void SetPosition(m2::PointD const & position) { m_position = position; }
inline void SetOnResults(TOnResults const & onResults) { m_onResults = onResults; }
inline void SetOnResults(SearchParams::TOnResults const & onResults) { m_onResults = onResults; }
inline string const & GetPivotRegion() const { return m_region; }
inline m2::PointD const & GetPosition() const { return m_position; }
@ -152,7 +152,7 @@ protected:
m2::PointD m_position;
Mode m_mode;
bool m_suggestsEnabled;
TOnResults m_onResults;
SearchParams::TOnResults m_onResults;
/// @name Get ranking params.
//@{

View file

@ -1,7 +1,7 @@
#pragma once
#include "search/params.hpp"
#include "search/processor.hpp"
#include "search/search_params.hpp"
#include "search/suggest.hpp"
#include "std/unique_ptr.hpp"

View file

@ -6,9 +6,9 @@
#include "search/keyword_lang_matcher.hpp"
#include "search/locality_finder.hpp"
#include "search/mode.hpp"
#include "search/params.hpp"
#include "search/result.hpp"
#include "search/reverse_geocoder.hpp"
#include "search/search_params.hpp"
#include "search/suggest.hpp"
#include "indexer/categories_holder.hpp"
@ -62,7 +62,7 @@ public:
TLocales m_categoryLocales;
size_t m_limit = 0;
TOnResults m_onResults;
SearchParams::TOnResults m_onResults;
};
static size_t const kBatchSize;

View file

@ -319,10 +319,10 @@ string DebugPrint(AddressInfo const & info)
return info.FormatNameAndAddress();
}
string DebugPrint(Result const & r)
string DebugPrint(Result const & result)
{
return "Result { Name: " + r.GetString() + "; Type: " + r.GetFeatureType() +
"; Info: " + DebugPrint(r.GetRankingInfo()) + " }";
return "Result { Name: " + result.GetString() + "; Type: " + result.GetFeatureType() +
"; Info: " + DebugPrint(result.GetRankingInfo()) + " }";
}
} // namespace search

View file

@ -15,7 +15,6 @@
namespace search
{
// Search result. Search returns a list of them, ordered by score.
class Result
{
@ -152,14 +151,14 @@ class Results
public:
Results() : m_status(NONE) {}
/// @name To implement end of search notification.
//@{
static Results GetEndMarker(bool isCancelled) { return Results(isCancelled); }
bool IsEndMarker() const { return (m_status != NONE); }
bool IsEndedNormal() const { return (m_status == ENDED); }
//@}
bool IsEndedCancelled() const { return m_status == ENDED_CANCELLED; }
bool AddResult(Result && res);
/// Fast function that don't do any duplicates checks.
/// Used in viewport search only.
void AddResultNoChecks(Result && res)
@ -172,8 +171,6 @@ public:
inline void Clear() { m_vec.clear(); }
typedef vector<Result>::const_iterator IterT;
inline IterT Begin() const { return m_vec.begin(); }
inline IterT End() const { return m_vec.end(); }
inline IterT begin() const { return m_vec.begin(); }
inline IterT end() const { return m_vec.end(); }
@ -221,11 +218,10 @@ struct AddressInfo
// Caroline, 7 vulica Frunze, Minsk, Belarus
string FormatNameAndAddress(AddressType type = DEFAULT) const;
friend string DebugPrint(AddressInfo const & info);
void Clear();
friend string DebugPrint(AddressInfo const & info);
};
string DebugPrint(search::Result const &);
string DebugPrint(search::Result const & result);
} // namespace search

View file

@ -16,6 +16,7 @@ HEADERS += \
common.hpp \
dummy_rank_table.hpp \
engine.hpp \
everywhere_search_params.hpp \
feature_offset_match.hpp \
features_filter.hpp \
features_layer.hpp \
@ -29,7 +30,6 @@ HEADERS += \
house_detector.hpp \
house_numbers_matcher.hpp \
house_to_street_table.hpp \
interactive_search_callback.hpp \
intermediate_result.hpp \
intersection_result.hpp \
interval_set.hpp \
@ -44,7 +44,6 @@ HEADERS += \
model.hpp \
mwm_context.hpp \
nested_rects_cache.hpp \
params.hpp \
pre_ranker.hpp \
pre_ranking_info.hpp \
processor.hpp \
@ -61,6 +60,7 @@ HEADERS += \
retrieval.hpp \
reverse_geocoder.hpp \
search_index_values.hpp \
search_params.hpp \
search_trie.hpp \
stats_cache.hpp \
street_vicinity_loader.hpp \
@ -70,6 +70,8 @@ HEADERS += \
token_slice.hpp \
types_skipper.hpp \
utils.hpp \
viewport_search_callback.hpp \
viewport_search_params.hpp
SOURCES += \
approximate_string_match.cpp \
@ -88,7 +90,6 @@ SOURCES += \
house_detector.cpp \
house_numbers_matcher.cpp \
house_to_street_table.cpp \
interactive_search_callback.cpp \
intermediate_result.cpp \
intersection_result.cpp \
keyword_lang_matcher.cpp \
@ -102,7 +103,6 @@ SOURCES += \
model.cpp \
mwm_context.cpp \
nested_rects_cache.cpp \
params.cpp \
pre_ranker.cpp \
pre_ranking_info.cpp \
processor.cpp \
@ -117,7 +117,9 @@ SOURCES += \
result.cpp \
retrieval.cpp \
reverse_geocoder.cpp \
search_params.cpp \
street_vicinity_loader.cpp \
streets_matcher.cpp \
token_slice.cpp \
types_skipper.cpp \
viewport_search_callback.cpp

View file

@ -2,7 +2,7 @@
#include "generator/generator_tests_support/test_feature.hpp"
#include "search/interactive_search_callback.hpp"
#include "search/viewport_search_callback.hpp"
#include "search/mode.hpp"
#include "search/search_integration_tests/helpers.hpp"
#include "search/search_tests_support/test_results_matching.hpp"
@ -37,16 +37,33 @@ public:
}
};
class InteractiveSearchRequest : public TestSearchRequest
class TestDelegate : public ViewportSearchCallback::Delegate
{
public:
TestDelegate(bool & mode) : m_mode(mode) {}
// ViewportSearchCallback::Delegate overrides:
void RunUITask(function<void()> /* fn */) override {}
void SetHotelDisplacementMode() override { m_mode = true; }
bool IsViewportSearchActive() const override { return true; }
void ShowViewportSearchResults(Results const & /* results */) override {}
void ClearViewportSearchResults() override {}
private:
bool & m_mode;
};
class InteractiveSearchRequest : public TestDelegate, public TestSearchRequest
{
public:
InteractiveSearchRequest(TestSearchEngine & engine, string const & query,
m2::RectD const & viewport, bool & mode)
: TestSearchRequest(
: TestDelegate(mode)
, TestSearchRequest(
engine, query, "en" /* locale */, Mode::Viewport, viewport,
bind(&InteractiveSearchRequest::OnStarted, this),
InteractiveSearchCallback([&mode]() { mode = true; },
bind(&InteractiveSearchRequest::OnResults, this, _1)))
ViewportSearchCallback(static_cast<ViewportSearchCallback::Delegate &>(*this),
bind(&InteractiveSearchRequest::OnResults, this, _1)))
{
}
};

View file

@ -267,7 +267,7 @@ UNIT_CLASS_TEST(ProcessorTest, SearchByName)
SetViewport(m2::RectD(m2::PointD(0.5, 0.5), m2::PointD(1.5, 1.5)));
{
TRules rules = {ExactMatch(worldId, london)};
TEST(ResultsMatch("london", Mode::World, rules), ());
TEST(ResultsMatch("london", Mode::Downloader, rules), ());
}
{
TRules rules = {ExactMatch(worldId, london), ExactMatch(wonderlandId, cafe)};
@ -291,7 +291,7 @@ UNIT_CLASS_TEST(ProcessorTest, DisableSuggests)
SearchParams params;
params.m_query = "londo";
params.m_inputLocale = "en";
params.SetMode(Mode::World);
params.SetMode(Mode::Downloader);
params.SetSuggestsEnabled(false);
TestSearchRequest request(m_engine, params, m_viewport);

View file

@ -1,10 +1,9 @@
#include "params.hpp"
#include "search/search_params.hpp"
#include "geometry/mercator.hpp"
#include "coding/multilang_utf8_string.hpp"
namespace search
{
SearchParams::SearchParams()
@ -37,10 +36,8 @@ bool SearchParams::GetSearchRect(m2::RectD & rect) const
bool SearchParams::IsEqualCommon(SearchParams const & rhs) const
{
return (m_query == rhs.m_query &&
m_inputLocale == rhs.m_inputLocale &&
m_validPos == rhs.m_validPos &&
m_mode == rhs.m_mode &&
return (m_query == rhs.m_query && m_inputLocale == rhs.m_inputLocale &&
m_validPos == rhs.m_validPos && m_mode == rhs.m_mode &&
m_searchRadiusM == rhs.m_searchRadiusM);
}
@ -51,4 +48,4 @@ string DebugPrint(SearchParams const & params)
<< ", Mode = " << DebugPrint(params.m_mode) << " }";
return ss.str();
}
} // namespace search
} // namespace search

61
search/search_params.hpp Normal file
View file

@ -0,0 +1,61 @@
#pragma once
#include "search/mode.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "std/function.hpp"
#include "std/string.hpp"
namespace search
{
class Results;
class SearchParams
{
public:
using TOnStarted = function<void()>;
using TOnResults = function<void(Results const &)>;
SearchParams();
/// @name Force run search without comparing with previous search params.
//@{
void SetForceSearch(bool b) { m_forceSearch = b; }
bool IsForceSearch() const { return m_forceSearch; }
//@}
inline void SetMode(Mode mode) { m_mode = mode; }
inline Mode GetMode() const { return m_mode; }
void SetPosition(double lat, double lon);
inline bool IsValidPosition() const { return m_validPos; }
inline bool IsSearchAroundPosition() const { return (m_searchRadiusM > 0 && IsValidPosition()); }
inline void SetSearchRadiusMeters(double radiusM) { m_searchRadiusM = radiusM; }
bool GetSearchRect(m2::RectD & rect) const;
/// @param[in] locale can be "fr", "en-US", "ru_RU" etc.
inline void SetInputLocale(string const & locale) { m_inputLocale = locale; }
inline void SetSuggestsEnabled(bool enabled) { m_suggestsEnabled = enabled; }
inline bool GetSuggestsEnabled() const { return m_suggestsEnabled; }
bool IsEqualCommon(SearchParams const & rhs) const;
inline void Clear() { m_query.clear(); }
TOnStarted m_onStarted;
TOnResults m_onResults;
string m_query;
string m_inputLocale;
double m_lat, m_lon;
friend string DebugPrint(SearchParams const & params);
private:
double m_searchRadiusM;
Mode m_mode;
bool m_forceSearch;
bool m_validPos;
bool m_suggestsEnabled;
};
} // namespace search

View file

@ -1,4 +1,4 @@
#include "search/params.hpp"
#include "search/search_params.hpp"
#include "indexer/classificator_loader.hpp"
#include "indexer/data_header.hpp"

View file

@ -31,7 +31,8 @@ TestSearchRequest::TestSearchRequest(TestSearchEngine & engine, SearchParams par
TestSearchRequest::TestSearchRequest(TestSearchEngine & engine, string const & query,
string const & locale, Mode mode, m2::RectD const & viewport,
TOnStarted onStarted, TOnResults onResults)
SearchParams::TOnStarted onStarted,
SearchParams::TOnResults onResults)
{
SearchParams params;
params.m_query = query;
@ -88,7 +89,7 @@ void TestSearchRequest::OnResults(search::Results const & results)
}
else
{
m_results.assign(results.Begin(), results.End());
m_results.assign(results.begin(), results.end());
}
}
} // namespace tests_support

View file

@ -2,8 +2,8 @@
#include "geometry/rect2d.hpp"
#include "search/params.hpp"
#include "search/result.hpp"
#include "search/search_params.hpp"
#include "std/condition_variable.hpp"
#include "std/mutex.hpp"
@ -36,8 +36,8 @@ public:
protected:
TestSearchRequest(TestSearchEngine & engine, string const & query, string const & locale,
Mode mode, m2::RectD const & viewport, TOnStarted onStarted,
TOnResults onResults);
Mode mode, m2::RectD const & viewport, SearchParams::TOnStarted onStarted,
SearchParams::TOnResults onResults);
void SetUpCallbacks(SearchParams & params);

View file

@ -0,0 +1,43 @@
#include "search/viewport_search_callback.hpp"
#include "search/result.hpp"
namespace search
{
ViewportSearchCallback::ViewportSearchCallback(Delegate & delegate, TOnResults onResults)
: m_delegate(delegate), m_onResults(move(onResults)), m_hotelsModeSet(false), m_firstCall(true)
{
}
void ViewportSearchCallback::operator()(Results const & results)
{
m_hotelsClassif.AddBatch(results);
if (!m_hotelsModeSet && m_hotelsClassif.IsHotelQuery())
{
m_delegate.SetHotelDisplacementMode();
m_hotelsModeSet = true;
}
if (!results.IsEndMarker())
{
auto & delegate = m_delegate;
bool const firstCall = m_firstCall;
m_delegate.RunUITask([&delegate, firstCall, results]() {
if (!delegate.IsViewportSearchActive())
return;
if (firstCall)
delegate.ClearViewportSearchResults();
delegate.ShowViewportSearchResults(results);
});
}
if (m_onResults)
m_onResults(results);
m_firstCall = false;
}
} // namespace search

View file

@ -0,0 +1,44 @@
#pragma once
#include "search/hotels_classifier.hpp"
#include "search/search_params.hpp"
#include "std/function.hpp"
namespace search
{
class Results;
// An on-results-callback that should be used for interactive search.
//
// *NOTE* the class is NOT thread safe.
class ViewportSearchCallback
{
public:
class Delegate
{
public:
virtual ~Delegate() = default;
virtual void RunUITask(function<void()> fn) = 0;
virtual void SetHotelDisplacementMode() = 0;
virtual bool IsViewportSearchActive() const = 0;
virtual void ShowViewportSearchResults(Results const & results) = 0;
virtual void ClearViewportSearchResults() = 0;
};
using TOnResults = SearchParams::TOnResults;
ViewportSearchCallback(Delegate & delegate, TOnResults onResults);
void operator()(Results const & results);
private:
Delegate & m_delegate;
TOnResults m_onResults;
HotelsClassifier m_hotelsClassif;
bool m_hotelsModeSet;
bool m_firstCall;
};
} // namespace search

View file

@ -0,0 +1,19 @@
#pragma once
#include "std/function.hpp"
#include "std/string.hpp"
namespace search
{
struct ViewportSearchParams
{
using TOnStarted = function<void()>;
using TOnCompleted = function<void()>;
string m_query;
string m_inputLocale;
TOnStarted m_onStarted;
TOnCompleted m_onCompleted;
};
} // namespace search