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:
authorConstantin Shalnev <c.shalnev@corp.mail.ru>2015-05-22 13:44:42 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:48:33 +0300
commit3ac8580696edf59736c2a7fc693cf65a44ad43a9 (patch)
tree7f43ef61de6b3b242bd7e6f2b724c5d38b17a143
parentd9f4d6994d738c7ffff01696bdc229a7579e0810 (diff)
Send statistics about pedestrian routing
-rw-r--r--map/framework.cpp28
-rw-r--r--map/routing_session.cpp4
-rw-r--r--map/routing_session.hpp8
-rw-r--r--routing/async_router.cpp110
-rw-r--r--routing/async_router.hpp28
-rw-r--r--routing/osrm_online_router.cpp4
-rw-r--r--routing/osrm_online_router.hpp4
-rw-r--r--routing/road_graph_router.cpp11
8 files changed, 158 insertions, 39 deletions
diff --git a/map/framework.cpp b/map/framework.cpp
index 8e4f857acf..cad0c3c5ac 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -2230,7 +2230,7 @@ void Framework::FollowRoute()
void Framework::SetRouter(RouterType type)
{
#ifdef DEBUG
- RoutingVisualizerFn const routingVisualizer = [this](m2::PointD const & pt)
+ RoutingVisualizerFn const routingVisualizerFn = [this](m2::PointD const & pt)
{
GetPlatform().RunOnGuiThread([this,pt]()
{
@@ -2239,25 +2239,33 @@ void Framework::SetRouter(RouterType type)
});
};
#else
- RoutingVisualizerFn const routingVisualizer = nullptr;
+ RoutingVisualizerFn const routingVisualizerFn = nullptr;
#endif
+ auto const routingStatisticsFn = [](map<string, string> const & statistics)
+ {
+ alohalytics::LogEvent("Routing_CalculatingRoute", statistics);
+ };
+
+ unique_ptr<IRouter> router;
if (type == RouterType::Pedestrian)
{
- m_routingSession.SetRouter(
- unique_ptr<IRouter>(new AStarRouter([this](m2::PointD const & pt)
- {
- return GetSearchEngine()->GetCountryFile(pt) + DATA_FILE_EXTENSION;
- },
- &m_model.GetIndex(), routingVisualizer)));
+ auto const countryFileFn = [this](m2::PointD const & pt)
+ {
+ return GetSearchEngine()->GetCountryFile(pt) + DATA_FILE_EXTENSION;
+ };
+ router.reset(new AStarRouter(countryFileFn, &m_model.GetIndex(), routingVisualizerFn));
}
else
{
- m_routingSession.SetRouter(unique_ptr<IRouter>(new OsrmRouter(&m_model.GetIndex(), [this] (m2::PointD const & pt)
+ auto const countryFileFn = [this](m2::PointD const & pt)
{
return GetSearchEngine()->GetCountryFile(pt);
- }, routingVisualizer)));
+ };
+ router.reset(new OsrmRouter(&m_model.GetIndex(), countryFileFn, routingVisualizerFn));
}
+
+ m_routingSession.SetRouter(move(router), routingStatisticsFn);
}
void Framework::RemoveRoute()
diff --git a/map/routing_session.cpp b/map/routing_session.cpp
index 493673b5c8..75b56ed1de 100644
--- a/map/routing_session.cpp
+++ b/map/routing_session.cpp
@@ -206,9 +206,9 @@ void RoutingSession::AssignRoute(Route & route)
m_route.Swap(route);
}
-void RoutingSession::SetRouter(unique_ptr<IRouter> && router)
+void RoutingSession::SetRouter(unique_ptr<IRouter> && router, TRoutingStatisticsCallback const & routingStatisticsFn)
{
- m_router.reset(new AsyncRouter(move(router)));
+ m_router.reset(new AsyncRouter(move(router), routingStatisticsFn));
}
void RoutingSession::DeleteIndexFile(string const & fileName)
diff --git a/map/routing_session.hpp b/map/routing_session.hpp
index 044f1bc1d1..2f900a0b9f 100644
--- a/map/routing_session.hpp
+++ b/map/routing_session.hpp
@@ -45,11 +45,15 @@ public:
* RouteFinished -> RouteNotReady // start new route
*/
- RoutingSession();
- void SetRouter(unique_ptr<IRouter> && router);
+ typedef function<void(map<string, string> const &)> TRoutingStatisticsCallback;
typedef function<void (Route const &, IRouter::ResultCode)> TReadyCallbackFn;
+ RoutingSession();
+
+ void SetRouter(unique_ptr<IRouter> && router,
+ TRoutingStatisticsCallback const & routingStatisticsFn);
+
/// @param[in] startPoint and endPoint in mercator
void BuildRoute(m2::PointD const & startPoint, m2::PointD const & endPoint, TReadyCallbackFn const & callback);
void RebuildRoute(m2::PointD const & startPoint, TReadyCallbackFn const & callback);
diff --git a/routing/async_router.cpp b/routing/async_router.cpp
index 7f3f037dff..6adddc6379 100644
--- a/routing/async_router.cpp
+++ b/routing/async_router.cpp
@@ -1,13 +1,67 @@
#include "routing/async_router.hpp"
#include "platform/platform.hpp"
-#include "base/macros.hpp"
+
#include "base/logging.hpp"
+#include "base/macros.hpp"
+#include "base/string_utils.hpp"
+#include "base/timer.hpp"
+
+#include "indexer/mercator.hpp"
namespace routing
{
-AsyncRouter::AsyncRouter(unique_ptr<IRouter> && router) : m_router(move(router))
+namespace
+{
+
+string ToString(IRouter::ResultCode code)
+{
+ switch (code)
+ {
+ case IRouter::NoError: return "NoError";
+ case IRouter::Cancelled: return "Cancelled";
+ case IRouter::NoCurrentPosition: return "NoCurrentPosition";
+ case IRouter::InconsistentMWMandRoute: return "InconsistentMWMandRoute";
+ case IRouter::RouteFileNotExist: return "RouteFileNotExist";
+ case IRouter::StartPointNotFound: return "StartPointNotFound";
+ case IRouter::EndPointNotFound: return "EndPointNotFound";
+ case IRouter::PointsInDifferentMWM: return "PointsInDifferentMWM";
+ case IRouter::RouteNotFound: return "RouteNotFound";
+ case IRouter::InternalError: return "InternalError";
+ default:
+ {
+ ASSERT(false, ("Unknown IRouter::ResultCode value ", code));
+ ostringstream o;
+ o << "UnknownResultCode(" << static_cast<unsigned int>(code) << ")";
+ return o.str();
+ }
+ }
+}
+
+map<string, string> PrepareStatisticsData(string const & routerName,
+ m2::PointD const & startPoint, m2::PointD const & startDirection,
+ m2::PointD const & finalPoint)
+{
+ // Coordinates precision in 5 digits after comma corresponds to metres (0,00001degree ~ 1meter),
+ // therefore we round coordinates up to 5 digits after comma.
+ int constexpr precision = 5;
+
+ return {{"name", routerName},
+ {"startLon", strings::to_string_dac(MercatorBounds::XToLon(startPoint.x), precision)},
+ {"startLat", strings::to_string_dac(MercatorBounds::YToLat(startPoint.y), precision)},
+ {"startDirectionX", strings::to_string_dac(startDirection.x, precision)},
+ {"startDirectionY", strings::to_string_dac(startDirection.y, precision)},
+ {"finalLon", strings::to_string_dac(MercatorBounds::XToLon(finalPoint.x), precision)},
+ {"finalLat", strings::to_string_dac(MercatorBounds::YToLat(finalPoint.y), precision)}};
+}
+
+} // namespace
+
+AsyncRouter::AsyncRouter(unique_ptr<IRouter> && router,
+ TRoutingStatisticsCallback const & routingStatisticsFn)
+ : m_router(move(router))
+ , m_routingStatisticsFn(routingStatisticsFn)
{
m_isReadyThread.clear();
}
@@ -15,7 +69,7 @@ AsyncRouter::AsyncRouter(unique_ptr<IRouter> && router) : m_router(move(router))
AsyncRouter::~AsyncRouter() { ClearState(); }
void AsyncRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const & direction,
- m2::PointD const & finalPoint, ReadyCallback const & callback)
+ m2::PointD const & finalPoint, TReadyCallback const & callback)
{
ASSERT(m_router, ());
{
@@ -41,7 +95,7 @@ void AsyncRouter::ClearState()
m_router->ClearState();
}
-void AsyncRouter::CalculateRouteImpl(ReadyCallback const & callback)
+void AsyncRouter::CalculateRouteImpl(TReadyCallback const & callback)
{
if (m_isReadyThread.test_and_set())
return;
@@ -66,7 +120,15 @@ void AsyncRouter::CalculateRouteImpl(ReadyCallback const & callback)
try
{
+ LOG(LDEBUG, ("Calculating the route from", startPoint, "to", finalPoint, "startDirection", startDirection));
+
+ my::Timer timer;
+ timer.Reset();
+
code = m_router->CalculateRoute(startPoint, startDirection, finalPoint, route);
+
+ double const elapsedSec = timer.ElapsedSeconds();
+
switch (code)
{
case IRouter::StartPointNotFound:
@@ -82,21 +144,59 @@ void AsyncRouter::CalculateRouteImpl(ReadyCallback const & callback)
LOG(LWARNING, ("Route not found"));
break;
case IRouter::RouteFileNotExist:
- LOG(LWARNING, ("There are no routing file"));
+ LOG(LWARNING, ("There is no routing file"));
+ break;
+ case IRouter::Cancelled:
+ LOG(LINFO, ("Route calculation cancelled, elapsed seconds:", elapsedSec));
+ break;
+ case IRouter::NoError:
+ LOG(LINFO, ("Route found, elapsed seconds:", elapsedSec));
break;
default:
break;
}
+
+ SendStatistics(startPoint, startDirection, finalPoint, code, elapsedSec);
}
catch (Reader::Exception const & e)
{
LOG(LERROR,
("Routing index is absent or incorrect. Error while loading routing index:", e.Msg()));
code = IRouter::InternalError;
+
+ SendStatistics(startPoint, startDirection, finalPoint, e.Msg());
}
GetPlatform().RunOnGuiThread(bind(callback, route, code));
}
+void AsyncRouter::SendStatistics(m2::PointD const & startPoint, m2::PointD const & startDirection,
+ m2::PointD const & finalPoint,
+ IRouter::ResultCode resultCode,
+ double elapsedSec)
+{
+ if (nullptr == m_routingStatisticsFn)
+ return;
+
+ map<string, string> statistics = PrepareStatisticsData(m_router->GetName(), startPoint, startDirection, finalPoint);
+ statistics.emplace("result", ToString(resultCode));
+ statistics.emplace("elapsed", strings::to_string(elapsedSec));
+
+ m_routingStatisticsFn(statistics);
+}
+
+void AsyncRouter::SendStatistics(m2::PointD const & startPoint, m2::PointD const & startDirection,
+ m2::PointD const & finalPoint,
+ string const & exceptionMessage)
+{
+ if (nullptr == m_routingStatisticsFn)
+ return;
+
+ map<string, string> statistics = PrepareStatisticsData(m_router->GetName(), startPoint, startDirection, finalPoint);
+ statistics.emplace("exception", exceptionMessage);
+
+ m_routingStatisticsFn(statistics);
+}
+
} // namespace routing
diff --git a/routing/async_router.hpp b/routing/async_router.hpp
index 6607621f9b..dc934ffb33 100644
--- a/routing/async_router.hpp
+++ b/routing/async_router.hpp
@@ -4,22 +4,28 @@
#include "routing/router.hpp"
#include "std/atomic.hpp"
+#include "std/map.hpp"
#include "std/mutex.hpp"
+#include "std/string.hpp"
#include "std/unique_ptr.hpp"
namespace routing
{
-/// Callback takes ownership of passed route.
-typedef function<void(Route &, IRouter::ResultCode)> ReadyCallback;
-
class AsyncRouter
{
public:
+ /// Callback takes ownership of passed route.
+ typedef function<void(Route &, IRouter::ResultCode)> TReadyCallback;
+
+ /// Callback on routing statistics
+ typedef function<void(map<string, string> const &)> TRoutingStatisticsCallback;
+
/// AsyncRouter is a wrapper class to run routing routines in the different thread
/// @param router pointer to the router implementation. AsyncRouter will take ownership over
/// router.
- AsyncRouter(unique_ptr<IRouter> && router);
+ AsyncRouter(unique_ptr<IRouter> && router,
+ TRoutingStatisticsCallback const & routingStatisticsFn);
virtual ~AsyncRouter();
@@ -31,14 +37,23 @@ public:
/// @param finalPoint target point for route
/// @param callback function to return routing result
virtual void CalculateRoute(m2::PointD const & startPoint, m2::PointD const & direction,
- m2::PointD const & finalPoint, ReadyCallback const & callback);
+ m2::PointD const & finalPoint, TReadyCallback const & callback);
/// Interrupt routing and clear buffers
virtual void ClearState();
private:
/// This function is called in async mode
- void CalculateRouteImpl(ReadyCallback const & callback);
+ void CalculateRouteImpl(TReadyCallback const & callback);
+
+ /// These functions are called to send statistics about the routing
+ void SendStatistics(m2::PointD const & startPoint, m2::PointD const & startDirection,
+ m2::PointD const & finalPoint,
+ IRouter::ResultCode resultCode,
+ double elapsedSec);
+ void SendStatistics(m2::PointD const & startPoint, m2::PointD const & startDirection,
+ m2::PointD const & finalPoint,
+ string const & exceptionMessage);
mutex m_paramsMutex;
mutex m_routeMutex;
@@ -49,6 +64,7 @@ private:
m2::PointD m_startDirection;
unique_ptr<IRouter> const m_router;
+ TRoutingStatisticsCallback const m_routingStatisticsFn;
};
} // namespace routing
diff --git a/routing/osrm_online_router.cpp b/routing/osrm_online_router.cpp
index 0a79b90c1c..3222de3535 100644
--- a/routing/osrm_online_router.cpp
+++ b/routing/osrm_online_router.cpp
@@ -25,7 +25,7 @@ string OsrmOnlineRouter::GetName() const
}
void OsrmOnlineRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const & /* direction */,
- m2::PointD const & /* finalPoint */, ReadyCallback const & callback)
+ m2::PointD const & /* finalPoint */, TReadyCallback const & callback)
{
// Construct OSRM url request to get the route
string url = OSRM_CAR_ROUTING_URL;
@@ -37,7 +37,7 @@ void OsrmOnlineRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD
downloader::HttpRequest::Get(url, bind(&OsrmOnlineRouter::OnRouteReceived, this, _1, callback));
}
-void OsrmOnlineRouter::OnRouteReceived(downloader::HttpRequest & request, ReadyCallback callback)
+void OsrmOnlineRouter::OnRouteReceived(downloader::HttpRequest & request, TReadyCallback callback)
{
if (request.Status() == downloader::HttpRequest::ECompleted)
{
diff --git a/routing/osrm_online_router.hpp b/routing/osrm_online_router.hpp
index 9e5143e8d7..3bd928e78d 100644
--- a/routing/osrm_online_router.hpp
+++ b/routing/osrm_online_router.hpp
@@ -14,13 +14,13 @@ class OsrmOnlineRouter : public AsyncRouter
m2::PointD m_finalPt;
/// Http callback from the server
- void OnRouteReceived(downloader::HttpRequest & request, ReadyCallback callback);
+ void OnRouteReceived(downloader::HttpRequest & request, TReadyCallback callback);
public:
virtual string GetName() const;
// AsyncRouter overrides:
void CalculateRoute(m2::PointD const & startPoint, m2::PointD const & /* direction */,
- m2::PointD const & /* finalPoint */, ReadyCallback const & callback) override;
+ m2::PointD const & /* finalPoint */, TReadyCallback const & callback) override;
};
} // namespace routing
diff --git a/routing/road_graph_router.cpp b/routing/road_graph_router.cpp
index 1971a1e19b..de9345ddbb 100644
--- a/routing/road_graph_router.cpp
+++ b/routing/road_graph_router.cpp
@@ -11,8 +11,6 @@
#include "geometry/distance.hpp"
#include "base/assert.hpp"
-#include "base/timer.hpp"
-#include "base/logging.hpp"
namespace routing
{
@@ -70,8 +68,6 @@ IRouter::ResultCode RoadGraphRouter::CalculateRoute(m2::PointD const & startPoin
// we still need to check that startPoint and finalPoint are in the same MWM
// and probably reset the graph. So the checks stay here.
- LOG(LDEBUG, ("Calculate route from", startPoint, "to", finalPoint));
-
string const mwmName = m_countryFileFn(finalPoint);
if (m_countryFileFn(startPoint) != mwmName)
return PointsInDifferentMWM;
@@ -96,9 +92,6 @@ IRouter::ResultCode RoadGraphRouter::CalculateRoute(m2::PointD const & startPoin
if (startVicinity.empty())
return StartPointNotFound;
- my::Timer timer;
- timer.Reset();
-
Junction const startPos(startPoint);
Junction const finalPos(finalPoint);
@@ -107,12 +100,10 @@ IRouter::ResultCode RoadGraphRouter::CalculateRoute(m2::PointD const & startPoin
m_roadGraph->AddFakeEdges(finalPos, finalVicinity);
vector<Junction> routePos;
- IRouter::ResultCode const resultCode = CalculateRoute(startPos, finalPos, routePos);
+ ResultCode const resultCode = CalculateRoute(startPos, finalPos, routePos);
m_roadGraph->ResetFakes();
- LOG(LINFO, ("Route calculation time:", timer.ElapsedSeconds(), "result code:", resultCode));
-
if (IRouter::NoError == resultCode)
{
ASSERT(routePos.back() == finalPos, ());