Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
252
libs/transit/transit_schedule.hpp
Normal file
252
libs/transit/transit_schedule.hpp
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
#pragma once
|
||||
|
||||
#include "base/macros.hpp"
|
||||
#include "base/newtype.hpp"
|
||||
#include "base/visitor.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "3party/just_gtfs/just_gtfs.h"
|
||||
|
||||
// This is the implementation of the Schedule class and its helpers for handling transit service
|
||||
// days and stops timetables.
|
||||
namespace routing
|
||||
{
|
||||
namespace transit
|
||||
{
|
||||
template <class Sink>
|
||||
class Serializer;
|
||||
template <class Source>
|
||||
class Deserializer;
|
||||
template <typename Sink>
|
||||
class FixedSizeSerializer;
|
||||
template <typename Sink>
|
||||
class FixedSizeDeserializer;
|
||||
} // namespace transit
|
||||
} // namespace routing
|
||||
|
||||
namespace transit
|
||||
{
|
||||
#define DECLARE_SCHEDULE_TYPES_FRIENDS \
|
||||
template <class Sink> \
|
||||
friend class routing::transit::Serializer; \
|
||||
template <class Source> \
|
||||
friend class routing::transit::Deserializer; \
|
||||
template <typename Sink> \
|
||||
friend class routing::transit::FixedSizeSerializer; \
|
||||
template <typename Sink> \
|
||||
friend class routing::transit::FixedSizeDeserializer;
|
||||
|
||||
// Status of some transit itinerary (e.g. line) in the moment of time.
|
||||
enum class Status : uint8_t
|
||||
{
|
||||
Open,
|
||||
Closed,
|
||||
Unknown
|
||||
};
|
||||
|
||||
std::string DebugPrint(Status const & status);
|
||||
|
||||
struct Date
|
||||
{
|
||||
Date() = default;
|
||||
Date(uint32_t year, uint8_t month, uint16_t day) : m_year(year), m_month(month), m_day(day) {}
|
||||
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(Date, visitor(m_year, "y"), visitor(m_month, "m"), visitor(m_day, "d"))
|
||||
|
||||
uint32_t m_year = 0;
|
||||
uint8_t m_month = 0;
|
||||
uint16_t m_day = 0;
|
||||
};
|
||||
|
||||
struct Time
|
||||
{
|
||||
Time() = default;
|
||||
Time(uint8_t hour, uint8_t minute, uint8_t second) : m_hour(hour), m_minute(minute), m_second(second) {}
|
||||
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(Time, visitor(m_hour, "h"), visitor(m_minute, "m"), visitor(m_second, "s"))
|
||||
|
||||
uint8_t m_hour = 0;
|
||||
uint8_t m_minute = 0;
|
||||
uint8_t m_second = 0;
|
||||
};
|
||||
|
||||
using WeekSchedule = std::array<bool, 7>;
|
||||
|
||||
enum WeekDays
|
||||
{
|
||||
Sunday = 0,
|
||||
Monday,
|
||||
Tuesday,
|
||||
Wednesday,
|
||||
Thursday,
|
||||
Friday,
|
||||
Saturday
|
||||
};
|
||||
|
||||
// Service dates specified using a weekly schedule with start and end dates. Dates range is
|
||||
// specified by the start_date and end_date fields in the GTFS calendar.txt.
|
||||
// Dates interval and open/closed states for week days are stored |m_data|.
|
||||
class DatesInterval
|
||||
{
|
||||
public:
|
||||
DatesInterval() = default;
|
||||
explicit DatesInterval(gtfs::CalendarItem const & calendarItem);
|
||||
explicit DatesInterval(uint32_t data);
|
||||
|
||||
bool operator==(DatesInterval const & rhs) const;
|
||||
|
||||
std::tuple<Date, Date, WeekSchedule> Extract() const;
|
||||
uint32_t GetRaw() const { return m_data; }
|
||||
|
||||
Status GetStatusInInterval(Date const & date, uint8_t wdIndex) const;
|
||||
|
||||
private:
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(DatesInterval, visitor(m_data, "m_data"))
|
||||
|
||||
// From greater indexes to smaller: year1, month1, day1, years delta (year2 - year1), month2,
|
||||
// day2, weekdays. Week indexes start from sunday = 0.
|
||||
uint32_t m_data = 0;
|
||||
};
|
||||
|
||||
struct DatesIntervalHasher
|
||||
{
|
||||
size_t operator()(DatesInterval const & key) const { return key.GetRaw(); }
|
||||
};
|
||||
|
||||
// Exceptions for the services defined in the calendar.txt. If calendar.txt is not used, it may
|
||||
// contain all dates of service. Exception date and its type (added/removed) are stored in |m_data|.
|
||||
class DateException
|
||||
{
|
||||
public:
|
||||
DateException() = default;
|
||||
DateException(gtfs::Date const & date, gtfs::CalendarDateException const & dateException);
|
||||
explicit DateException(uint16_t data);
|
||||
|
||||
bool operator==(DateException const & rhs) const;
|
||||
|
||||
std::tuple<Date, bool> Extract() const;
|
||||
uint32_t GetRaw() const { return m_data; }
|
||||
|
||||
Status GetExceptionStatus(Date const & date) const;
|
||||
|
||||
private:
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(DateException, visitor(m_data, "m_data"))
|
||||
|
||||
// From greater indexes to smaller: year, month, day, status
|
||||
uint16_t m_data = 0;
|
||||
};
|
||||
|
||||
struct DateExceptionHasher
|
||||
{
|
||||
size_t operator()(DateException const & key) const { return key.GetRaw(); }
|
||||
};
|
||||
|
||||
// Time range for lines frequencies or stop timetables. Start time and end time are stored in
|
||||
// m_data.
|
||||
class TimeInterval
|
||||
{
|
||||
public:
|
||||
TimeInterval() = default;
|
||||
TimeInterval(gtfs::Time const & startTime, gtfs::Time const & endTime);
|
||||
explicit TimeInterval(uint64_t data);
|
||||
|
||||
bool operator<(TimeInterval const & rhs) const;
|
||||
bool operator==(TimeInterval const & rhs) const;
|
||||
|
||||
std::pair<Time, Time> Extract() const;
|
||||
uint64_t GetRaw() const { return m_data; }
|
||||
|
||||
Status GetTimeStatus(Time const & time) const;
|
||||
|
||||
private:
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(TimeInterval, visitor(m_data, "m_data"))
|
||||
|
||||
// From greater indexes to smaller: start time, end time.
|
||||
uint64_t m_data = 0;
|
||||
};
|
||||
|
||||
using Frequency = uint32_t;
|
||||
inline Frequency constexpr kDefaultFrequency = 0;
|
||||
|
||||
// Headway (interval between times that a vehicle arrives at and departs from stops) for
|
||||
// headway-based service or a compressed representation of fixed-schedule service. For each time
|
||||
// range there is a frequency value.
|
||||
class FrequencyIntervals
|
||||
{
|
||||
public:
|
||||
FrequencyIntervals() = default;
|
||||
FrequencyIntervals(gtfs::Frequencies const & frequencies);
|
||||
|
||||
bool operator==(FrequencyIntervals const & rhs) const;
|
||||
|
||||
void AddInterval(TimeInterval const & timeInterval, Frequency frequency);
|
||||
|
||||
Frequency GetFrequency(Time const & time) const;
|
||||
std::map<TimeInterval, Frequency> const & GetFrequencies() const;
|
||||
|
||||
private:
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(FrequencyIntervals, visitor(m_intervals, "m_intervals"))
|
||||
|
||||
std::map<TimeInterval, Frequency> m_intervals;
|
||||
};
|
||||
|
||||
using DatesIntervals = std::unordered_map<DatesInterval, FrequencyIntervals, DatesIntervalHasher>;
|
||||
using DatesExceptions = std::unordered_map<DateException, FrequencyIntervals, DateExceptionHasher>;
|
||||
|
||||
// Line schedule with line service days (as DatesInterval ranges) and exceptions in service days
|
||||
// (as DateException items). For each date there are frequency intervals (time ranges with headway
|
||||
// in seconds). This schedule is useful while building transit routes based on particular route
|
||||
// start time.
|
||||
class Schedule
|
||||
{
|
||||
public:
|
||||
bool operator==(Schedule const & rhs) const;
|
||||
|
||||
void AddDatesInterval(gtfs::CalendarItem const & calendarItem, gtfs::Frequencies const & frequencies);
|
||||
void AddDateException(gtfs::Date const & date, gtfs::CalendarDateException const & dateException,
|
||||
gtfs::Frequencies const & frequencies);
|
||||
|
||||
Status GetStatus(time_t const & time) const;
|
||||
Frequency GetFrequency(time_t const & time) const;
|
||||
Frequency GetFrequency() const { return m_defaultFrequency; }
|
||||
|
||||
DatesIntervals const & GetServiceIntervals() const;
|
||||
DatesExceptions const & GetServiceExceptions() const;
|
||||
|
||||
void AddDatesInterval(DatesInterval const & interval, FrequencyIntervals const & frequencies);
|
||||
void AddDateException(DateException const & dateException, FrequencyIntervals const & frequencies);
|
||||
|
||||
void SetDefaultFrequency(Frequency const & frequency) { m_defaultFrequency = frequency; }
|
||||
|
||||
private:
|
||||
std::pair<Date, uint8_t> GetDateAndWeekIndex(time_t const & time) const;
|
||||
std::tuple<Date, Time, uint8_t> GetDateTimeAndWeekIndex(time_t const & time) const;
|
||||
|
||||
DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(Schedule, visitor(m_serviceIntervals, "m_serviceIntervals"),
|
||||
visitor(m_serviceExceptions, "m_serviceExceptions"),
|
||||
visitor(m_defaultFrequency, "m_defaultFrequency"))
|
||||
|
||||
DatesIntervals m_serviceIntervals;
|
||||
DatesExceptions m_serviceExceptions;
|
||||
|
||||
Frequency m_defaultFrequency = kDefaultFrequency;
|
||||
};
|
||||
|
||||
#undef DECLARE_SCHEDULE_TYPES_FRIENDS
|
||||
} // namespace transit
|
||||
Loading…
Add table
Add a link
Reference in a new issue