def __init__(self, service_id, gtfs_override=None): # TODO: ensure this works for alternate calendars method self._gtfs = gtfs_override if gtfs_override else gtfs_singleton calendar_row = self._gtfs.get_table('calendar').loc[service_id] self.daterange = GTFSDateRange(calendar_row.loc['start_date'], calendar_row.loc['end_date']) # dows for day in DOWS: self.dows[day] = (calendar_row.loc[day] == GTFSBool.TRUE) # exceptions if self._gtfs.has_table('calendar_dates'): calendar_dates = self._gtfs.get_table('calendar_dates') exceptions = calendar_dates[calendar_dates['service_id'] == service_id] added_exceptions = exceptions[exceptions['exception_type'] == GTFSExceptionType.ADDED] self.added_dates = added_exceptions['date'].astype(str).tolist() removed_exceptions = exceptions[exceptions['exception_type'] == GTFSExceptionType.REMOVED] self.removed_dates = removed_exceptions['date'].astype( str).tolist()
def filter_board_alight_by_daterange(daterange): if not gtfs.has_table('board_alight'): return board_alight = gtfs.get_table('board_alight', index=False) if 'service_date' not in board_alight.columns: return filter_daterange = GTFSDateRange(daterange['start'], daterange['end']) board_alight['_inrange'] = board_alight.apply( lambda row: filter_daterange.includes(row['service_date']), axis=1) board_alight_filtered = board_alight[board_alight['_inrange']] gtfs.update_table('board_alight', board_alight_filtered)
def filter_calendar_dates_by_daterange(daterange): if not gtfs.has_table('calendar_dates'): return calendar_dates = gtfs.get_table('calendar_dates') filter_daterange = GTFSDateRange(daterange['start'], daterange['end']) calendar_dates['_gtfs_date'] = calendar_dates.apply( lambda row: GTFSDate(row['date']), axis=1) calendar_dates['_inrange'] = calendar_dates.apply( lambda row: filter_daterange.includes(row['date']), axis=1) calendar_dates_filtered = calendar_dates[calendar_dates['_inrange']] gtfs.update_table('calendar_dates', calendar_dates_filtered)
def reset_feed_dates(daterange): if not gtfs.has_table('feed_info'): return gtfs_daterange = GTFSDateRange(daterange['start'], daterange['end']) feed_info = gtfs.get_table('feed_info') feed_info['feed_start_date'] = gtfs_daterange.start.datestring() feed_info['feed_end_date'] = gtfs_daterange.end.datestring() gtfs.update_table('feed_info', feed_info)
def warn_if_any_input_dates_outside_gtfs_singleton_bounds(self, settings): if 'date_range' in settings: input_dr = GTFSDateRange(settings['date_range']['start'], settings['date_range']['end']) self.warn_if_daterange_not_within_gtfs_calendar_bounds(input_dr) self.warn_if_daterange_not_within_feed_bounds(input_dr) if 'date' in settings: input_date = GTFSDate(settings['date']) self.warn_if_date_not_within_gtfs_calendar_bounds(input_date) self.warn_if_date_not_within_feed_bounds(input_date)
class GTFSServiceCalendar: daterange = None dows = {} added_dates = [] # list of datestrings removed_dates = [] # list of datestrings _gtfs = None def __init__(self, service_id, gtfs_override=None): # TODO: ensure this works for alternate calendars method self._gtfs = gtfs_override if gtfs_override else gtfs_singleton calendar_row = self._gtfs.get_table('calendar').loc[service_id] self.daterange = GTFSDateRange(calendar_row.loc['start_date'], calendar_row.loc['end_date']) # dows for day in DOWS: self.dows[day] = (calendar_row.loc[day] == GTFSBool.TRUE) # exceptions if self._gtfs.has_table('calendar_dates'): calendar_dates = self._gtfs.get_table('calendar_dates') exceptions = calendar_dates[calendar_dates['service_id'] == service_id] added_exceptions = exceptions[exceptions['exception_type'] == GTFSExceptionType.ADDED] self.added_dates = added_exceptions['date'].astype(str).tolist() removed_exceptions = exceptions[exceptions['exception_type'] == GTFSExceptionType.REMOVED] self.removed_dates = removed_exceptions['date'].astype( str).tolist() def num_active_days(self): # hopefully this isn't slow on large calendars day_count = 0 current_date = self.daterange.start # add service days, not including days with removed service while not current_date.after(self.daterange.end): if self.dows[current_date.dow()] and (current_date.datestring() not in self.removed_dates): day_count += 1 current_date.add_days(1) # if added_dates are not in daterange or are not on served dow, add to day_count for ad in self.added_dates: added_date = GTFSDate(ad) if (not self.daterange.includes(added_date)) or ( not self.dows[added_date.dow()]): day_count += 1 return day_count
def filter_calendars_by_daterange(daterange): calendar = gtfs.get_table('calendar') filter_daterange = GTFSDateRange(daterange['start'], daterange['end']) calendar['_gtfs_daterange'] = calendar.apply( lambda row: GTFSDateRange(row['start_date'], row['end_date']), axis=1) calendar['_overlap'] = calendar['_gtfs_daterange'].apply(lambda dr: \ filter_daterange.get_overlap(dr) \ ) # we want to remove calendar entries that don't overlap DOWs calendar['_dows_overlap'] = calendar.apply(lambda row: \ GTFSBool.TRUE in (row[dow] for dow in filter_daterange.days_of_week()), axis=1 ) # we want to keep calendar entries that are used in overlapping exceptions if gtfs.has_table('calendar_dates'): calendar_dates = gtfs.get_table('calendar_dates') calendar_dates['_date_overlap'] = calendar_dates.apply( lambda row: filter_daterange.includes(row['date']), axis=1) calendar_dates = calendar_dates[calendar_dates['_date_overlap']] calendar['_exception_overlap'] = calendar.index.to_series().isin( calendar_dates['service_id']) else: calendar['_exception_overlap'] = False calendar = calendar[(calendar['_overlap'].notnull() & calendar['_dows_overlap']) | calendar['_exception_overlap']] # trim bounds to fit within daterange calendar['start_date'] = calendar['_overlap'].apply( lambda dr: dr.start.datestring()) calendar['end_date'] = calendar['_overlap'].apply( lambda dr: dr.end.datestring()) gtfs.update_table('calendar', calendar)
def get_feed_start_end_daterange(): if not gtfs.has_table('feed_info'): return None feed_info = gtfs.get_table('feed_info') return GTFSDateRange(feed_info.loc[0, 'feed_start_date'], feed_info.loc[0, 'feed_end_date'])
def get_feed_calendar_service_daterange(): calendar = gtfs.get_table('calendar') calendar_min_start = calendar['start_date'].min() calendar_max_end = calendar['end_date'].max() return GTFSDateRange(calendar_min_start, calendar_max_end)