def get_stop_times( id, dir=None, date=None ): """Returns a stop with a list of stop times. The stop ID is required. Either a direction or a date must be given to filter the times at this stop. If a direction is given. All stop times for this stop constrained by trip direction. If a date is given. All stop times for this stop constrained by services on the specific date. :param id: stop id. :param dir: optional route direction, codes are '1' and '0'. :param date: a datetime.date object; the services available on this date are used to filter the results. :returns: a :class:`Stop_Definition` instance. """ Stop_Definition.set_db( settings.db ) stop= list( Stop_Definition.view('service/stop',key=id) )[0] if date: services= set(get_services_today( date )) for s in stop.trips: if s not in services: del stop.trips[s] if dir: for svc in stop.trips: for trip in stop.trips[svc]: if stop.trips[svc][trip]['direction_id'] != dir: del stop.trips[svc][trip] return stop
def get_closest_times_in_service( stop_id, time, services, min_time=None, max_time=None ): """Given a stop and a time, locate the scheduled stop_time closest to this. :param stop_id: The id for a stop :param time: The seconds-after-midnight time :param services: The iterable sequence of services applicable :param min_time: The lower limit on seconds prior to the scheduled time. Usually, this is a negative number. :param max_time: The upper limit on seconds after the the scheduled time. This is a positive number. :returns: iterator over (time,stop_time) pairs ordered from closest in time to the max_time value. The absolute magnitude is used for sorting so early and late times will be intermixed. """ # get StopTimes based on Stop. Need a view of key=Stop, value=stop time Stop_Definition.set_db( settings.db ) stop= list( Stop_Definition.view('service/stop') )[0] trips = [] for svc in services: trips.extend( stop.trips[svc].values() ) times = ( (st['arrival_time']-time, st) for t in trips for st in t['times'] ) if min_time is not None: times = ( (time,stop) for time,stop in times if time >= min_time ) if max_time is not None: times = ( (time,stop) for time,stop in times if time < max_time ) return sorted(times, key=lambda x: abs(x[0]) )
def get_closest_stops( lat_lon, max_dist=None ): """Given a lat/lon pair, locate nearby stops. :param lat_lon: A (lat,lon) 2-tuple :param max_dist: An upper limit on distances to examine :return: iterator over (distance,stop) pairs ordered from nearest to the specified max_dist value. """ Stop_Definition.set_db( settings.db ) distances= ( (dist_approx( lat_lon, (s.stop_lat,s.stop_lon) ), s) for s in Stop_Definition.view('service/stop') ) if max_dist is not None: distances = ( (dist,stop) for dist,stop in distances if dist < max_dist ) return sorted(distances)
def get_stop( id=None ): """Returns stop or list of stops. If ``id`` is None, it returns all stop definitions. Otherwise, it returns the requested stop definition. :param id: Optional stop id. If no stop id, all stops are returned. :return: stop definition or list of stop definitions. """ Stop_Definition.set_db( settings.db ) if id: return list( Stop_Definition.view( 'service/stop', key=id ) ) else: return list( Stop_Definition.view( 'service/stop' ) )
def test_should_get_next_stop( self ): stop= list( Stop_Definition.view('service/stop',key='0001') )[0] stop_time= 23580 stops = list( caravel.transit_system.query.get_next_stop_time( stop, stop_time, services=['WE','MR'], ) ) #print( ">>> test_should_get_next_stop", stops ) self.assertEqual( '0001', stops[0]['stop_id']) self.assertEqual( '0406', stops[1]['stop_id'])
def _load_stops(self, rdr): """Fetch the stops table, creating :class:`Stop_Definition` objects. Note that some stops don't have any stop times, and should be ignored. """ Stop_Definition.set_db( settings.db ) for row in rdr: for s in Stop_Definition.view( 'service/stop', key=row['stop_id'] ): s.delete() row['stop_lat']= float(row['stop_lat']) row['stop_lon']= float(row['stop_lon']) stop= Stop_Definition(**row) stop.save()
def _load_stop_times(self, rdr): """Fetch the stop_times table, :class:`Route_Definition` objects with times. Must be done last. Requires the self.trip and self.trip_by_route information. """ for row in rdr: try: row['arrival_time']= self.time_parse(row['arrival_time']) row['departure_time']= self.time_parse(row['departure_time']) except ValueError: raise GTFException( "Bad Time {0!r}".format(row) ) trip= self.trip[row['trip_id']] docs= list( Route_Definition.view( 'service/route', key=trip['route_id'] ) ) route= docs[0] if trip['service_id'] not in route.trips: route.trips[ trip['service_id'] ]= {} if trip['trip_id'] not in route.trips[trip['service_id']]: route.trips[ trip['service_id'] ][trip['trip_id']] = dict( direction_id= trip['direction_id'], block_id= trip['block_id'], stops= [], ) route_trip= route.trips[ trip['service_id'] ][trip['trip_id']] route_trip['stops'].append( row ) route.save() docs = list( Stop_Definition.view( 'service/stop', key=row['stop_id'])) stop= docs[0] if trip['service_id'] not in stop.trips: stop.trips[ trip['service_id'] ]= {} if trip['trip_id'] not in stop.trips[trip['service_id']]: stop.trips[ trip['service_id'] ][trip['trip_id']] = dict( direction_id= trip['direction_id'], block_id= trip['block_id'], route= trip['route_id'], times= [], ) stop_trip= stop.trips[ trip['service_id'] ][trip['trip_id']] stop_trip['times'].append( row ) stop.save()