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

route.hpp « routing - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 6da41e880e9e03dcdd27cee101c5de8898577370 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma once

#include "routing/turns.hpp"

#include "geometry/polyline2d.hpp"

#include "std/vector.hpp"
#include "std/string.hpp"


namespace location
{
  class GpsInfo;
  class RouteMatchingInfo;
}

namespace routing
{

struct TurnItem
{
  TurnItem()
      : m_index(numeric_limits<uint32_t>::max()),
        m_turn(turns::TurnDirection::NoTurn),
        m_exitNum(0),
        m_keepAnyway(false)
  {
  }

  TurnItem(uint32_t idx, turns::TurnDirection t, uint32_t exitNum = 0)
    : m_index(idx), m_turn(t), m_exitNum(exitNum), m_keepAnyway(false)
  {
  }

  bool operator==(TurnItem const & rhs) const
  {
    return m_index == rhs.m_index && m_turn == rhs.m_turn
        && m_lanes == rhs.m_lanes && m_exitNum == rhs.m_exitNum
        && m_sourceName == rhs.m_sourceName && m_targetName == rhs.m_targetName
        && m_keepAnyway == rhs.m_keepAnyway;
  }

  uint32_t m_index; // Index of point on polyline (number of segment + 1).
  turns::TurnDirection m_turn;
  vector<turns::SingleLaneInfo> m_lanes;  // Lane information on the edge before the turn.
  uint32_t m_exitNum;  // Number of exit on roundabout.
  string m_sourceName;
  string m_targetName;
  // m_keepAnyway is true if the turn shall not be deleted
  // and shall be demonstrated to an end user.
  bool m_keepAnyway;
};

string DebugPrint(TurnItem const & turnItem);

class Route
{
public:
  typedef vector<TurnItem> TTurns;
  typedef pair<uint32_t, double> TTimeItem;
  typedef vector<TTimeItem> TTimes;

  explicit Route(string const & router) : m_router(router) {}

  template <class IterT>
  Route(string const & router, IterT beg, IterT end)
    : m_router(router), m_poly(beg, end)
  {
    Update();
  }

  Route(string const & router, vector<m2::PointD> const & points, string const & name = string());

  void Swap(Route & rhs);

  template <class IterT> void SetGeometry(IterT beg, IterT end)
  {
    m2::PolylineD(beg, end).Swap(m_poly);
    Update();
  }

  inline void SetTurnInstructions(TTurns & v)
  {
    swap(m_turns, v);
  }

  inline void SetSectionTimes(TTimes & v)
  {
    swap(m_times, v);
  }

  inline void SetTurnInstructionsGeometry(turns::TTurnsGeom & v)
  {
    swap(m_turnsGeom, v);
  }

  // Time measure are seconds
  uint32_t GetAllTime() const;
  uint32_t GetTime() const;

  string const & GetRouterId() const { return m_router; }
  m2::PolylineD const & GetPoly() const { return m_poly; }
  turns::TTurnsGeom const & GetTurnsGeometry() const { return m_turnsGeom; }
  TTurns const & GetTurns() const { return m_turns; }
  string const & GetName() const { return m_name; }
  bool IsValid() const { return (m_poly.GetSize() > 1); }

  struct IterT
  {
    m2::PointD m_pt;
    size_t m_ind;

    IterT(m2::PointD pt, size_t ind) : m_pt(pt), m_ind(ind) {}
    IterT() : m_ind(-1) {}

    bool IsValid() const { return m_ind != -1; }
  };

  /// @return Distance on route in meters.
  //@{
  double GetDistance() const;
  double GetCurrentDistanceFromBegin() const;
  double GetCurrentDistanceToEnd() const;
  //@}

  void GetTurn(double & distance, TurnItem & turn) const;

  /// @return true  If position was updated successfully (projection within gps error radius).
  bool MoveIterator(location::GpsInfo const & info) const;

  /// Square distance to current projection in mercator.
  double GetCurrentSqDistance(m2::PointD const & pt) const;
  void MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const;

  bool IsCurrentOnEnd() const;

  /// Add country name if we have no country filename to make route
  void AddAbsentCountry(string const & name) {m_absentCountries.push_back(name);}

  /// Get absent file list of a routing files for shortest path finding
  vector<string> const & GetAbsentCountries() const {return m_absentCountries;}

private:
  /// @param[in]  predictDistance   Predict distance from previous FindProjection call (meters).
  IterT FindProjection(m2::RectD const & posRect, double predictDistance = -1.0) const;

  template <class DistanceF>
  IterT GetClosestProjection(m2::RectD const & posRect, DistanceF const & distFn) const;

  double GetDistanceOnPolyline(IterT const & it1, IterT const & it2) const;

  /// Call this fucnction when geometry have changed.
  void Update();
  double GetPolySegAngle(size_t ind) const;

private:
  friend string DebugPrint(Route const & r);

  string m_router;
  m2::PolylineD m_poly;
  string m_name;

  vector<string> m_absentCountries;

  /// Accumulated cache of segments length in meters.
  vector<double> m_segDistance;
  /// Precalculated info for fast projection finding.
  vector<m2::ProjectionToSection<m2::PointD>> m_segProj;

  TTurns m_turns;
  TTimes m_times;

  turns::TTurnsGeom m_turnsGeom;

  /// Cached result iterator for last MoveIterator query.
  mutable IterT m_current;
  mutable double m_currentTime;
};

} // namespace routing