forked from organicmaps/organicmaps
Collecting transit route summary info.
This commit is contained in:
parent
d2f4d95a52
commit
9dec257452
2 changed files with 116 additions and 6 deletions
|
@ -41,7 +41,10 @@
|
|||
#include "3party/Alohalytics/src/alohalytics.h"
|
||||
#include "3party/jansson/myjansson.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
|
@ -190,9 +193,19 @@ void AddTransitShapes(std::vector<transit::ShapeId> const & shapeIds, TransitSha
|
|||
subroute.m_style.emplace_back(move(style));
|
||||
}
|
||||
|
||||
string ColorToHexStr(dp::Color const & color)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << nouppercase << hex << setfill('0');
|
||||
ss << setw(2) << static_cast<int>(color.GetRed())
|
||||
<< setw(2) << static_cast<int>(color.GetGreen())
|
||||
<< setw(2) << static_cast<int>(color.GetBlue());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void FillTransitStyleForRendering(vector<RouteSegment> const & segments, TransitReadManager & transitReadManager,
|
||||
GetMwmIdFn const & getMwmIdFn, df::Subroute & subroute,
|
||||
vector<TransitMarkInfo> & transitMarks)
|
||||
vector<TransitMarkInfo> & transitMarks, TransitRouteInfo & routeInfo)
|
||||
{
|
||||
TransitDisplayInfos transitDisplayInfos;
|
||||
CollectTransitDisplayInfo(segments, getMwmIdFn, transitDisplayInfos);
|
||||
|
@ -210,13 +223,20 @@ void FillTransitStyleForRendering(vector<RouteSegment> const & segments, Transit
|
|||
df::SubrouteMarker marker;
|
||||
TransitMarkInfo transitMarkInfo;
|
||||
|
||||
double distance = 0;
|
||||
double prevDistance = routeInfo.m_totalDistance;
|
||||
double prevTime = routeInfo.m_totalDistance;
|
||||
|
||||
bool pendingEntrance = false;
|
||||
|
||||
for (auto const & s : segments)
|
||||
{
|
||||
auto const time = s.GetTimeFromBeginningSec() - prevTime;
|
||||
auto const distance = s.GetDistFromBeginningMeters() - prevDistance;
|
||||
|
||||
if (!s.HasTransitInfo())
|
||||
{
|
||||
routeInfo.AddStep(TransitStepInfo(true /* isPedestrian */, distance, time));
|
||||
|
||||
AddTransitPedestrianSegment(s.GetJunction().GetPoint(), subroute);
|
||||
lastColor = "";
|
||||
continue;
|
||||
|
@ -234,12 +254,16 @@ void FillTransitStyleForRendering(vector<RouteSegment> const & segments, Transit
|
|||
auto const & line = displayInfo.m_lines.at(edge.m_lineId);
|
||||
auto const currentColor = df::GetTransitColorName(line.GetColor());
|
||||
|
||||
string const hexColor = ColorToHexStr(df::GetColorConstant(currentColor));
|
||||
routeInfo.AddStep(TransitStepInfo(false /* isPedestrian */, distance, time,
|
||||
line.GetType(), line.GetNumber(), hexColor));
|
||||
|
||||
auto const & stop1 = displayInfo.m_stops.at(edge.m_stop1Id);
|
||||
auto const & stop2 = displayInfo.m_stops.at(edge.m_stop2Id);
|
||||
bool const isTransfer1 = stop1.GetTransferId() != transit::kInvalidTransferId;
|
||||
bool const isTransfer2 = stop2.GetTransferId() != transit::kInvalidTransferId;
|
||||
|
||||
marker.m_distance = distance;
|
||||
marker.m_distance = prevDistance;
|
||||
marker.m_scale = kStopMarkerScale;
|
||||
marker.m_innerColor = currentColor;
|
||||
if (isTransfer1)
|
||||
|
@ -296,9 +320,8 @@ void FillTransitStyleForRendering(vector<RouteSegment> const & segments, Transit
|
|||
transitMarkInfo = TransitMarkInfo();
|
||||
|
||||
lastDir = currentDir;
|
||||
distance += stop1.GetPoint().Length(stop2.GetPoint());
|
||||
|
||||
marker.m_distance = distance;
|
||||
marker.m_distance = s.GetDistFromBeginningMeters();
|
||||
marker.m_scale = kStopMarkerScale;
|
||||
marker.m_innerColor = currentColor;
|
||||
marker.m_colors.push_back(currentColor);
|
||||
|
@ -323,6 +346,8 @@ void FillTransitStyleForRendering(vector<RouteSegment> const & segments, Transit
|
|||
auto const & gate = transitInfo.GetGate();
|
||||
if (!lastColor.empty())
|
||||
{
|
||||
routeInfo.AddStep(TransitStepInfo(true /* isPedestrian */, distance, time));
|
||||
|
||||
AddTransitGateSegment(s.GetJunction().GetPoint(), subroute);
|
||||
|
||||
subroute.m_markers.push_back(marker);
|
||||
|
@ -336,8 +361,14 @@ void FillTransitStyleForRendering(vector<RouteSegment> const & segments, Transit
|
|||
pendingEntrance = true;
|
||||
}
|
||||
}
|
||||
|
||||
prevDistance = s.GetDistFromBeginningMeters();
|
||||
prevTime = s.GetTimeFromBeginningSec();
|
||||
}
|
||||
|
||||
routeInfo.m_totalDistance = prevDistance;
|
||||
routeInfo.m_totalTime = prevTime;
|
||||
|
||||
if (subroute.m_markers.size() > 1)
|
||||
{
|
||||
subroute.m_markers.front().m_innerColor = df::kTransitOutlineColor;
|
||||
|
@ -533,6 +564,44 @@ namespace marketing
|
|||
char const * const kRoutingCalculatingRoute = "Routing_CalculatingRoute";
|
||||
} // namespace marketing
|
||||
|
||||
TransitStepInfo::TransitStepInfo(bool isPedestrian, double distance, double time,
|
||||
std::string const & type, std::string const & number, std::string const & color)
|
||||
: m_isPedestrian(isPedestrian)
|
||||
, m_distance(distance)
|
||||
, m_time(time)
|
||||
, m_type(type)
|
||||
, m_number(number)
|
||||
, m_color(color)
|
||||
{}
|
||||
|
||||
bool TransitStepInfo::IsEqualType(TransitStepInfo const & ts) const
|
||||
{
|
||||
if (m_isPedestrian)
|
||||
return ts.m_isPedestrian;
|
||||
|
||||
return m_isPedestrian == ts.m_isPedestrian &&
|
||||
(m_isPedestrian || (m_type == ts.m_type && m_number == ts.m_number && m_color == ts.m_color));
|
||||
}
|
||||
|
||||
void TransitRouteInfo::AddStep(TransitStepInfo const & step)
|
||||
{
|
||||
if (!m_steps.empty() && m_steps.back().IsEqualType(step))
|
||||
{
|
||||
m_steps.back().m_distance += step.m_distance;
|
||||
m_steps.back().m_time += step.m_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_steps.push_back(step);
|
||||
}
|
||||
|
||||
if (step.m_isPedestrian)
|
||||
{
|
||||
m_totalPedestrianDistance += step.m_distance;
|
||||
m_totalPedestrianTime += step.m_time;
|
||||
}
|
||||
}
|
||||
|
||||
RoutingManager::RoutingManager(Callbacks && callbacks, Delegate & delegate)
|
||||
: m_callbacks(move(callbacks))
|
||||
, m_delegate(delegate)
|
||||
|
@ -742,6 +811,7 @@ void RoutingManager::RemoveRoute(bool deactivateFollowing)
|
|||
{
|
||||
lock_guard<mutex> lock(m_drapeSubroutesMutex);
|
||||
m_drapeSubroutes.clear();
|
||||
m_transitRouteInfo = TransitRouteInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -756,6 +826,7 @@ void RoutingManager::InsertRoute(Route const & route)
|
|||
vector<RouteSegment> segments;
|
||||
vector<m2::PointD> points;
|
||||
double distance = 0.0;
|
||||
TransitRouteInfo transitRouteInfo;
|
||||
auto const subroutesCount = route.GetSubrouteCount();
|
||||
for (size_t subrouteIndex = route.GetCurrentSubrouteIdx(); subrouteIndex < subroutesCount; ++subrouteIndex)
|
||||
{
|
||||
|
@ -810,7 +881,8 @@ void RoutingManager::InsertRoute(Route const & route)
|
|||
};
|
||||
|
||||
vector<TransitMarkInfo> transitMarks;
|
||||
FillTransitStyleForRendering(segments, m_transitReadManager, getMwmIdFn, *subroute.get(), transitMarks);
|
||||
FillTransitStyleForRendering(segments, m_transitReadManager, getMwmIdFn, *subroute.get(),
|
||||
transitMarks, transitRouteInfo);
|
||||
|
||||
auto & marksController = m_bmManager->GetUserMarksController(UserMark::Type::TRANSIT);
|
||||
CreateTransitMarks(transitMarks, marksController);
|
||||
|
@ -838,6 +910,7 @@ void RoutingManager::InsertRoute(Route const & route)
|
|||
|
||||
lock_guard<mutex> lock(m_drapeSubroutesMutex);
|
||||
m_drapeSubroutes.push_back(subrouteId);
|
||||
m_transitRouteInfo = transitRouteInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1532,6 +1605,12 @@ void RoutingManager::CancelRecommendation(Recommendation recommendation)
|
|||
m_loadRoutePointsTimestamp = chrono::steady_clock::time_point();
|
||||
}
|
||||
|
||||
TransitRouteInfo RoutingManager::GetTransitRouteInfo() const
|
||||
{
|
||||
lock_guard<mutex> lock(m_drapeSubroutesMutex);
|
||||
return m_transitRouteInfo;
|
||||
}
|
||||
|
||||
std::vector<dp::DrapeID> RoutingManager::GetSubrouteIds() const
|
||||
{
|
||||
lock_guard<mutex> lock(m_drapeSubroutesMutex);
|
||||
|
|
|
@ -50,6 +50,32 @@ struct RoutePointInfo
|
|||
m2::PointD m_position;
|
||||
};
|
||||
|
||||
struct TransitStepInfo
|
||||
{
|
||||
TransitStepInfo(bool isPedestrian, double distance, double time,
|
||||
std::string const & type = "", std::string const & number = "", std::string const & color = "");
|
||||
|
||||
bool IsEqualType(TransitStepInfo const & ts) const;
|
||||
|
||||
bool m_isPedestrian = false;
|
||||
double m_distance = 0.0;
|
||||
double m_time = 0.0;
|
||||
std::string m_type;
|
||||
std::string m_number;
|
||||
std::string m_color;
|
||||
};
|
||||
|
||||
struct TransitRouteInfo
|
||||
{
|
||||
double m_totalDistance = 0.0;
|
||||
double m_totalTime = 0.0;
|
||||
double m_totalPedestrianDistance = 0.0;
|
||||
double m_totalPedestrianTime = 0.0;
|
||||
std::vector<TransitStepInfo> m_steps;
|
||||
|
||||
void AddStep(TransitStepInfo const & step);
|
||||
};
|
||||
|
||||
class RoutingManager final
|
||||
{
|
||||
public:
|
||||
|
@ -142,6 +168,9 @@ public:
|
|||
{
|
||||
m_routingSession.GetRouteFollowingInfo(info);
|
||||
}
|
||||
|
||||
TransitRouteInfo GetTransitRouteInfo() const;
|
||||
|
||||
m2::PointD GetRouteEndPoint() const { return m_routingSession.GetEndPoint(); }
|
||||
/// Returns the most situable router engine type.
|
||||
routing::RouterType GetBestRouter(m2::PointD const & startPoint,
|
||||
|
@ -286,6 +315,8 @@ private:
|
|||
|
||||
std::unique_ptr<location::GpsInfo> m_gpsInfoCache;
|
||||
|
||||
TransitRouteInfo m_transitRouteInfo;
|
||||
|
||||
struct RoutePointsTransaction
|
||||
{
|
||||
std::vector<RouteMarkData> m_routeMarks;
|
||||
|
|
Loading…
Add table
Reference in a new issue