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

transit_entities.hpp « transit - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 58c9d4949966bd4aba94ac667333da342b63f7bf (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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#pragma once

#include "transit/transit_schedule.hpp"

#include "geometry/point2d.hpp"

#include "base/macros.hpp"
#include "base/newtype.hpp"
#include "base/visitor.hpp"

#include "defines.hpp"

#include <cstdint>
#include <limits>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "3party/boost/boost/container_hash/hash.hpp"

#include "3party/opening_hours/opening_hours.hpp"

namespace routing
{
inline double constexpr kTransitMaxSpeedKMpH = 400.0;
}  // namespace routing

namespace transit
{
// File names for saving resulting data exported from GTFS.
inline std::string const kTransitFileExtension = std::string(TRANSIT_FILE_EXTENSION);
inline std::string const kNetworksFile = "networks" + kTransitFileExtension;
inline std::string const kRoutesFile = "routes" + kTransitFileExtension;
inline std::string const kLinesFile = "lines" + kTransitFileExtension;
inline std::string const kLinesMetadataFile = "lines_metadata" + kTransitFileExtension;
inline std::string const kShapesFile = "shapes" + kTransitFileExtension;
inline std::string const kStopsFile = "stops" + kTransitFileExtension;
inline std::string const kEdgesFile = "edges" + kTransitFileExtension;
inline std::string const kEdgesTransferFile = "edges_transfer" + kTransitFileExtension;
inline std::string const kTransfersFile = "transfers" + kTransitFileExtension;
inline std::string const kGatesFile = "gates" + kTransitFileExtension;

// Route types shown on the subway layer.
inline std::unordered_set<std::string> const kSubwayLayerTypes{"subway", "train", "light_rail",
                                                               "monorail"};

// Unique id for transit entities. It is generated by gtfs_converter and is persistent between
// re-runs. Generated based on the unique string hash of the GTFS entity. Lies in the interval
// |routing::FakeFeatureIds::IsTransitFeature()|. If the GTFS entity is renamed or the new GTFS
// feed is added the new id is generated by |IdGenerator::MakeId()|.
using TransitId = uint32_t;
inline TransitId constexpr kInvalidTransitId = std::numeric_limits<TransitId>::max();

// Mapping of language id to text. Language id exists in |StringUtf8Multilang::kLanguages|.
using Translations = std::unordered_map<std::string, std::string>;

struct TimeFromGateToStop
{
  TimeFromGateToStop() = default;
  TimeFromGateToStop(TransitId stopId, uint32_t timeSeconds)
    : m_stopId(stopId), m_timeSeconds(timeSeconds)
  {
  }
  bool operator==(TimeFromGateToStop const & rhs) const
  {
    return std::tie(m_stopId, m_timeSeconds) == std::tie(rhs.m_stopId, rhs.m_timeSeconds);
  }

  DECLARE_VISITOR_AND_DEBUG_PRINT(TimeFromGateToStop, visitor(m_stopId, "stopId"),
                                  visitor(m_timeSeconds, "timeSeconds"))

  TransitId m_stopId = kInvalidTransitId;
  uint32_t m_timeSeconds = 0;
};

using IdList = std::vector<TransitId>;
using IdSet = std::unordered_set<TransitId>;
using TimeTable = std::unordered_map<TransitId, std::vector<TimeInterval>>;
using EdgeWeight = uint32_t;

// Link to the shape: shape id and indexes in the corresponding polyline.
struct ShapeLink
{
  ShapeLink() = default;
  ShapeLink(TransitId id, uint32_t startIndex, uint32_t endIndex)
    : m_shapeId(id), m_startIndex(startIndex), m_endIndex(endIndex)
  {
  }

  bool operator==(ShapeLink const & rhs) const
  {
    return std::tie(m_shapeId, m_startIndex, m_endIndex) ==
           std::tie(rhs.m_shapeId, rhs.m_startIndex, rhs.m_endIndex);
  }

  bool operator<(ShapeLink const & rhs) const
  {
    return std::tie(m_shapeId, m_startIndex, m_endIndex) <
           std::tie(rhs.m_shapeId, rhs.m_startIndex, rhs.m_endIndex);
  }

  DECLARE_VISITOR_AND_DEBUG_PRINT(ShapeLink, visitor(m_shapeId, "id"),
                                  visitor(m_startIndex, "startIndex"),
                                  visitor(m_endIndex, "endIndex"))

  TransitId m_shapeId = kInvalidTransitId;
  uint32_t m_startIndex = 0;
  uint32_t m_endIndex = 0;
};

struct EdgeId
{
  EdgeId() = default;
  EdgeId(TransitId fromStopId, TransitId toStopId, TransitId lineId)
    : m_fromStopId(fromStopId), m_toStopId(toStopId), m_lineId(lineId)
  {
  }

  bool operator==(EdgeId const & other) const
  {
    return std::tie(m_fromStopId, m_toStopId, m_lineId) ==
           std::tie(other.m_fromStopId, other.m_toStopId, other.m_lineId);
  }

  TransitId m_fromStopId = 0;
  TransitId m_toStopId = 0;
  TransitId m_lineId = 0;
};

struct EdgeIdHasher
{
  size_t operator()(EdgeId const & key) const
  {
    size_t seed = 0;
    boost::hash_combine(seed, key.m_fromStopId);
    boost::hash_combine(seed, key.m_toStopId);
    boost::hash_combine(seed, key.m_lineId);
    return seed;
  }
};

using IdEdgeSet = std::unordered_set<EdgeId, EdgeIdHasher>;

struct EdgeData
{
  EdgeData() = default;
  EdgeData(ShapeLink const & shapeLink, EdgeWeight const & weight)
    : m_shapeLink(shapeLink), m_weight(weight)
  {
  }

  explicit EdgeData(EdgeWeight const & weight) : m_weight(weight) {}

  ShapeLink m_shapeLink;
  EdgeWeight m_weight = 0;

  // Feature id for cross-mwm transit section. It is used in Segment class as a feature id for
  // transit routing case.
  uint32_t m_featureId = std::numeric_limits<uint32_t>::max();
};

struct LineSegment
{
  LineSegment() = default;
  explicit LineSegment(uint32_t startIdx) : m_startIdx(startIdx) {}
  LineSegment(uint32_t startIdx, uint32_t endIdx) : m_startIdx(startIdx), m_endIdx(endIdx) {}

  bool operator==(LineSegment const & rhs) const
  {
    return m_startIdx == rhs.m_startIdx && m_endIdx == rhs.m_endIdx;
  }

  DECLARE_VISITOR_AND_DEBUG_PRINT(LineSegment, visitor(m_startIdx, "startIdx"),
                                  visitor(m_endIdx, "endIdx"))

  uint32_t m_startIdx = 0;
  uint32_t m_endIdx = 0;
};

using LineSegments = std::vector<LineSegment>;

struct LineSegmentOrder
{
  LineSegmentOrder() = default;
  LineSegmentOrder(LineSegment const & lineSegment, int order)
    : m_segment(lineSegment), m_order(order)
  {
  }

  bool operator==(LineSegmentOrder const & rhs) const
  {
    return m_order == rhs.m_order && m_segment == rhs.m_segment;
  }

  DECLARE_VISITOR_AND_DEBUG_PRINT(LineSegmentOrder, visitor(m_segment, "segment"),
                                  visitor(m_order, "order"))

  LineSegment m_segment;
  int m_order = 0;
};

using LineSegmentsOrder = std::vector<LineSegmentOrder>;

template <class T, class I>
typename std::vector<T>::const_iterator FindById(std::vector<T> const & container, I const & id,
                                                 bool exists = true)
{
  auto const it = std::find_if(container.begin(), container.end(),
                               [id](T const & obj) { return obj.GetId() == id; });

  if (exists)
    CHECK(it != container.end(), (id));
  return it;
}

inline std::vector<m2::PointD> GetPolylinePart(std::vector<m2::PointD> const & polyline,
                                               size_t startIdx, size_t endIdx)
{
  CHECK_GREATER(endIdx, startIdx, ());
  CHECK_GREATER(polyline.size(), endIdx, ());

  return std::vector<m2::PointD>(polyline.begin() + startIdx, polyline.begin() + endIdx + 1);
}
}  // namespace transit