def __init__(self, shape): self._shape = shape self._cache = _CacheEntry(None) self._cache_hit = 0 self._cache_miss = 0 if all(pt.shape_dist_traveled != -999999 for pt in shape.points): self._xdist = ContinousPiecewiseLinearFunc() else: self._xdist = None # Normalize the shape here: # 1) dist_traveled to meters # 2) pt_seq to contiguous numbering from 0 ptseq = 0 distance_meters = 0.0 last_pt = None shape.points.sort(key=lambda p: p.shape_pt_sequence) for pt in shape.points: if last_pt is not None: # Note: we do not use distance cache, as most probably # many of the points will be different from each other. distance_meters += orthodromic_distance(last_pt, pt) last_pt = pt pt.shape_pt_sequence = ptseq old_distance = pt.shape_dist_traveled pt.shape_dist_traveled = distance_meters # Remember the distance mapping for stop times if self._xdist: self._xdist.append(old_distance, pt.shape_dist_traveled) ptseq += 1
def test_distance(self): a = SimplePoint(0, 0) b = SimplePoint(1, 0) c = SimplePoint(0, 1) self.assertAlmostEqual(orthodromic_distance(a, a), 0.0, 3) dab = orthodromic_distance(a, b) dac = orthodromic_distance(a, c) dbc = orthodromic_distance(b, c) self.assertAlmostEqual(dab, dac, 3) # This is the definition of the nautical mile self.assertAlmostEqual(dab / 60, self._NAUTICAL_MILE, 2) # Spherical triangular inequality self.assertTrue(dab * dab + dac * dac > dbc * dbc) d = SimplePoint(90, 0) e = SimplePoint(0, 90) dad = orthodromic_distance(a, d) dae = orthodromic_distance(a, e) dde = orthodromic_distance(d, e) self.assertAlmostEqual(dad, dae, 3) self.assertAlmostEqual(dae, dde, 3) self.assertAlmostEqual(dad, dde, 3) f = SimplePoint(45, 0) daf = orthodromic_distance(a, f) self.assertAlmostEqual(daf * 2, dad, 3) g = SimplePoint(45.0001, 0) h = SimplePoint(45, 0.0001) dfg = orthodromic_distance(f, g) dfh = orthodromic_distance(f, h) dgh = orthodromic_distance(g, h) self.assertAlmostEqual(dfg * math.cos(math.radians(45)), dfh, 3) # Not perfectly equals, but for small distance should hold self.assertAlmostEqual(dfg * dfg + dfh * dfh, dgh * dgh, 2)
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_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)