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

transit_types.hpp « transit - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3eb296b1c78dcdb6486768e6588ed5bfae528306 (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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
#pragma once

#include "indexer/scales.hpp"

#include "geometry/point2d.hpp"

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

#include <algorithm>
#include <cstdint>
#include <limits>
#include <string>
#include <vector>

namespace routing
{
namespace transit
{
using Anchor = uint8_t;
using FeatureId = uint32_t;
using LineId = uint32_t;
using NetworkId = uint32_t;
using OsmId = uint64_t;
using StopId = uint64_t;
using TransferId = uint64_t;
using Weight = int32_t;
using Ranges = std::vector<std::vector<StopId>>;

Anchor constexpr kInvalidAnchor = std::numeric_limits<Anchor>::max();
std::string const kInvalidColor = std::string("");
FeatureId constexpr kInvalidFeatureId = std::numeric_limits<FeatureId>::max();
LineId constexpr kInvalidLineId = std::numeric_limits<LineId>::max();
NetworkId constexpr kInvalidNetworkId = std::numeric_limits<NetworkId>::max();
OsmId constexpr kInvalidOsmId = std::numeric_limits<OsmId>::max();
StopId constexpr kInvalidStopId = std::numeric_limits<StopId>::max();
TransferId constexpr kInvalidTransferId = std::numeric_limits<TransferId>::max();
Weight constexpr kInvalidWeight = std::numeric_limits<Weight>::max();

#define DECLARE_TRANSIT_TYPE_FRIENDS                                                  \
  template <class Sink> friend class Serializer;                                      \
  template <class Source> friend class Deserializer;                                  \
  friend class DeserializerFromJson;                                                  \
  template <typename Sink> friend class FixedSizeSerializer;                          \
  template <typename Sink> friend class FixedSizeDeserializer;                        \

struct TransitHeader
{
  TransitHeader() { Reset(); }
  TransitHeader(uint16_t version, uint32_t stopsOffset, uint32_t gatesOffset, uint32_t edgesOffset,
                uint32_t transfersOffset, uint32_t linesOffset, uint32_t shapesOffset,
                uint32_t networksOffset, uint32_t endOffset);

  void Reset();
  bool IsEqualForTesting(TransitHeader const & header) const;
  bool IsValid() const;

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(
      TransitHeader, visitor(m_version, "version"), visitor(m_reserve, "reserve"),
      visitor(m_stopsOffset, "stops"), visitor(m_gatesOffset, "gatesOffset"),
      visitor(m_edgesOffset, "edgesOffset"), visitor(m_transfersOffset, "transfersOffset"),
      visitor(m_linesOffset, "linesOffset"), visitor(m_shapesOffset, "shapesOffset"),
      visitor(m_networksOffset, "networksOffset"), visitor(m_endOffset, "endOffset"))

public:
  uint16_t m_version;
  uint16_t m_reserve;
  uint32_t m_stopsOffset;
  uint32_t m_gatesOffset;
  uint32_t m_edgesOffset;
  uint32_t m_transfersOffset;
  uint32_t m_linesOffset;
  uint32_t m_shapesOffset;
  uint32_t m_networksOffset;
  uint32_t m_endOffset;
};

static_assert(sizeof(TransitHeader) == 36, "Wrong header size of transit section.");

/// \brief This class represents osm id and feature id of the same feature.
class FeatureIdentifiers
{
public:
  explicit FeatureIdentifiers(bool serializeFeatureIdOnly);
  FeatureIdentifiers(OsmId osmId, FeatureId const & featureId, bool serializeFeatureIdOnly);

  bool operator<(FeatureIdentifiers const & rhs) const;
  bool operator==(FeatureIdentifiers const & rhs) const;
  bool operator!=(FeatureIdentifiers const & rhs) const { return !(*this == rhs); }
  bool IsValid() const;
  void SetOsmId(OsmId osmId) { m_osmId = osmId; }
  void SetFeatureId(FeatureId featureId) { m_featureId = featureId; }

  OsmId GetOsmId() const { return m_osmId; }
  FeatureId GetFeatureId() const { return m_featureId; }
  bool IsSerializeFeatureIdOnly() const { return m_serializeFeatureIdOnly; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(FeatureIdentifiers, visitor(m_osmId, "osm_id"),
                                  visitor(m_featureId, "feature_id"))

  OsmId m_osmId = kInvalidOsmId;
  FeatureId m_featureId = kInvalidFeatureId;
  bool m_serializeFeatureIdOnly = true;
};

class TitleAnchor
{
public:
  TitleAnchor() = default;
  TitleAnchor(uint8_t minZoom, Anchor anchor);

  bool operator==(TitleAnchor const & titleAnchor) const;
  bool IsEqualForTesting(TitleAnchor const & titleAnchor) const;
  bool IsValid() const;

  uint8_t GetMinZoom() const { return m_minZoom; }
  Anchor const & GetAnchor() const { return m_anchor; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(TitleAnchor, visitor(m_minZoom, "min_zoom"),
                                  visitor(m_anchor, "anchor"))

  uint8_t m_minZoom = scales::UPPER_STYLE_SCALE;
  Anchor m_anchor = kInvalidAnchor;
};

class Stop
{
public:
  NEWTYPE(StopId, WrappedStopId);

  Stop() : m_featureIdentifiers(true /* serializeFeatureIdOnly */){};
  Stop(StopId id, OsmId osmId, FeatureId featureId, TransferId transferId,
       std::vector<LineId> const & lineIds, m2::PointD const & point,
       std::vector<TitleAnchor> const & titleAnchors);
  explicit Stop(StopId id) : m_id(id), m_featureIdentifiers(true /* serializeFeatureIdOnly */) {}

  bool operator<(Stop const & rhs) const { return m_id < rhs.m_id; }
  bool operator==(Stop const & rhs) const { return m_id == rhs.m_id; }
  bool IsEqualForTesting(Stop const & stop) const;
  bool IsValid() const;

  StopId GetId() const { return m_id.Get(); }
  FeatureId GetFeatureId() const { return m_featureIdentifiers.GetFeatureId(); }
  OsmId GetOsmId() const { return m_featureIdentifiers.GetOsmId(); }
  TransferId GetTransferId() const { return m_transferId; }
  std::vector<LineId> const & GetLineIds() const { return m_lineIds; }
  m2::PointD const & GetPoint() const { return m_point; }
  std::vector<TitleAnchor> const & GetTitleAnchors() const { return m_titleAnchors; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Stop, visitor(m_id, "id"),
                                  visitor(m_featureIdentifiers, "osm_id"),
                                  visitor(m_transferId, "transfer_id"),
                                  visitor(m_lineIds, "line_ids"), visitor(m_point, "point"),
                                  visitor(m_titleAnchors, "title_anchors"))

  WrappedStopId m_id = WrappedStopId(kInvalidStopId);
  FeatureIdentifiers m_featureIdentifiers;
  TransferId m_transferId = kInvalidTransferId;
  std::vector<LineId> m_lineIds;
  m2::PointD m_point;
  std::vector<TitleAnchor> m_titleAnchors;
};
NEWTYPE_SIMPLE_OUTPUT(Stop::WrappedStopId)

class SingleMwmSegment
{
public:
  SingleMwmSegment() = default;
  SingleMwmSegment(FeatureId featureId, uint32_t segmentIdx, bool forward);
  bool IsEqualForTesting(SingleMwmSegment const & s) const;
  bool IsValid() const;

  FeatureId GetFeatureId() const { return m_featureId; }
  uint32_t GetSegmentIdx() const { return m_segmentIdx; }
  bool GetForward() const { return m_forward; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(SingleMwmSegment, visitor(m_featureId, "feature_id"),
                                  visitor(m_segmentIdx, "segment_idx"),
                                  visitor(m_forward, "forward"))

  FeatureId m_featureId = kInvalidFeatureId;
  uint32_t m_segmentIdx = 0;
  bool m_forward = false;
};

class Gate
{
public:
  Gate() : m_featureIdentifiers(false /* serializeFeatureIdOnly */){};
  Gate(OsmId osmId, FeatureId featureId, bool entrance, bool exit, Weight weight,
       std::vector<StopId> const & stopIds, m2::PointD const & point);

  bool operator<(Gate const & rhs) const;
  bool operator==(Gate const & rhs) const;
  bool IsEqualForTesting(Gate const & gate) const;
  bool IsValid() const;
  void SetBestPedestrianSegment(SingleMwmSegment const & s) { m_bestPedestrianSegment = s; };

  FeatureId GetFeatureId() const { return m_featureIdentifiers.GetFeatureId(); }
  OsmId GetOsmId() const { return m_featureIdentifiers.GetOsmId(); }
  SingleMwmSegment const & GetBestPedestrianSegment() const { return m_bestPedestrianSegment; }
  bool GetEntrance() const { return m_entrance; }
  bool GetExit() const { return m_exit; }
  Weight GetWeight() const { return m_weight; }
  std::vector<StopId> const & GetStopIds() const { return m_stopIds; }
  m2::PointD const & GetPoint() const { return m_point; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Gate, visitor(m_featureIdentifiers, "osm_id"),
                                  visitor(m_bestPedestrianSegment, "best_pedestrian_segment"),
                                  visitor(m_entrance, "entrance"), visitor(m_exit, "exit"),
                                  visitor(m_weight, "weight"), visitor(m_stopIds, "stop_ids"),
                                  visitor(m_point, "point"))

  // |m_featureIdentifiers| contains feature id of a feature which represents gates. Usually it's a
  // point feature.
  FeatureIdentifiers m_featureIdentifiers;
  // |m_bestPedestrianSegment| is a segment which can be used for pedestrian routing to leave and
  // enter the gate. The segment may be invalid because of map date. If so there's no pedestrian
  // segment which can be used to reach the gate.
  SingleMwmSegment m_bestPedestrianSegment;
  bool m_entrance = true;
  bool m_exit = true;
  Weight m_weight = kInvalidWeight;
  std::vector<StopId> m_stopIds;
  m2::PointD m_point;
};

class ShapeId
{
public:
  ShapeId() = default;
  ShapeId(StopId stop1Id, StopId stop2Id) : m_stop1Id(stop1Id), m_stop2Id(stop2Id) {}

  bool operator<(ShapeId const & rhs) const;
  bool operator==(ShapeId const & rhs) const;
  bool IsEqualForTesting(ShapeId const & rhs) const { return *this == rhs; }

  bool IsValid() const;
  StopId GetStop1Id() const { return m_stop1Id; }
  StopId GetStop2Id() const { return m_stop2Id; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(ShapeId, visitor(m_stop1Id, "stop1_id"),
                                  visitor(m_stop2Id, "stop2_id"))

  StopId m_stop1Id = kInvalidStopId;
  StopId m_stop2Id = kInvalidStopId;
};

class EdgeFlags
{
public:
  DECLARE_TRANSIT_TYPE_FRIENDS
  friend std::string DebugPrint(EdgeFlags const & f);

  uint8_t GetFlags() const;
  void SetFlags(uint8_t flags);

  // |m_transfer == true| if |Edge::m_shapeIds| is empty.
  bool m_transfer = false;
  /// |m_isShapeIdsEmpty == true| if |Edge::m_shapeIds| is empty.
  bool m_isShapeIdsEmpty = false;
  // |m_isShapeIdsSingle == true| if |Edge::m_shapeIds| contains only one item.
  bool m_isShapeIdsSingle = false;
  // Note. If |m_isShapeIdsSingle == true| |m_isShapeIdsSame| is set to
  // |Edge::m_stop1Id == m_shapeIds[0].m_stop1Id && Edge::m_stop2Id == m_shapeIds[0].m_stop2Id|.
  // |m_isShapeIdsSingle| is invalid otherwise.
  bool m_isShapeIdsSame = false;
  // Note. If |m_isShapeIdsSingle == true| |m_isShapeIdsReversed| is set to
  // |Edge::m_stop1Id == m_shapeIds[0].m_stop2Id && Edge::m_stop2Id == m_shapeIds[0].m_stop1Id|.
  // |m_isShapeIdsReversed| is invalid otherwise.
  bool m_isShapeIdsReversed = false;

private:
  uint8_t BoolToUint(bool b) const { return static_cast<uint8_t>(b ? 1 : 0); }
  uint8_t GetBit(uint8_t flags, uint8_t mask) const { return BoolToUint((flags & mask) != 0); }

  static uint8_t constexpr kTransferMask = 1;
  static uint8_t constexpr kEmptyShapeIdsMask = (1 << 1);
  static uint8_t constexpr kSingleShapeIdMask = (1 << 2);
  static uint8_t constexpr kShapeIdIsSameMask = (1 << 3);
  static uint8_t constexpr kShapeIdIsReversedMask = (1 << 4);
};

std::string DebugPrint(EdgeFlags const & f);

class Edge
{
public:
  NEWTYPE(StopId, WrappedEdgeId);

  Edge() = default;
  Edge(StopId stop1Id, StopId stop2Id, Weight weight, LineId lineId, bool transfer,
       std::vector<ShapeId> const & shapeIds);

  bool operator<(Edge const & rhs) const;
  bool operator==(Edge const & rhs) const;
  bool operator!=(Edge const & rhs) const { return !(*this == rhs); }
  bool IsEqualForTesting(Edge const & edge) const;
  bool IsValid() const;
  void SetWeight(Weight weight) { m_weight = weight; }

  StopId GetStop1Id() const { return m_stop1Id.Get(); }
  StopId GetStop2Id() const { return m_stop2Id; }
  Weight GetWeight() const { return m_weight; }
  LineId GetLineId() const { return m_lineId; }
  bool GetTransfer() const { return m_flags.m_transfer; }
  std::vector<ShapeId> const & GetShapeIds() const { return m_shapeIds; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Edge, visitor(m_stop1Id, "stop1_id"),
                                  visitor(m_stop2Id, "stop2_id"), visitor(m_weight, "weight"),
                                  visitor(m_lineId, "line_id"), visitor(m_flags, "transfer"),
                                  visitor(m_shapeIds, "shape_ids"))

  WrappedEdgeId m_stop1Id = WrappedEdgeId(kInvalidStopId);
  StopId m_stop2Id = kInvalidStopId;
  Weight m_weight = kInvalidWeight;  // in seconds
  LineId m_lineId = kInvalidLineId;
  EdgeFlags m_flags;
  std::vector<ShapeId> m_shapeIds;
};
NEWTYPE_SIMPLE_OUTPUT(Edge::WrappedEdgeId)

class Transfer
{
public:
  Transfer() = default;
  Transfer(StopId id, m2::PointD const & point, std::vector<StopId> const & stopIds,
           std::vector<TitleAnchor> const & titleAnchors);

  bool operator<(Transfer const & rhs) const { return m_id < rhs.m_id; }
  bool operator==(Transfer const & rhs) const { return m_id == rhs.m_id; }
  bool IsEqualForTesting(Transfer const & transfer) const;
  bool IsValid() const;

  StopId GetId() const { return m_id; }
  m2::PointD const & GetPoint() const { return m_point; }
  std::vector<StopId> const & GetStopIds() const { return m_stopIds; }
  std::vector<TitleAnchor> const & GetTitleAnchors() const { return m_titleAnchors; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Transfer, visitor(m_id, "id"), visitor(m_point, "point"),
                                  visitor(m_stopIds, "stop_ids"),
                                  visitor(m_titleAnchors, "title_anchors"))

  StopId m_id = kInvalidStopId;
  m2::PointD m_point;
  std::vector<StopId> m_stopIds;
  std::vector<TitleAnchor> m_titleAnchors;
};

class StopIdRanges
{
public:
  StopIdRanges() = default;
  explicit StopIdRanges(Ranges const & ids) : m_ids(ids) {}

  bool operator==(StopIdRanges const & rhs) const { return m_ids == rhs.m_ids; }
  bool IsValid() const { return !m_ids.empty(); }

  Ranges const & GetIds() const { return m_ids; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(StopIdRanges, visitor(m_ids, "ids"))

  Ranges m_ids;
};

class Line
{
public:
  Line() = default;
  Line(LineId id, std::string const & number, std::string const & title, std::string const & type,
       std::string const & color, NetworkId networkId, Ranges const & stopIds, Weight interval);

  bool operator<(Line const & rhs) const { return m_id < rhs.m_id; }
  bool operator==(Line const & rhs) const { return m_id == rhs.m_id; }
  bool IsEqualForTesting(Line const & line) const;
  bool IsValid() const;

  LineId GetId() const { return m_id; }
  std::string const & GetNumber() const { return m_number; }
  std::string const & GetTitle() const { return m_title; }
  std::string const & GetType() const { return m_type; }
  std::string const & GetColor() const { return m_color; }
  NetworkId GetNetworkId() const { return m_networkId; }
  Ranges const & GetStopIds() const { return m_stopIds.GetIds(); }
  Weight GetInterval() const { return m_interval; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Line, visitor(m_id, "id"), visitor(m_number, "number"),
                                  visitor(m_title, "title"), visitor(m_type, "type"),
                                  visitor(m_color, "color"), visitor(m_networkId, "network_id"),
                                  visitor(m_stopIds, "stop_ids"), visitor(m_interval, "interval"))

  LineId m_id = kInvalidLineId;
  std::string m_number;
  std::string m_title;
  std::string m_type;
  std::string m_color = kInvalidColor;
  NetworkId m_networkId = kInvalidNetworkId;
  StopIdRanges m_stopIds;
  Weight m_interval = kInvalidWeight;
};

class Shape
{
public:
  Shape() = default;
  Shape(ShapeId const & id, std::vector<m2::PointD> const & polyline)
    : m_id(id), m_polyline(polyline)
  {
  }

  bool operator<(Shape const & rhs) const { return m_id < rhs.m_id; }
  bool operator==(Shape const & rhs) const { return m_id == rhs.m_id; }
  bool IsEqualForTesting(Shape const & shape) const;
  bool IsValid() const { return m_id.IsValid() && m_polyline.size() > 1; }

  ShapeId GetId() const { return m_id; }
  std::vector<m2::PointD> const & GetPolyline() const { return m_polyline; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Shape, visitor(m_id, "id"), visitor(m_polyline, "polyline"))

  ShapeId m_id;
  std::vector<m2::PointD> m_polyline;
};

class Network
{
public:
  Network() = default;
  Network(NetworkId id, std::string const & title);
  explicit Network(NetworkId id) : m_id(id), m_title("") {}

  bool operator<(Network const & rhs) const { return m_id < rhs.m_id; }
  bool operator==(Network const & rhs) const { return m_id == rhs.m_id; }
  bool IsEqualForTesting(Network const & shape) const;
  bool IsValid() const;

  NetworkId GetId() const { return m_id; }
  std::string const & GetTitle() const { return m_title; }

private:
  DECLARE_TRANSIT_TYPE_FRIENDS
  DECLARE_VISITOR_AND_DEBUG_PRINT(Network, visitor(m_id, "id"), visitor(m_title, "title"))

  NetworkId m_id = kInvalidNetworkId;
  std::string m_title;
};

template <class Item>
void CheckValid(std::vector<Item> const & items, std::string const & name)
{
  for (auto const & i : items)
    CHECK(i.IsValid(), (i, "is not valid. Table name:", name));
}

template <class Item>
void CheckSorted(std::vector<Item> const & items, std::string const & name)
{
  CHECK(std::is_sorted(items.cbegin(), items.cend()), ("Table is not sorted. Table name:", name));
}

template <class Item>
void CheckUnique(std::vector<Item> const & items, std::string const & name)
{
  auto const it = std::adjacent_find(items.cbegin(), items.cend());
  CHECK(it == items.cend(), (*it, "is not unique. Table name:", name));
}

template <class Item>
void CheckValidSortedUnique(std::vector<Item> const & items, std::string const & name)
{
  CheckValid(items, name);
  CheckSorted(items, name);
  CheckUnique(items, name);
}

EdgeFlags GetEdgeFlags(bool transfer, StopId stopId1, StopId stopId2,
                       std::vector<ShapeId> const & shapeIds);

#undef DECLARE_TRANSIT_TYPE_FRIENDS
}  // namespace transit
}  // namespace routing