Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coding/uri.cpp8
-rw-r--r--map/framework.cpp30
-rw-r--r--map/framework.hpp5
-rw-r--r--map/map_tests/mwm_url_tests.cpp26
-rw-r--r--map/mwm_url.cpp144
-rw-r--r--map/mwm_url.hpp17
-rw-r--r--xcode/map/map.xcodeproj/project.pbxproj4
7 files changed, 183 insertions, 51 deletions
diff --git a/coding/uri.cpp b/coding/uri.cpp
index 4b98a96839..4894e7df9f 100644
--- a/coding/uri.cpp
+++ b/coding/uri.cpp
@@ -51,7 +51,13 @@ bool Uri::ForEachKeyValue(TCallback const & callback) const
{
// parse query for keys and values
size_t const count = m_url.size();
- for (size_t start = m_queryStart; start < count; )
+ size_t const queryStart = m_queryStart;
+
+ // Just a URL without parametrs.
+ if (queryStart == count)
+ return false;
+
+ for (size_t start = queryStart; start < count; )
{
size_t end = m_url.find('&', start);
if (end == string::npos)
diff --git a/map/framework.cpp b/map/framework.cpp
index 725f02f5c7..8ae00581a9 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -317,6 +317,7 @@ void Framework::OnViewportChanged(ScreenBase const & screen)
UpdateUserViewportChanged();
m_currentModelView = screen;
+ m_isViewportInitialized = true;
m_trafficManager.UpdateViewport(m_currentModelView);
m_localAdsManager.UpdateViewport(m_currentModelView);
@@ -1290,7 +1291,6 @@ bool Framework::SearchEverywhere(search::EverywhereSearchParams const & params)
GetPlatform().RunOnGuiThread([params, results]() { params.m_onResults(results); });
};
SetCurrentPositionIfPossible(p);
-
return Search(p);
}
@@ -1490,14 +1490,10 @@ bool Framework::Search(search::SearchParams const & params)
if (ParseEditorDebugCommand(params))
return true;
- m2::RectD const viewport = GetCurrentViewport();
-
- if (QueryMayBeSkipped(intent, rParams, viewport))
+ if (QueryMayBeSkipped(intent, rParams, GetCurrentViewport()))
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);
@@ -1509,11 +1505,26 @@ bool Framework::Search(search::SearchParams const & params)
intent.m_params.m_minDistanceOnMapBetweenResults = eps;
}
- intent.m_handle = m_searchEngine->Search(intent.m_params, intent.m_viewport);
+ Search(intent);
return true;
}
+void Framework::Search(SearchIntent & intent) const
+{
+ if (!m_isViewportInitialized)
+ {
+ Platform().RunOnGuiThread([this, &intent]
+ {
+ this->Search(intent);
+ });
+ return;
+ }
+
+ intent.m_viewport = GetCurrentViewport();
+ intent.m_handle = m_searchEngine->Search(intent.m_params, intent.m_viewport);
+}
+
void Framework::SetCurrentPositionIfPossible(search::SearchParams & params)
{
double lat;
@@ -2074,6 +2085,11 @@ Framework::ParsedRoutingData Framework::GetParsedRoutingData() const
routing::FromString(m_ParsedMapApi.GetRoutingType()));
}
+url_scheme::SearchRequest Framework::GetParsedSearchRequest() const
+{
+ return m_ParsedMapApi.GetSearchRequest();
+}
+
unique_ptr<FeatureType> Framework::GetFeatureAtPoint(m2::PointD const & mercator) const
{
unique_ptr<FeatureType> poi, line, area;
diff --git a/map/framework.hpp b/map/framework.hpp
index 875337792a..b57c45ad4d 100644
--- a/map/framework.hpp
+++ b/map/framework.hpp
@@ -394,6 +394,7 @@ private:
};
unique_ptr<TapEvent> m_lastTapEvent;
+ bool m_isViewportInitialized = false;
void OnTapEvent(TapEvent const & tapEvent);
/// outInfo is valid only if return value is not df::SelectionShape::OBJECT_EMPTY.
@@ -497,8 +498,6 @@ private:
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);
@@ -516,6 +515,7 @@ private:
SearchIntent m_searchIntents[static_cast<size_t>(search::Mode::Count)];
bool Search(search::SearchParams const & params);
+ void Search(SearchIntent & intent) const;
// Returns true when |params| and |viewport| are almost the same as
// the latest search query's params and viewport in the |intent|.
@@ -624,6 +624,7 @@ public:
};
ParsedRoutingData GetParsedRoutingData() const;
+ url_scheme::SearchRequest GetParsedSearchRequest() const;
private:
// TODO(vng): Uncomment when needed.
diff --git a/map/map_tests/mwm_url_tests.cpp b/map/map_tests/mwm_url_tests.cpp
index 0d1261bd47..80d8d680ef 100644
--- a/map/map_tests/mwm_url_tests.cpp
+++ b/map/map_tests/mwm_url_tests.cpp
@@ -46,6 +46,7 @@ namespace
bool GoBackOnBalloonClick() const { return m_api.GoBackOnBalloonClick(); }
int GetPointCount() const { return UserMarkControllerGuard(*m_m, type).m_controller.GetUserMarkCount(); }
vector<RoutePoint> GetRoutePoints() const { return m_api.GetRoutePoints(); }
+ url_scheme::SearchRequest const & GetSearchRequest() const { return m_api.GetSearchRequest(); }
string const & GetGlobalBackUrl() const { return m_api.GetGlobalBackUrl(); }
int GetApiVersion() const { return m_api.GetApiVersion(); }
bool TestLatLon(int index, double lat, double lon) const
@@ -128,6 +129,31 @@ UNIT_TEST(RouteApiSmoke)
TEST(test.TestRouteType("vehicle"), ());
}
+UNIT_TEST(SearchApiSmoke)
+{
+ string const uriString = "mapsme://search?query=fff&cll=1,1&locale=ru&map";
+ TEST(Uri(uriString).IsValid(), ());
+
+ ApiTest test(uriString);
+ TEST(test.IsValid(), ());
+
+ auto const & request = test.GetSearchRequest();
+ TEST_EQUAL(request.m_query, "fff", ());
+ TEST_EQUAL(request.m_centerLat, 1, ());
+ TEST_EQUAL(request.m_centerLon, 1, ());
+ TEST_EQUAL(request.m_locale, "ru", ());
+ TEST(request.m_isSearchOnMap, ());
+}
+
+UNIT_TEST(SearchApiInvalidUrl)
+{
+ Framework f;
+ TEST(!IsValid(f, "mapsme://search?"), ("The url must have at least search query parametr"));
+ TEST(!IsValid(f, "mapsme://search?query"), ("Search query can't be empty"));
+ TEST(IsValid(f, "mapsme://search?query=aaa&cll=1,1,1"), ("If it's wrong lat lon format then just ignore it"));
+ TEST(IsValid(f, "mapsme://search?query=aaa&ignoreThisParam=sure"), ("We shouldn't fail search request if there are some unsopported parameters."));
+}
+
UNIT_TEST(MapApiInvalidUrl)
{
Framework fm;
diff --git a/map/mwm_url.cpp b/map/mwm_url.cpp
index 593f9a3ea8..ea7c0dec67 100644
--- a/map/mwm_url.cpp
+++ b/map/mwm_url.cpp
@@ -22,6 +22,10 @@ namespace url_scheme
namespace
{
string const kLatLon = "ll";
+string const kQuery = "query";
+string const kCenterLatLon = "cll";
+string const kLocale = "locale";
+string const kSearchOnMap = "map";
string const kSourceLatLon = "sll";
string const kDestLatLon = "dll";
string const kZoomLevel = "z";
@@ -39,6 +43,31 @@ string const kRouteTypeVehicle = "vehicle";
string const kRouteTypePedestrian = "pedestrian";
string const kRouteTypeBicycle = "bicycle";
+enum class ApiURLType
+{
+ Incorrect,
+ Map,
+ Route,
+ Search
+};
+
+ApiURLType URLTypeFrom(Uri const & uri)
+{
+ auto const scheme = uri.GetScheme();
+ if (scheme != "mapswithme" && scheme != "mwm" && scheme != "mapsme")
+ return ApiURLType::Incorrect;
+
+ auto const path = uri.GetPath();
+ if (path == "map")
+ return ApiURLType::Map;
+ if (path == "route")
+ return ApiURLType::Route;
+ if (path == "search")
+ return ApiURLType::Search;
+
+ return ApiURLType::Incorrect;
+}
+
bool ParseLatLon(string const & key, string const & value, double & lat, double & lon)
{
size_t const firstComma = value.find(',');
@@ -69,6 +98,7 @@ void ParsedMapApi::SetBookmarkManager(BookmarkManager * manager)
{
m_bmManager = manager;
}
+
ParsedMapApi::ParsingResult ParsedMapApi::SetUriAndParse(string const & url)
{
Reset();
@@ -86,53 +116,58 @@ ParsedMapApi::ParsingResult ParsedMapApi::SetUriAndParse(string const & url)
ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri)
{
- string const & scheme = uri.GetScheme();
- string const & path = uri.GetPath();
- bool const isRoutePath = path == "route";
- if ((scheme != "mapswithme" && scheme != "mwm" && scheme != "mapsme") ||
- (path != "map" && !isRoutePath))
+ switch (URLTypeFrom(uri))
{
- return ParsingResult::Incorrect;
- }
-
- if (isRoutePath)
- {
- m_routePoints.clear();
- vector<string> pattern{kSourceLatLon, kSourceName, kDestLatLon, kDestName, kRouteType};
- if (!uri.ForEachKeyValue(bind(&ParsedMapApi::RouteKeyValue, this, _1, _2, ref(pattern))))
+ case ApiURLType::Incorrect:
return ParsingResult::Incorrect;
-
- if (pattern.size() != 0)
- return ParsingResult::Incorrect;
-
- if (m_routePoints.size() != 2)
+ case ApiURLType::Map:
{
- ASSERT(false, ());
- return ParsingResult::Incorrect;
+ vector<ApiPoint> points;
+ if (!uri.ForEachKeyValue(bind(&ParsedMapApi::AddKeyValue, this, _1, _2, ref(points))))
+ return ParsingResult::Incorrect;
+
+ if (points.empty())
+ return ParsingResult::Incorrect;
+
+ ASSERT(m_bmManager != nullptr, ());
+ UserMarkControllerGuard guard(*m_bmManager, UserMarkType::API_MARK);
+ for (auto const & p : points)
+ {
+ m2::PointD glPoint(MercatorBounds::FromLatLon(p.m_lat, p.m_lon));
+ ApiMarkPoint * mark = static_cast<ApiMarkPoint *>(guard.m_controller.CreateUserMark(glPoint));
+ mark->SetName(p.m_name);
+ mark->SetID(p.m_id);
+ mark->SetStyle(style::GetSupportedStyle(p.m_style, p.m_name, ""));
+ }
+
+ return ParsingResult::Map;
}
+ case ApiURLType::Route:
+ {
+ m_routePoints.clear();
+ vector<string> pattern{kSourceLatLon, kSourceName, kDestLatLon, kDestName, kRouteType};
+ if (!uri.ForEachKeyValue(bind(&ParsedMapApi::RouteKeyValue, this, _1, _2, ref(pattern))))
+ return ParsingResult::Incorrect;
- return ParsingResult::Route;
- }
-
- vector<ApiPoint> points;
- if (!uri.ForEachKeyValue(bind(&ParsedMapApi::AddKeyValue, this, _1, _2, ref(points))))
- return ParsingResult::Incorrect;
+ if (pattern.size() != 0)
+ return ParsingResult::Incorrect;
- if (points.empty())
- return ParsingResult::Incorrect;
+ if (m_routePoints.size() != 2)
+ {
+ ASSERT(false, ());
+ return ParsingResult::Incorrect;
+ }
- ASSERT(m_bmManager != nullptr, ());
- UserMarkControllerGuard guard(*m_bmManager, UserMarkType::API_MARK);
- for (auto const & p : points)
- {
- m2::PointD glPoint(MercatorBounds::FromLatLon(p.m_lat, p.m_lon));
- ApiMarkPoint * mark = static_cast<ApiMarkPoint *>(guard.m_controller.CreateUserMark(glPoint));
- mark->SetName(p.m_name);
- mark->SetID(p.m_id);
- mark->SetStyle(style::GetSupportedStyle(p.m_style, p.m_name, ""));
+ return ParsingResult::Route;
+ }
+ case ApiURLType::Search:
+ SearchRequest request;
+ if (!uri.ForEachKeyValue(bind(&ParsedMapApi::SearchKeyValue, this, _1, _2, ref(request))))
+ return ParsingResult::Incorrect;
+
+ m_request = request;
+ return ParsingResult::Search;
}
-
- return ParsingResult::Map;
}
bool ParsedMapApi::RouteKeyValue(string key, string const & value, vector<string> & pattern)
@@ -252,6 +287,37 @@ bool ParsedMapApi::AddKeyValue(string key, string const & value, vector<ApiPoint
return true;
}
+bool ParsedMapApi::SearchKeyValue(string key, string const & value, SearchRequest & request)
+{
+ if (key == kQuery)
+ {
+ if (value.empty())
+ return false;
+
+ request.m_query = value;
+ }
+ else if (key == kCenterLatLon)
+ {
+ double lat = 0.0;
+ double lon = 0.0;
+ if (ParseLatLon(key, value, lat, lon))
+ {
+ request.m_centerLat = lat;
+ request.m_centerLon = lon;
+ }
+ }
+ else if (key == kLocale)
+ {
+ request.m_locale = value;
+ }
+ else if (key == kSearchOnMap)
+ {
+ request.m_isSearchOnMap = true;
+ }
+
+ return !request.m_query.empty();
+}
+
void ParsedMapApi::Reset()
{
m_globalBackUrl.clear();
diff --git a/map/mwm_url.hpp b/map/mwm_url.hpp
index 3192ed7727..8ac94d1b68 100644
--- a/map/mwm_url.hpp
+++ b/map/mwm_url.hpp
@@ -28,9 +28,18 @@ struct RoutePoint
string m_name;
};
+struct SearchRequest
+{
+ string m_query;
+ string m_locale;
+ double m_centerLat = 0.0;
+ double m_centerLon = 0.0;
+ bool m_isSearchOnMap = false;
+};
+
class Uri;
-/// Handles [mapswithme|mwm]://map?params - everything related to displaying info on a map
+/// Handles [mapswithme|mwm|mapsme]://map|route|search?params - everything related to displaying info on a map
class ParsedMapApi
{
public:
@@ -38,7 +47,8 @@ public:
{
Incorrect,
Map,
- Route
+ Route,
+ Search
};
ParsedMapApi() = default;
@@ -58,13 +68,16 @@ public:
ApiMarkPoint const * GetSinglePoint() const;
vector<RoutePoint> const & GetRoutePoints() const { return m_routePoints; }
string const & GetRoutingType() const { return m_routingType; }
+ SearchRequest const & GetSearchRequest() const { return m_request; }
private:
ParsingResult Parse(Uri const & uri);
bool AddKeyValue(string key, string const & value, vector<ApiPoint> & points);
bool RouteKeyValue(string key, string const & value, vector<string> & pattern);
+ bool SearchKeyValue(string key, string const & value, SearchRequest & request);
BookmarkManager * m_bmManager = nullptr;
vector<RoutePoint> m_routePoints;
+ SearchRequest m_request;
string m_globalBackUrl;
string m_appTitle;
string m_routingType;
diff --git a/xcode/map/map.xcodeproj/project.pbxproj b/xcode/map/map.xcodeproj/project.pbxproj
index c873d680be..78cca016a4 100644
--- a/xcode/map/map.xcodeproj/project.pbxproj
+++ b/xcode/map/map.xcodeproj/project.pbxproj
@@ -94,6 +94,7 @@
67F183831BD5049500AB1840 /* libminizip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67F1837F1BD5049500AB1840 /* libminizip.a */; };
67F183841BD5049500AB1840 /* libtess2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67F183801BD5049500AB1840 /* libtess2.a */; };
BB421D6C1E8C0031005BFA4D /* transliteration_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB421D6A1E8C0026005BFA4D /* transliteration_test.cpp */; };
+ F627BFC41E8E89B600B1CBF4 /* librouting_common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F627BFC31E8E89B600B1CBF4 /* librouting_common.a */; };
F63421F81DF9BF9100A96868 /* reachable_by_taxi_checker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F63421F61DF9BF9100A96868 /* reachable_by_taxi_checker.cpp */; };
F63421F91DF9BF9100A96868 /* reachable_by_taxi_checker.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F63421F71DF9BF9100A96868 /* reachable_by_taxi_checker.hpp */; };
F6B283031C1B03320081957A /* gps_track_collection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B282FB1C1B03320081957A /* gps_track_collection.cpp */; };
@@ -216,6 +217,7 @@
67F183851BD504ED00AB1840 /* libsystem_configuration.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsystem_configuration.tbd; path = usr/lib/system/libsystem_configuration.tbd; sourceTree = SDKROOT; };
67F183871BD5050900AB1840 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
BB421D6A1E8C0026005BFA4D /* transliteration_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transliteration_test.cpp; sourceTree = "<group>"; };
+ F627BFC31E8E89B600B1CBF4 /* librouting_common.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = librouting_common.a; path = "/Users/v.mikhaylenko/mapsme/omim/xcode/routing_common/../../../omim-build/xcode/Debug/librouting_common.a"; sourceTree = "<absolute>"; };
F63421F61DF9BF9100A96868 /* reachable_by_taxi_checker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reachable_by_taxi_checker.cpp; sourceTree = "<group>"; };
F63421F71DF9BF9100A96868 /* reachable_by_taxi_checker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = reachable_by_taxi_checker.hpp; sourceTree = "<group>"; };
F6B282FB1C1B03320081957A /* gps_track_collection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gps_track_collection.cpp; sourceTree = "<group>"; };
@@ -240,6 +242,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ F627BFC41E8E89B600B1CBF4 /* librouting_common.a in Frameworks */,
674231CB1DF984F600913FEB /* libtraffic.a in Frameworks */,
34DDA1811DBE5DF40088A609 /* libpartners_api.a in Frameworks */,
34DDA1821DBE5DF40088A609 /* libtracking.a in Frameworks */,
@@ -291,6 +294,7 @@
34DDA17E1DBE5DF40088A609 /* Frameworks */ = {
isa = PBXGroup;
children = (
+ F627BFC31E8E89B600B1CBF4 /* librouting_common.a */,
674231CA1DF984F600913FEB /* libtraffic.a */,
34DDA17F1DBE5DF40088A609 /* libpartners_api.a */,
34DDA1801DBE5DF40088A609 /* libtracking.a */,