Given a route_id generate a list of patterns of the route. For each
    pattern include some basic information and a few sample trips.

def handle_json_GET_routepatterns(self, params):
    """Given a route_id generate a list of patterns of the route. For each
    pattern include some basic information and a few sample trips."""
    schedule = self.server.schedule
    route = schedule.GetRoute(params.get('route', None))
    if not route:
      self.send_error(404)
      return
    time = int(params.get('time', 0))
    date = params.get('date', "")
    sample_size = 3  # For each pattern return the start time for this many trips

    pattern_id_trip_dict = route.GetPatternIdTripDict()
    patterns = []

    for pattern_id, trips in pattern_id_trip_dict.items():
      time_stops = trips[0].GetTimeStops()
      if not time_stops:
        continue
      has_non_zero_trip_type = False;

      # Iterating over a copy so we can remove from trips inside the loop
      trips_with_service = []
      for trip in trips:
        service_id = trip.service_id
        service_period = schedule.GetServicePeriod(service_id)

        if date and not service_period.IsActiveOn(date):
          continue
        trips_with_service.append(trip)

        if trip['trip_type'] and trip['trip_type'] != '0':
          has_non_zero_trip_type = True

      # We're only interested in the trips that do run on the specified date
      trips = trips_with_service

      name = u'%s to %s, %d stops' % (time_stops[0][2].stop_name, time_stops[-1][2].stop_name, len(time_stops))
      transitfeed.SortListOfTripByTime(trips)

      num_trips = len(trips)
      if num_trips <= sample_size:
        start_sample_index = 0
        num_after_sample = 0
      else:
        # Will return sample_size trips that start after the 'time' param.

        # Linear search because I couldn't find a built-in way to do a binary
        # search with a custom key.
        start_sample_index = len(trips)
        for i, trip in enumerate(trips):
          if trip.GetStartTime() >= time:
            start_sample_index = i
            break

        num_after_sample = num_trips - (start_sample_index + sample_size)
        if num_after_sample < 0:
          # Less than sample_size trips start after 'time' so return all the
          # last sample_size trips.
          num_after_sample = 0
          start_sample_index = num_trips - sample_size

      sample = []
      for t in trips[start_sample_index:start_sample_index + sample_size]:
        sample.append( (t.GetStartTime(), t.trip_id) )

      patterns.append((name, pattern_id, start_sample_index, sample,
                       num_after_sample, (0,1)[has_non_zero_trip_type]))

    patterns.sort()
    return patterns