예제 #1
0
 def __init__(self, limit_per_type, ignore_types=None):
   # {TYPE_WARNING: {"ClassName": BoundedProblemList()}}
   self._type_to_name_to_problist = {
     TYPE_WARNING: defaultdict(lambda: BoundedProblemList(limit_per_type)),
     TYPE_ERROR: defaultdict(lambda: BoundedProblemList(limit_per_type))
   }
   self._ignore_types = ignore_types or set()
예제 #2
0
 def __init__(self, limit_per_type):
     # {TYPE_WARNING: {"ClassName": BoundedProblemList()}}
     self._type_to_name_to_problist = {
         TYPE_WARNING:
         defaultdict(lambda: BoundedProblemList(limit_per_type)),
         TYPE_ERROR: defaultdict(lambda: BoundedProblemList(limit_per_type))
     }
예제 #3
0
  def GenerateDateTripsDeparturesList(self, date_start, date_end):
    """Return a list of (date object, number of trips, number of departures).

    The list is generated for dates in the range [date_start, date_end).

    Args:
      date_start: The first date in the list, a date object
      date_end: The first date after the list, a date object

    Returns:
      a list of (date object, number of trips, number of departures) tuples
    """
    
    service_id_to_trips = defaultdict(lambda: 0)
    service_id_to_departures = defaultdict(lambda: 0)
    for trip in self.GetTripList():
      headway_start_times = trip.GetFrequencyStartTimes()
      if headway_start_times:
        trip_runs = len(headway_start_times)
      else:
        trip_runs = 1

      service_id_to_trips[trip.service_id] += trip_runs
      service_id_to_departures[trip.service_id] += (
          (trip.GetCountStopTimes() - 1) * trip_runs)

    date_services = self.GetServicePeriodsActiveEachDate(date_start, date_end)
    date_trips = []

    for date, services in date_services:
      day_trips = sum(service_id_to_trips[s.service_id] for s in services)
      day_departures = sum(
          service_id_to_departures[s.service_id] for s in services)
      date_trips.append((date, day_trips, day_departures))
    return date_trips
예제 #4
0
 def __init__(self, limit_per_type, ignore_types=None):
     # {TYPE_WARNING: {"ClassName": BoundedProblemList()}}
     self._type_to_name_to_problist = {
         TYPE_WARNING: defaultdict(lambda: BoundedProblemList(limit_per_type)),
         TYPE_ERROR: defaultdict(lambda: BoundedProblemList(limit_per_type)),
         TYPE_NOTICE: defaultdict(lambda: BoundedProblemList(limit_per_type)),
     }
     self._ignore_types = ignore_types or set()
예제 #5
0
  def __init__(self, problem_reporter=None,
               memory_db=True, check_duplicate_trips=False,
               gtfs_factory=None, db_filename=None, create_db=True):
    if gtfs_factory is None:
      gtfs_factory = gtfsfactory.GetGtfsFactory()
    self._gtfs_factory = gtfs_factory

    # Map from table name to list of columns present in this schedule
    self._table_columns = {}

    self._agencies = {}
    self.stops = {}
    self.routes = {}
    self.trips = {}
    self.service_periods = {}
    self.fares = {}
    self.fare_zones = {}  # represents the set of all known fare zones
    self._shapes = {}  # shape_id to Shape
    # A map from transfer._ID() to a list of transfers. A list is used so
    # there can be more than one transfer with each ID. Once GTFS explicitly
    # prohibits duplicate IDs this might be changed to a simple dict of
    # Transfers.
    self._transfers = defaultdict(lambda: [])
    self._default_service_period = None
    self._default_agency = None
    if problem_reporter is None:
      self.problem_reporter = problems_module.default_problem_reporter
    else:
      self.problem_reporter = problem_reporter
    self._check_duplicate_trips = check_duplicate_trips
    self.ConnectDb(memory_db, db_filename, create_db)
예제 #6
0
def calendar_summary(schedule):
    today = datetime.date.today()
    summary_end_date = today + datetime.timedelta(days=60)
    start_date, end_date = schedule.get_date_range()

    if not start_date or not end_date:
        return {}

    start_date_object = transitfeed.date_string_to_date_object(start_date)
    end_date_object = transitfeed.date_string_to_date_object(end_date)
    if not start_date_object or not end_date_object:
        return {}

    # Get the list of trips only during the period the feed is active.
    # As such we have to check if it starts in the future and/or if
    # if it ends in less than 60 days.
    date_trips_departures = schedule.generate_date_trips_departures_list(
        max(today, start_date_object), min(summary_end_date, end_date_object))

    if not date_trips_departures:
        return {}

    # Check that the dates which will be shown in summary agree with these
    # calculations. Failure implies a bug which should be fixed. It isn't good
    # for users to discover assertion failures but means it will likely be fixed.
    assert start_date <= date_trips_departures[0][0].strftime("%Y%m%d")
    assert end_date >= date_trips_departures[-1][0].strftime("%Y%m%d")

    # Generate a map from int number of trips in a day to a list of date objects
    # with that many trips. The list of dates is sorted.
    trips_dates = defaultdict(list)
    trips = 0
    for date, day_trips, day_departures in date_trips_departures:
        trips += day_trips
        trips_dates[day_trips].append(date)
    mean_trips = trips / len(date_trips_departures)
    max_trips = max(trips_dates.keys())
    min_trips = min(trips_dates.keys())

    return {
        'mean_trips':
        mean_trips,
        'max_trips':
        max_trips,
        'max_trips_dates':
        format_date_list(trips_dates[max_trips]),
        'min_trips':
        min_trips,
        'min_trips_dates':
        format_date_list(trips_dates[min_trips]),
        'date_trips_departures':
        date_trips_departures,
        'date_summary_range':
        "%s to %s" % (date_trips_departures[0][0].strftime("%a %b %d"),
                      date_trips_departures[-1][0].strftime("%a %b %d"))
    }
def CalendarSummary(schedule):
  today = datetime.date.today()
  summary_end_date = today + datetime.timedelta(days=60)
  start_date, end_date = schedule.GetDateRange()

  if not start_date or not end_date:
    return {}
  
  try:
    start_date_object = transitfeed.DateStringToDateObject(start_date)
    end_date_object = transitfeed.DateStringToDateObject(end_date)
  except ValueError:
    return {}

  # Get the list of trips only during the period the feed is active.
  # As such we have to check if it starts in the future and/or if
  # if it ends in less than 60 days.
  date_trips_departures = schedule.GenerateDateTripsDeparturesList(
                              max(today, start_date_object),
                              min(summary_end_date, end_date_object))

  if not date_trips_departures:
    return {}

  # Check that the dates which will be shown in summary agree with these
  # calculations. Failure implies a bug which should be fixed. It isn't good
  # for users to discover assertion failures but means it will likely be fixed.
  assert start_date <= date_trips_departures[0][0].strftime("%Y%m%d")
  assert end_date >= date_trips_departures[-1][0].strftime("%Y%m%d")

  # Generate a map from int number of trips in a day to a list of date objects
  # with that many trips. The list of dates is sorted.
  trips_dates = defaultdict(lambda: [])
  trips = 0
  for date, day_trips, day_departures in date_trips_departures:
    trips += day_trips
    trips_dates[day_trips].append(date)
  mean_trips = trips / len(date_trips_departures)
  max_trips = max(trips_dates.keys())
  min_trips = min(trips_dates.keys())

  calendar_summary = {}
  calendar_summary['mean_trips'] = mean_trips
  calendar_summary['max_trips'] = max_trips
  calendar_summary['max_trips_dates'] = FormatDateList(trips_dates[max_trips])
  calendar_summary['min_trips'] = min_trips
  calendar_summary['min_trips_dates'] = FormatDateList(trips_dates[min_trips])
  calendar_summary['date_trips_departures'] = date_trips_departures
  calendar_summary['date_summary_range'] = "%s to %s" % (
      date_trips_departures[0][0].strftime("%a %b %d"),
      date_trips_departures[-1][0].strftime("%a %b %d"))

  return calendar_summary
예제 #8
0
  def ValidateTrips(self, problems):
    stop_types = {} # a dict mapping stop_id to [route_id, route_type, is_match]
    trips = {} # a dict mapping tuple to (route_id, trip_id)

    # a dict mapping block_id to a list of tuple of
    # (trip_id, first_arrival_secs, last_arrival_secs)
    trip_intervals_by_block_id = defaultdict(lambda: [])

    for trip in sorted(self.trips.values()):
      if trip.route_id not in self.routes:
        continue
      route_type = self.GetRoute(trip.route_id).route_type
      stop_ids = []
      stop_times = trip.GetStopTimes(problems)
      for index, st in enumerate(stop_times):
        stop_id = st.stop.stop_id
        stop_ids.append(stop_id)
        # Check a stop if which belongs to both subway and bus.
        if (route_type == self._gtfs_factory.Route._ROUTE_TYPE_NAMES['Subway'] or
            route_type == self._gtfs_factory.Route._ROUTE_TYPE_NAMES['Bus']):
          if stop_id not in stop_types:
            stop_types[stop_id] = [trip.route_id, route_type, 0]
          elif (stop_types[stop_id][1] != route_type and
                stop_types[stop_id][2] == 0):
            stop_types[stop_id][2] = 1
            if stop_types[stop_id][1] == \
                self._gtfs_factory.Route._ROUTE_TYPE_NAMES['Subway']:
              subway_route_id = stop_types[stop_id][0]
              bus_route_id = trip.route_id
            else:
              subway_route_id = trip.route_id
              bus_route_id = stop_types[stop_id][0]
            problems.StopWithMultipleRouteTypes(st.stop.stop_name, stop_id,
                                                subway_route_id, bus_route_id)

      # We only care about trips with a block id
      if not util.IsEmpty(trip.block_id) and stop_times:

        first_arrival_secs = stop_times[0].arrival_secs
        last_departure_secs = stop_times[-1].departure_secs

        # The arrival and departure time of the first and last stop_time
        # SHOULD be set, but we need to handle the case where we're given
        # an invalid feed anyway
        if first_arrival_secs is not None and last_departure_secs is not None:

          # Create a trip interval tuple of the trip id and arrival time
          # intervals
          key = trip.block_id
          trip_intervals = trip_intervals_by_block_id[key]
          trip_interval = (trip, first_arrival_secs, last_departure_secs)
          trip_intervals.append(trip_interval)

      # Check duplicate trips which go through the same stops with same
      # service and start times.
      if self._check_duplicate_trips:
        if not stop_ids or not stop_times:
          continue
        key = (trip.service_id, stop_times[0].arrival_time, str(stop_ids))
        if key not in trips:
          trips[key] = (trip.route_id, trip.trip_id)
        else:
          problems.DuplicateTrip(trips[key][1], trips[key][0], trip.trip_id,
                                 trip.route_id)

    # Now that we've generated our block trip intervls, we can check for
    # overlaps in the intervals
    self.ValidateBlocks(problems, trip_intervals_by_block_id)