예제 #1
0
    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()
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
    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)
예제 #6
0
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
예제 #7
0
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)
예제 #8
0
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'])
예제 #9
0
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)