#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 #include #include #include #include #include #include #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 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::max(); // Mapping of language id to text. Language id exists in |StringUtf8Multilang::kLanguages|. using Translations = std::unordered_map; 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; using IdSet = std::unordered_set; using TimeTable = std::unordered_map>; 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; 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::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; 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; template typename std::vector::const_iterator FindById(std::vector 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 GetPolylinePart(std::vector const & polyline, size_t startIdx, size_t endIdx) { CHECK_GREATER(endIdx, startIdx, ()); CHECK_GREATER(polyline.size(), endIdx, ()); return std::vector(polyline.begin() + startIdx, polyline.begin() + endIdx + 1); } } // namespace transit