def test_trip(self): dao = Dao() f1 = FeedInfo("F1") a1 = Agency("F1", "A1", "Agency 1", agency_url="http://www.agency.fr/", agency_timezone="Europe/Paris") r1 = Route("F1", "R1", "A1", 3, route_short_name="R1", route_long_name="Route 1") c1 = Calendar("F1", "C1") c1.dates = [ d for d in CalendarDate.range(CalendarDate.ymd(2016, 1, 1), CalendarDate.ymd(2016, 1, 31).next_day()) ] s1 = Stop("F1", "S1", "Stop 1", 45.0, 0.0) s2 = Stop("F1", "S2", "Stop 2", 45.1, 0.1) s3 = Stop("F1", "S3", "Stop 3", 45.2, 0.2) t1 = Trip("F1", "T1", "R1", "C1") t11 = StopTime("F1", "T1", "S1", 0, 28800, 28800, 0.0) t12 = StopTime("F1", "T1", "S2", 1, 29400, 29400, 0.0) t13 = StopTime("F1", "T1", "S3", 2, 30000, 30000, 0.0) t2 = Trip("F1", "T2", "R1", "C1") # Order is not important for now t2.stop_times.append(StopTime(None, None, "S1", 1, 31000, 31000, 0.0)) t2.stop_times.append(StopTime(None, None, "S2", 0, 30600, 30600, 0.0)) dao.add_all([ f1, a1, r1, c1, s1, s2, s3, t1, t11, t12, t13, t2 ]) # Commit is needed to re-order stop times of T2 dao.commit() cal = dao.calendar("C1", feed_id="F1") for trip in cal.trips: self.assertTrue(trip.calendar.service_id == "C1") for stoptime in trip.stop_times: self.assertTrue(stoptime.trip.calendar.service_id == "C1") stop = dao.stop("S2", feed_id="F1") for stoptime in stop.stop_times: self.assertTrue(stoptime.stop.stop_id == "S2") self.assertTrue(stoptime.trip.trip_id.startswith("T")) trip = dao.trip("T1", feed_id="F1") self.assertTrue(len(trip.stop_times) == 3) trip = dao.trip("T2", feed_id="F1") self.assertTrue(len(trip.stop_times) == 2) for trip in dao.trips(prefetch_stop_times=True): last_stop_seq = -1 for stoptime in trip.stop_times: self.assertTrue(stoptime.stop_sequence > last_stop_seq) last_stop_seq = stoptime.stop_sequence for trip in dao.trips(): for stoptime1, stoptime2 in trip.hops(): self.assertTrue(stoptime1.trip == stoptime2.trip) self.assertTrue(stoptime1.stop_sequence + 1 == stoptime2.stop_sequence)
def test_broken(self): exception = False try: dao = Dao("") dao.load_gtfs(BROKEN_GTFS, lenient=False) except KeyError: exception = True self.assertTrue(exception) dao = Dao("") dao.load_gtfs(BROKEN_GTFS, lenient=True) # The following are based on BROKEN GTFS content, # that is the entities count minus broken ones. self.assertTrue(len(dao.routes()) == 4) self.assertTrue(len(list(dao.stops())) == 12) self.assertTrue(len(dao.calendars()) == 2) self.assertTrue(len(list(dao.trips())) == 104) self.assertTrue(len(dao.stoptimes()) == 500) self.assertTrue(len(dao.fare_attributes()) == 2) self.assertTrue(len(dao.fare_rules()) == 4) # This stop has missing coordinates in the broken file stop00 = dao.stop('FUR_CREEK_RES3') self.assertAlmostEquals(stop00.stop_lat, 0.0, 5) self.assertAlmostEquals(stop00.stop_lon, 0.0, 5)
def test_broken(self): exception = False try: clear_mappers() dao = Dao("") dao.load_gtfs(BROKEN_GTFS, lenient=False) except KeyError: exception = True self.assertTrue(exception) clear_mappers() dao = Dao("") dao.load_gtfs(BROKEN_GTFS, lenient=True) # The following are based on BROKEN GTFS content, # that is the entities count minus broken ones. self.assertTrue(len(dao.routes()) == 4) self.assertTrue(len(list(dao.stops())) == 12) self.assertTrue(len(dao.calendars()) == 2) self.assertTrue(len(list(dao.trips())) == 104) self.assertTrue(len(dao.stoptimes()) == 500) self.assertTrue(len(dao.fare_attributes()) == 2) self.assertTrue(len(dao.fare_rules()) == 4) # This stop has missing coordinates in the broken file stop00 = dao.stop('FUR_CREEK_RES3') self.assertAlmostEquals(stop00.stop_lat, 0.0, 5) self.assertAlmostEquals(stop00.stop_lon, 0.0, 5)
def test_gtfs_data(self): dao = Dao(DAO_URL, sql_logging=SQL_LOG) dao.load_gtfs(MINI_GTFS) # Check feed feed = dao.feed() self.assertTrue(feed.feed_id == "") self.assertTrue(feed.feed_publisher_name is None) self.assertTrue(feed.feed_publisher_url is None) self.assertTrue(feed.feed_contact_email is None) self.assertTrue(feed.feed_contact_url is None) self.assertTrue(feed.feed_start_date is None) self.assertTrue(feed.feed_end_date is None) self.assertTrue(len(dao.agencies()) == 1) self.assertTrue(len(dao.routes()) == 1) self.assertTrue(len(feed.agencies) == 1) self.assertTrue(len(feed.routes) == 1) # Check if optional route agency is set a = dao.agency("A") self.assertTrue(a is not None) self.assertTrue(len(a.routes) == 1) # Check for frequency-generated trips # They should all have the same delta trips = dao.trips(fltr=(Trip.frequency_generated == True), prefetch_stop_times=True) n_trips = 0 deltas = {} for trip in trips: original_trip_id = trip.trip_id.rsplit('@', 1)[0] delta1 = [] for st1, st2 in trip.hops(): delta1.append(st2.arrival_time - st1.departure_time) delta2 = deltas.get(original_trip_id) if delta2 is not None: self.assertTrue(delta1 == delta2) else: deltas[original_trip_id] = delta1 n_trips += 1 self.assertTrue(n_trips == 8)
def test_non_overlapping_feeds(self): dao = Dao(DAO_URL, sql_logging=SQL_LOG) # Load twice the same data under two distinct namespaces dao.load_gtfs(DUMMY_GTFS, feed_id='A') dao.load_gtfs(DUMMY_GTFS, feed_id='B') # Check that each feed only return it's own data feed_a = dao.feed('A') self.assertTrue(feed_a.feed_id == 'A') feed_b = dao.feed('B') self.assertTrue(feed_b.feed_id == 'B') self.assertTrue(len(dao.agencies()) == 4) self.assertTrue(len(feed_a.agencies) == 2) self.assertTrue(len(feed_b.agencies) == 2) self.assertTrue(len(feed_a.routes) * 2 == len(dao.routes())) self.assertTrue(len(feed_b.routes) * 2 == len(dao.routes())) self.assertTrue(len(feed_a.stops) * 2 == len(list(dao.stops()))) self.assertTrue(len(feed_b.stops) * 2 == len(list(dao.stops()))) self.assertTrue(len(feed_a.calendars) * 2 == len(dao.calendars())) self.assertTrue(len(feed_b.calendars) * 2 == len(dao.calendars())) self.assertTrue(len(feed_a.trips) * 2 == len(list(dao.trips()))) self.assertTrue(len(feed_b.trips) * 2 == len(list(dao.trips())))
def test_gtfs_data(self): dao = Dao(DAO_URL, sql_logging=False) dao.load_gtfs(DUMMY_GTFS) # Check feed feed = dao.feed() self.assertTrue(feed.feed_id == "") self.assertTrue(feed.feed_publisher_name == "Mecatran") self.assertTrue(feed.feed_publisher_url == "http://www.mecatran.com/") self.assertTrue(feed.feed_contact_email == "*****@*****.**") self.assertTrue(feed.feed_lang == "fr") self.assertTrue(len(dao.agencies()) == 2) self.assertTrue(len(dao.routes()) == 3) self.assertTrue(len(feed.agencies) == 2) self.assertTrue(len(feed.routes) == 3) # Check agencies at = dao.agency("AT") self.assertTrue(at.agency_name == "Agency Train") self.assertTrue(len(at.routes) == 1) ab = dao.agency("AB") self.assertTrue(ab.agency_name == "Agency Bus") self.assertTrue(len(ab.routes) == 2) # Check calendars week = dao.calendar("WEEK") self.assertTrue(len(week.dates) == 253) summer = dao.calendar("SUMMER") self.assertTrue(len(summer.dates) == 42) mon = dao.calendar("MONDAY") self.assertTrue(len(mon.dates) == 49) sat = dao.calendar("SAT") self.assertTrue(len(sat.dates) == 53) for date in mon.dates: self.assertTrue(date.dow() == 0) for date in sat.dates: self.assertTrue(date.dow() == 5) for date in week.dates: self.assertTrue(date.dow() >= 0 and date.dow() <= 4) for date in summer.dates: self.assertTrue(date >= CalendarDate.ymd(2016, 7, 1) and date <= CalendarDate.ymd(2016, 8, 31)) empty = dao.calendars(func.date(CalendarDate.date) == datetime.date(2016, 5, 1)) # OR USE: empty = dao.calendars(CalendarDate.date == "2016-05-01") self.assertTrue(len(empty) == 0) july4 = CalendarDate.ymd(2016, 7, 4) summer_mon = dao.calendars(func.date(CalendarDate.date) == july4.date) n = 0 for cal in summer_mon: self.assertTrue(july4 in cal.dates) n += 1 self.assertTrue(n == 3) # Check stops sbq = dao.stop("BQ") self.assertAlmostEqual(sbq.stop_lat, 44.844, places=2) self.assertAlmostEqual(sbq.stop_lon, -0.573, places=2) self.assertTrue(sbq.stop_name == "Bordeaux Quinconces") n = 0 for stop in dao.stops(Stop.stop_name.like("Gare%")): self.assertTrue(stop.stop_name.startswith("Gare")) n += 1 self.assertTrue(n == 7) n = 0 for stop in dao.stops(fltr=dao.in_area(RectangularArea(44.7, -0.6, 44.9, -0.4))): self.assertTrue(stop.stop_lat >= 44.7 and stop.stop_lat <= 44.9 and stop.stop_lon >= -0.6 and stop.stop_lon <= -0.4) n += 1 self.assertTrue(n == 16) for station in dao.stops(Stop.location_type == Stop.TYPE_STATION): self.assertTrue(station.location_type == Stop.TYPE_STATION) self.assertTrue(len(station.sub_stops) >= 2) for stop in station.sub_stops: self.assertTrue(stop.parent_station == station) # Check zones z_inexistant = dao.zone("ZX") self.assertTrue(z_inexistant is None) z1 = dao.zone("Z1") self.assertEquals(16, len(z1.stops)) z2 = dao.zone("Z2") self.assertEquals(4, len(z2.stops)) # Check transfers transfers = dao.transfers() self.assertTrue(len(transfers) == 3) transfers = dao.transfers(fltr=(dao.transfer_from_stop().stop_id == 'GBSJB')) self.assertTrue(len(transfers) == 1) self.assertTrue(transfers[0].from_stop.stop_id == 'GBSJB') # Check routes tgv = dao.route("TGVBP") self.assertTrue(tgv.agency == at) self.assertTrue(tgv.route_type == 2) r1 = dao.route("BR") self.assertTrue(r1.route_short_name == "R1") self.assertTrue(r1.route_long_name == "Bus Red") n = 0 for route in dao.routes(Route.route_type == 3): self.assertTrue(route.route_type == 3) n += 1 self.assertTrue(n == 2) # Check trip for route n = 0 trips = dao.trips(fltr=Route.route_type == Route.TYPE_BUS) for trip in trips: self.assertTrue(trip.route.route_type == Route.TYPE_BUS) n += 1 self.assertTrue(n > 20) # Check trips on date trips = dao.trips(fltr=func.date(CalendarDate.date) == july4.date, prefetch_calendars=True) n = 0 for trip in trips: self.assertTrue(july4 in trip.calendar.dates) n += 1 self.assertTrue(n > 30)
def _test_one_gtfs(self, gtfs): clear_mappers() dao = Dao(DAO_URL, sql_logging=SQL_LOG) dao.load_gtfs(gtfs) # Check stop time normalization and interpolation for trip in dao.trips(prefetch_stop_times=True): stopseq = 0 n_stoptimes = len(trip.stop_times) last_stop = None distance = trip.stop_times[0].shape_dist_traveled last_stoptime = None last_interpolated_speed = None for stoptime in trip.stop_times: self.assertTrue(stoptime.stop_sequence == stopseq) if stopseq == 0: self.assertTrue(stoptime.arrival_time is None) else: self.assertTrue(stoptime.arrival_time is not None) if stopseq == n_stoptimes - 1: self.assertTrue(stoptime.departure_time is None) else: self.assertTrue(stoptime.departure_time is not None) if last_stop is not None: distance += orthodromic_distance(last_stop, stoptime.stop) last_stop = stoptime.stop if trip.shape is not None: self.assertTrue(stoptime.shape_dist_traveled >= distance) else: self.assertAlmostEqual(stoptime.shape_dist_traveled, distance, 1) stopseq += 1 if stoptime.interpolated or (last_stoptime is not None and last_stoptime.interpolated): dist = stoptime.shape_dist_traveled - last_stoptime.shape_dist_traveled time = stoptime.arrival_time - last_stoptime.departure_time speed = dist * 1.0 / time if last_interpolated_speed is not None: self.assertAlmostEqual(speed, last_interpolated_speed, 2) last_interpolated_speed = speed if not stoptime.interpolated: last_interpolated_speed = None last_stoptime = stoptime # Get all hops hops = dao.hops() nhops = 0 for st1, st2 in hops: self.assertTrue(st1.stop_sequence + 1 == st2.stop_sequence) self.assertTrue(st1.trip == st2.trip) nhops += 1 # Get hops with a delta of 2 hops = dao.hops(delta=2) nhops2 = 0 for st1, st2 in hops: self.assertTrue(st1.stop_sequence + 2 == st2.stop_sequence) self.assertTrue(st1.trip == st2.trip) nhops2 += 1 ntrips = len(list(dao.trips())) # Assume all trips have len > 2 self.assertTrue(nhops == nhops2 + ntrips) # Test shape_dist_traveled on stoptimes for trip in dao.trips(): # Assume no shapes for now distance = 0.0 last_stop = None for stoptime in trip.stop_times: if last_stop is not None: distance += orthodromic_distance(last_stop, stoptime.stop) last_stop = stoptime.stop if trip.shape: self.assertTrue(stoptime.shape_dist_traveled >= distance) else: self.assertAlmostEqual(stoptime.shape_dist_traveled, distance, 2) # Test shape normalization for shape in dao.shapes(): distance = 0.0 last_pt = None ptseq = 0 for point in shape.points: if last_pt is not None: distance += orthodromic_distance(last_pt, point) last_pt = point self.assertAlmostEqual(point.shape_dist_traveled, distance, 2) self.assertTrue(point.shape_pt_sequence == ptseq) ptseq += 1 # Check zone-stop relationship for zone in dao.zones(prefetch_stops=True): for stop in zone.stops: self.assertTrue(stop.zone == zone) for stop in dao.stops(): if stop.zone: self.assertTrue(stop in stop.zone.stops)
def test_trip(self): dao = Dao() f1 = FeedInfo("F1") a1 = Agency("F1", "A1", "Agency 1", agency_url="http://www.agency.fr/", agency_timezone="Europe/Paris") r1 = Route("F1", "R1", "A1", 3, route_short_name="R1", route_long_name="Route 1") c1 = Calendar("F1", "C1") c1.dates = [ d for d in CalendarDate.range( CalendarDate.ymd(2016, 1, 1), CalendarDate.ymd(2016, 1, 31).next_day()) ] s1 = Stop("F1", "S1", "Stop 1", 45.0, 0.0) s2 = Stop("F1", "S2", "Stop 2", 45.1, 0.1) s3 = Stop("F1", "S3", "Stop 3", 45.2, 0.2) t1 = Trip("F1", "T1", "R1", "C1") t1.direction_id = 0 t11 = StopTime("F1", "T1", "S1", 0, 28800, 28800, 0.0) t12 = StopTime("F1", "T1", "S2", 1, 29400, 29400, 0.0) t13 = StopTime("F1", "T1", "S3", 2, 30000, 30000, 0.0) t2 = Trip("F1", "T2", "R1", "C1") t2.direction_id = 1 # Order is not important for now t2.stop_times.append(StopTime(None, None, "S1", 1, 31000, 31000, 0.0)) t2.stop_times.append(StopTime(None, None, "S2", 0, 30600, 30600, 0.0)) dao.add_all([f1, a1, r1, c1, s1, s2, s3, t1, t11, t12, t13, t2]) # Commit is needed to re-order stop times of T2 dao.commit() cal = dao.calendar("C1", feed_id="F1") for trip in cal.trips: self.assertTrue(trip.calendar.service_id == "C1") for stoptime in trip.stop_times: self.assertTrue(stoptime.trip.calendar.service_id == "C1") stop = dao.stop("S2", feed_id="F1") for stoptime in stop.stop_times: self.assertTrue(stoptime.stop.stop_id == "S2") self.assertTrue(stoptime.trip.trip_id.startswith("T")) trip = dao.trip("T1", feed_id="F1") self.assertTrue(len(trip.stop_times) == 3) trip = dao.trip("T2", feed_id="F1") self.assertTrue(len(trip.stop_times) == 2) for trip in dao.trips(prefetch_stop_times=True): last_stop_seq = -1 for stoptime in trip.stop_times: self.assertTrue(stoptime.stop_sequence > last_stop_seq) last_stop_seq = stoptime.stop_sequence for trip in dao.trips(): for stoptime1, stoptime2 in trip.hops(): self.assertTrue(stoptime1.trip == stoptime2.trip) self.assertTrue(stoptime1.stop_sequence + 1 == stoptime2.stop_sequence) trips = list(dao.trips(fltr=Trip.direction_id == 0)) self.assertTrue(len(trips) == 1) trips = list(dao.trips(fltr=Trip.direction_id == 1)) self.assertTrue(len(trips) == 1)
def _test_one_gtfs(self, gtfs): dao = Dao(DAO_URL, sql_logging=SQL_LOG) dao.load_gtfs(gtfs) # Check stop time normalization and interpolation for trip in dao.trips(prefetch_stop_times=True): stopseq = 0 n_stoptimes = len(trip.stop_times) last_stop = None distance = trip.stop_times[0].shape_dist_traveled last_stoptime = None last_interpolated_speed = None for stoptime in trip.stop_times: self.assertTrue(stoptime.stop_sequence == stopseq) if stopseq == 0: self.assertTrue(stoptime.arrival_time is None) else: self.assertTrue(stoptime.arrival_time is not None) if stopseq == n_stoptimes - 1: self.assertTrue(stoptime.departure_time is None) else: self.assertTrue(stoptime.departure_time is not None) if last_stop is not None: distance += orthodromic_distance(last_stop, stoptime.stop) last_stop = stoptime.stop if trip.shape is not None: self.assertTrue(stoptime.shape_dist_traveled >= distance) else: self.assertAlmostEqual(stoptime.shape_dist_traveled, distance, 1) stopseq += 1 if stoptime.interpolated or (last_stoptime is not None and last_stoptime.interpolated): dist = stoptime.shape_dist_traveled - last_stoptime.shape_dist_traveled time = stoptime.arrival_time - last_stoptime.departure_time speed = dist * 1.0 / time if last_interpolated_speed is not None: self.assertAlmostEqual(speed, last_interpolated_speed, 2) last_interpolated_speed = speed if not stoptime.interpolated: last_interpolated_speed = None last_stoptime = stoptime # Get all hops hops = dao.hops() nhops = 0 for st1, st2 in hops: self.assertTrue(st1.stop_sequence + 1 == st2.stop_sequence) self.assertTrue(st1.trip == st2.trip) nhops += 1 # Get hops with a delta of 2 hops = dao.hops(delta=2) nhops2 = 0 for st1, st2 in hops: self.assertTrue(st1.stop_sequence + 2 == st2.stop_sequence) self.assertTrue(st1.trip == st2.trip) nhops2 += 1 ntrips = len(list(dao.trips())) # Assume all trips have len > 2 self.assertTrue(nhops == nhops2 + ntrips) # Test shape_dist_traveled on stoptimes for trip in dao.trips(): # Assume no shapes for now distance = 0.0 last_stop = None for stoptime in trip.stop_times: if last_stop is not None: distance += orthodromic_distance(last_stop, stoptime.stop) last_stop = stoptime.stop if trip.shape: self.assertTrue(stoptime.shape_dist_traveled >= distance) else: self.assertAlmostEqual(stoptime.shape_dist_traveled, distance, 2) # Test shape normalization for shape in dao.shapes(): distance = 0.0 last_pt = None ptseq = 0 for point in shape.points: if last_pt is not None: distance += orthodromic_distance(last_pt, point) last_pt = point self.assertAlmostEqual(point.shape_dist_traveled, distance, 2) self.assertTrue(point.shape_pt_sequence == ptseq) ptseq += 1 # Check zone-stop relationship for zone in dao.zones(prefetch_stops=True): for stop in zone.stops: self.assertTrue(stop.zone == zone) for stop in dao.stops(): if stop.zone: self.assertTrue(stop in stop.zone.stops)