Esempio n. 1
0
 def choose_stop(rs: List[RouteSection]) -> Maybe[m.Stop]:
     if len(rs) == 0:
         return Nothing()
     elif len(rs) == 1:
         return Just(rs[0].s1)
     elif rs[0].s2 == rs[1].s1:
         return Just(rs[0].s2)
     else:
         return Just(rs[0].s1)
Esempio n. 2
0
def section_times(
    snapshots: List[Tuple[db.BusSnapshot, Dict[api.TimetableVariant,
                                               Set[int]]]],
    sections: Dict[api.TimetableVariant, List[RouteSection]],
) -> Dict[api.TimetableVariant, List[SectionTime]]:
    """Calculates entry and exit times for each section in snapshots.

    Arguments:
        snapshots: The bus snapshots, each with, for each timetable variant,
            the sections that snapshot falls in.
        sections: The sections in each timetable variant (in order).

    Returns:
        For each timetable variant, the route sections that were entered and
        exited in snapshots, in order of exit.
    """
    section_windows: Dict[api.TimetableVariant,
                          List[SectionTime]] = defaultdict(list)
    sections_entered: Dict[Tuple[api.TimetableVariant, int], EntryWindow] = {}
    last_positions: Dict[api.TimetableVariant, Set[int]] = {}
    last_time: Maybe[datetime] = Nothing()
    for snapshot, positions in snapshots:
        update_positions = False
        for variant, these_positions in positions.items():
            if not these_positions:
                continue
            else:
                update_positions = True
            for position in these_positions.difference(
                    last_positions.get(variant, set())):
                window = (last_time, Just(snapshot.poll_time))
                sections_entered[(variant, position)] = window
            for position in last_positions.get(
                    variant, set()).difference(these_positions):
                exit_interval = last_time, Just(snapshot.poll_time)
                section_time = SectionTime(
                    (position, sections_entered[(variant, position)],
                     exit_interval))
                section_windows[variant].append(section_time)
        for variant, old_positions in last_positions.items():
            if variant not in positions:
                for position in list(old_positions):
                    exit_interval = last_time, Just(snapshot.poll_time)
                    section_time = SectionTime(
                        (position, sections_entered[(variant, position)],
                         exit_interval))
                    section_windows[variant].append(section_time)
                    old_positions.remove(position)
        if update_positions:
            last_positions = positions
            last_time = Just(snapshot.poll_time)
    return section_windows
Esempio n. 3
0
 def estimate(arrival: StopArrival) -> Maybe[Tuple[datetime, datetime]]:
     if isinstance(arrival, SeenAtStop):
         return Just((arrival.first_at, arrival.last_at))
     elif isinstance(arrival, NotSeenAtStop):
         return arrival.last_before.bind(
             lambda before: arrival.first_after.map(lambda after: before + (
                 (after - before) / 2)).map(lambda a: (a, a)))
Esempio n. 4
0
def route_sections(
    stops: Iterable[m.Stop],
    rectangle_width: float = 0.001,
    circle_radius: float = 0.001,
) -> Iterator[RouteSection]:
    def shapes() -> Iterator[RouteSection]:
        for s1, s2 in pairwise(stops):
            yield make_circle(s1, circle_radius)
            yield make_rectangle(s1, s2, rectangle_width)
        yield make_circle(s2, circle_radius)

    for section1, section2, section3 in drop(
            1,
        (tuplewise_padded(3,
                          (Just(x) for x in shapes()), pad_value=Nothing()))):
        if isinstance(section2, Just):
            if isinstance(section2.value, RoadSection):
                if isinstance(section1, Just) and isinstance(
                        section1.value, StopCircle):
                    section2 = section2.value.difference(section1.value)
                if isinstance(section3, Just) and isinstance(
                        section3.value, StopCircle):
                    section2 = section2.bind(
                        lambda s: s.difference(section3.value))
        if isinstance(section2, Just):
            yield section2.value
Esempio n. 5
0
def timetable(
    timetable_id: int, connection: Maybe[connection] = Nothing()
) -> Either[str, Timetable]:
    with connection.or_else_lazy(default_connection) as conn:
        with conn.cursor() as cursor:
            cursor.execute(
                """
                select caption from timetables
                where id = %s
                """,
                [timetable_id],
            )
            result = cursor.fetchone()
            if result is None:
                return Left(f"Timetable {timetable_id} not in database")
            caption = result[0]
            cursor.execute(
                """
                select id from timetable_variants
                where timetable_id = %s
                """,
                [timetable_id],
            )
            variants = (timetable_variant(id, Just(conn))
                        for (id, ) in cursor.fetchall())
            return Right(
                Timetable(caption,
                          {v.value
                           for v in variants if isinstance(v, Right)}))
Esempio n. 6
0
 def cell_time(t: Tag) -> Maybe[time]:
     contents = "".join([s for s in t.stripped_strings])
     if contents.endswith("[+1]"):
         contents = contents[:-4]
     try:
         return Just(time.fromisoformat(contents))
     except ValueError:
         return Nothing()
Esempio n. 7
0
def match_stop_name(stops: Dict[str, Stop], name: str) -> Maybe[Stop]:
    name = name.strip()
    if name == "Cork Railway Station (Kent)":
        name = "Kent Rail Station (Horgans Quay)"
    prefixes: Iterable[str] = chain([name],
                                    takewhile(lambda s: s != "",
                                              iterate(lambda s: s[:-1], name)))
    for p in prefixes:
        if p in stops:
            return Just(stops[p])
    return Nothing()
Esempio n. 8
0
def timetables(
    route: RouteId, connection: Maybe[connection] = Nothing()
) -> Iterator[Either[str, Timetable]]:
    """Gets the timetables for a specific route from the database."""
    with connection.or_else_lazy(default_connection) as conn:
        with conn.cursor() as cursor:
            cursor.execute(
                """
                select timetable from route_timetables
                where route = %s
                """,
                [route.raw],
            )
            for (timetable_id, ) in cursor.fetchall():
                yield timetable(timetable_id, Just(conn))
Esempio n. 9
0
 def difference(self, circle: StopCircle) -> Maybe[RoadSection]:
     new_polygon = self.polygon.difference(circle.polygon)
     if isinstance(new_polygon, sg.Polygon):
         return Just(RoadSection(monkey_patch_polygon(new_polygon)))
     else:
         return Nothing()
Esempio n. 10
0
 def from_my_json(j: MyPassageJson) -> Passage:
     return Passage(
         id=Just(PassageId(cast(str, j["id"]))),
         last_modified=Just(
             datetime.fromisoformat(cast(str, j["last_modified"]))),
         trip=Just(TripId(cast(str, j["trip_id"]))),
         route=Just(RouteId(cast(str, j["route_id"]))),
         vehicle=Just(VehicleId(cast(str, j["vehicle_id"]))),
         stop=Just(StopId(cast(str, j["stop_id"]))),
         pattern=Just(PatternId(cast(str, j["pattern_id"]))),
         latitude=Just(cast(int, j["latitude"])),
         longitude=Just(cast(int, j["longitude"])),
         bearing=Just(cast(int, j["bearing"])),
         time=PassageTime.from_json(cast(MyPassageTimeJson, j["time"])),
         is_deleted=Just(cast(bool, j["is_deleted"])),
         is_accessible=Just(cast(bool, j["is_accessible"])),
         has_bike_rack=Just(cast(bool, j["has_bike_rack"])),
         direction=Just(cast(int, j["direction"])),
         congestion=Just(cast(int, j["congestion"])),
         accuracy=Just(cast(int, j["accuracy"])),
         status=Just(cast(int, j["status"])),
         category=Just(cast(int, j["category"])),
     )