diff --git a/libs/coding/url.hpp b/libs/coding/url.hpp
index a514babf7..ef3f6a5a0 100644
--- a/libs/coding/url.hpp
+++ b/libs/coding/url.hpp
@@ -41,6 +41,7 @@ public:
return &p.second;
return nullptr;
}
+ std::vector const & GetParams() const { return m_params; }
private:
bool Parse(std::string const & url);
diff --git a/libs/map/mwm_url.cpp b/libs/map/mwm_url.cpp
index ee7e3f32c..5d11bc75e 100644
--- a/libs/map/mwm_url.cpp
+++ b/libs/map/mwm_url.cpp
@@ -1,8 +1,19 @@
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+#include "platform/preferred_languages.hpp"
+#endif
+
#include "map/mwm_url.hpp"
#include "map/api_mark_point.hpp"
#include "map/bookmark_manager.hpp"
#include "map/framework.hpp"
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+#include "map/everywhere_search_params.hpp"
+#include "map/routing_manager.hpp"
+#include "map/routing_mark.hpp"
+
+#include "search/result.hpp"
+#endif
#include "ge0/geo_url_parser.hpp"
#include "ge0/parser.hpp"
@@ -17,8 +28,9 @@
#include "base/scope_guard.hpp"
#include "base/string_utils.hpp"
-#include
-#include
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+#include
+#endif
namespace url_scheme
{
@@ -238,6 +250,131 @@ ParsedMapApi::UrlType ParsedMapApi::SetUrlAndParse(std::string const & raw)
UNREACHABLE();
}
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ParsedMapApi::UrlType ParsedMapApi::ParseGeoNav(std::string const & raw, Framework & fm)
+{
+ Reset();
+ SCOPE_GUARD(guard, [this]
+ {
+ if (m_requestType == UrlType::Incorrect)
+ Reset();
+ });
+
+ url::Url const url(raw);
+
+ if (url.GetHost() == "place")
+ {
+ auto const latLon = url.GetParamValue("coordinate");
+ auto const addr = url.GetParamValue("address");
+
+ if (latLon)
+ {
+ auto const tokens = strings::Tokenize(*latLon, ",");
+ double lat;
+ double lon;
+
+ if (tokens.size() != 2 || !strings::to_double(tokens[0], lat) || !strings::to_double(tokens[1], lon) ||
+ !mercator::ValidLat(lat) || !mercator::ValidLon(lon))
+ {
+ LOG(LWARNING, ("Invalid lat,lon in", raw));
+ return m_requestType = UrlType::Incorrect;
+ }
+
+ if (addr)
+ {
+ m_searchRequest = SearchRequest();
+ m_searchRequest.m_query = *addr;
+ m_centerLatLon = {lat, lon};
+ return m_requestType = UrlType::Search;
+ }
+
+ else
+ {
+ m_centerLatLon = {lat, lon};
+ m_mapPoints.push_back({lat /* m_lat */, lon /* m_lon */, "" /* m_label */, "" /* m_id */, "" /* m_style */});
+ return m_requestType = UrlType::Map;
+ }
+ }
+
+ else if (addr)
+ {
+ m_searchRequest = SearchRequest();
+ m_searchRequest.m_query = *addr;
+ return m_requestType = UrlType::Search;
+ }
+ }
+
+ else if (url.GetHost() == "directions")
+ {
+ auto const source = url.GetParamValue("source");
+ auto const destination = url.GetParamValue("destination");
+
+ if (source)
+ SetRouteMark(*source, fm, RouteMarkType::Finish);
+
+ if (url.GetParamValue("waypoint"))
+ for (auto const & param : url.GetParams())
+ if (param.first == "waypoint")
+ SetRouteMark(param.second, fm, RouteMarkType::Intermediate);
+
+ if (destination)
+ SetRouteMark(*destination, fm, RouteMarkType::Finish);
+
+ if (source || destination)
+ {
+ m_routingType = routing::ToString(routing::GetLastUsedRouter());
+
+ return m_requestType = UrlType::Route;
+ }
+
+ return m_requestType = UrlType::Incorrect;
+ }
+
+ return m_requestType = UrlType::Incorrect;
+}
+
+void ParsedMapApi::SetRouteMark(std::string_view const raw, Framework & fm, RouteMarkType const type)
+{
+ auto const tokens = strings::Tokenize(raw, ",");
+ double lat;
+ double lon;
+
+ if (tokens.size() != 2 || !strings::to_double(tokens[0], lat) || !strings::to_double(tokens[1], lon) ||
+ !mercator::ValidLat(lat) || !mercator::ValidLon(lon))
+ {
+ std::promise signal;
+ std::future future = signal.get_future();
+
+ ::search::EverywhereSearchParams params{
+ std::string(raw),
+ languages::GetMostPreferredLang(),
+ {} /* timeout */,
+ false,
+ // m_onResults
+ [this, type = std::move(type), &signal](::search::Results results, std::vector<::search::ProductInfo>)
+ {
+ auto const center = results[0].GetFeatureCenter();
+ RoutePoint p;
+ p.m_type = type;
+ p.m_org = mercator::FromLatLon(mercator::YToLat(center.y), mercator::XToLon(center.x));
+ p.m_name = results[0].GetString();
+ m_routePoints.push_back(p);
+ signal.set_value();
+ }};
+
+ fm.GetSearchAPI().SearchEverywhere(std::move(params));
+ future.wait();
+ }
+ else
+ {
+ RoutePoint p;
+ p.m_org = mercator::FromLatLon(lat, lon);
+ p.m_type = type;
+ m_routePoints.push_back(p);
+ }
+}
+#endif
+
void ParsedMapApi::ParseMapParam(std::string const & key, std::string const & value, bool & correctOrder)
{
using namespace map;
diff --git a/libs/map/mwm_url.hpp b/libs/map/mwm_url.hpp
index 0941ca242..eeba63e66 100644
--- a/libs/map/mwm_url.hpp
+++ b/libs/map/mwm_url.hpp
@@ -1,5 +1,10 @@
#pragma once
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+#include "map/everywhere_search_params.hpp"
+#include "map/routing_mark.hpp"
+#endif
+
#include "geometry/latlon.hpp"
#include "geometry/point2d.hpp"
@@ -22,9 +27,20 @@ struct MapPoint
struct RoutePoint
{
RoutePoint() = default;
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ RoutePoint(m2::PointD const & org, std::string const & name, RouteMarkType type)
+ : m_org(org)
+ , m_name(name)
+ , m_type(type)
+ {}
+#else
RoutePoint(m2::PointD const & org, std::string const & name) : m_org(org), m_name(name) {}
+#endif
m2::PointD m_org = m2::PointD::Zero();
std::string m_name;
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ RouteMarkType m_type;
+#endif
};
struct SearchRequest
@@ -66,6 +82,9 @@ public:
explicit ParsedMapApi(std::string const & url) { SetUrlAndParse(url); }
UrlType SetUrlAndParse(std::string const & url);
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ UrlType ParseGeoNav(std::string const & raw, Framework & fm);
+#endif
UrlType GetRequestType() const { return m_requestType; }
std::string const & GetGlobalBackUrl() const { return m_globalBackUrl; }
std::string const & GetAppName() const { return m_appName; }
@@ -123,6 +142,9 @@ public:
private:
void ParseMapParam(std::string const & key, std::string const & value, bool & correctOrder);
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ void SetRouteMark(std::string_view const raw, Framework & fm, RouteMarkType const type);
+#endif
void ParseRouteParam(std::string const & key, std::string const & value, std::vector & pattern);
void ParseSearchParam(std::string const & key, std::string const & value);
void ParseInAppFeatureHighlightParam(std::string const & key, std::string const & value);
diff --git a/libs/map/routing_manager.cpp b/libs/map/routing_manager.cpp
index 5507debd4..8fd4a243a 100644
--- a/libs/map/routing_manager.cpp
+++ b/libs/map/routing_manager.cpp
@@ -470,10 +470,10 @@ void RoutingManager::OnLocationUpdate(location::GpsInfo const & info)
RouterType RoutingManager::GetBestRouter(m2::PointD const & startPoint, m2::PointD const & finalPoint) const
{
// todo Implement something more sophisticated here (or delete the method).
- return GetLastUsedRouter();
+ return routing::GetLastUsedRouter();
}
-RouterType RoutingManager::GetLastUsedRouter() const
+RouterType routing::GetLastUsedRouter()
{
string routerTypeStr;
if (!settings::Get(kRouterTypeKey, routerTypeStr))
diff --git a/libs/map/routing_manager.hpp b/libs/map/routing_manager.hpp
index 59fc30e85..0ecf4e5a3 100644
--- a/libs/map/routing_manager.hpp
+++ b/libs/map/routing_manager.hpp
@@ -40,6 +40,7 @@ class CountryInfoGetter;
namespace routing
{
class NumMwmIds;
+RouterType GetLastUsedRouter();
}
class DataSource;
@@ -172,7 +173,6 @@ public:
m2::PointD GetRouteEndPoint() const { return m_routingSession.GetEndPoint(); }
/// Returns the most situable router engine type.
routing::RouterType GetBestRouter(m2::PointD const & startPoint, m2::PointD const & finalPoint) const;
- routing::RouterType GetLastUsedRouter() const;
void SetLastUsedRouter(routing::RouterType type);
// Sound notifications for turn instructions.
void EnableTurnNotifications(bool enable) { m_routingSession.EnableTurnNotifications(enable); }
diff --git a/libs/platform/preferred_languages.cpp b/libs/platform/preferred_languages.cpp
index a2c28d73b..989a628f0 100644
--- a/libs/platform/preferred_languages.cpp
+++ b/libs/platform/preferred_languages.cpp
@@ -579,6 +579,11 @@ std::string GetCurrentMapLanguage()
return languageCode;
}
+std::string GetMostPreferredLang()
+{
+ return std::string(StringUtf8Multilang::GetLangByCode(GetPreferredLangIndexes()[0]));
+}
+
std::vector GetPreferredLangIndexes()
{
std::vector langs = {};
diff --git a/libs/platform/preferred_languages.hpp b/libs/platform/preferred_languages.hpp
index 1ec78582e..03be5098d 100644
--- a/libs/platform/preferred_languages.hpp
+++ b/libs/platform/preferred_languages.hpp
@@ -25,6 +25,7 @@ std::string GetCurrentMapTwine();
std::string Normalize(std::string_view lang);
std::string GetCurrentNorm();
std::string GetCurrentMapLanguage();
+std::string GetMostPreferredLang();
std::vector GetPreferredLangIndexes();
buffer_vector const & GetSystemPreferred();
diff --git a/libs/platform/settings.cpp b/libs/platform/settings.cpp
index 500906c13..bb895fb2b 100644
--- a/libs/platform/settings.cpp
+++ b/libs/platform/settings.cpp
@@ -49,6 +49,13 @@ bool FromString(string const & strIn, string & strOut)
return true;
}
+template <>
+bool FromString(string const & strIn, std::string_view & strOut)
+{
+ strOut = strIn;
+ return true;
+}
+
namespace impl
{
template
diff --git a/libs/search/query_saver.cpp b/libs/search/query_saver.cpp
index e2cea6974..19c585c89 100644
--- a/libs/search/query_saver.cpp
+++ b/libs/search/query_saver.cpp
@@ -130,11 +130,13 @@ void QuerySaver::Deserialize(string const & data)
{
Length localeLength = ReadPrimitiveFromSource(reader);
vector locale(localeLength);
- reader.Read(&locale[0], localeLength);
- Length stringLength = ReadPrimitiveFromSource(reader);
- vector str(stringLength);
- reader.Read(&str[0], stringLength);
- m_topQueries.emplace_back(make_pair(string(&locale[0], localeLength), string(&str[0], stringLength)));
+ if (locale.size() > 0) {
+ reader.Read(&locale[0], localeLength);
+ Length stringLength = ReadPrimitiveFromSource(reader);
+ vector str(stringLength);
+ reader.Read(&str[0], stringLength);
+ m_topQueries.emplace_back(make_pair(string(&locale[0], localeLength), string(&str[0], stringLength)));
+ }
}
}