Ejemplo n.º 1
0
 def __init__(self, code, name, offset, relative_to=None):
     self.code = code
     self.name = name
     self._offset = offset
     self.relative_to = relative_to
     self.platforms = SortedDict()
     self.placed = SortedDict()
     self.label_direction = None
     self.label_offset = Vector(0, 0)
Ejemplo n.º 2
0
    def load(self, filename):
        self.stations = SortedDict()
        self.lines = SortedDict()
        self.extents = [0, 0, 0, 0]
        self.outbounds = []
        draw_last = []
        draw_first = []
        with open(filename) as fh:
            for lineno, line in enumerate(fh):
                line = line.strip()
                if line and line[0] != "#":
                    # Get the parts
                    parts = line.split()
                    type, parts = parts[0], parts[1:]
                    # What kind of line is it?
                    if type == "line":
                        # Line definition
                        code = parts[0]
                        colors = [(
                            int(part[0:2], 16) / 255.0,
                            int(part[2:4], 16) / 255.0,
                            int(part[4:8], 16) / 255.0,
                        ) for part in parts[1].split(",")]
                        self.lines[code] = Line(code, colors)

                    # Track segment
                    elif type in ("track", "subtrack"):
                        # It's a station-to-station description
                        station_code, platform_number = parts[0].split("-", 1)
                        dest_code, dest_number = parts[1].split("-", 1)
                        station = self.stations[station_code]
                        # Check for reverses
                        leaves_start = False
                        if platform_number[-1] == "!":
                            leaves_start = True
                            platform_number = platform_number[:-1]
                        finishes_end = False
                        if dest_number[-1] == "!":
                            finishes_end = True
                            dest_number = dest_number[:-1]
                        # Add it
                        try:
                            self.add_outbound(
                                station.platforms[platform_number],
                                self.stations[dest_code].
                                platforms[dest_number],
                                self.lines[parts[2]],
                                leaves_start=leaves_start,
                                finishes_end=finishes_end,
                                subtrack=(type == "subtrack"),
                            )
                        except:
                            print "Error context: %s, %s" % (station, parts)
                            raise

                    # Station/waypoint record
                    elif type in ("station", "waypoint", "depot", "sidings",
                                  "disstation"):
                        # It's a station or points definition
                        code = parts[0]
                        index = 1
                        while "," not in parts[index]:
                            index += 1
                        name = " ".join(parts[1:index])
                        # Work out the coordinates
                        coord_parts = parts[index].split(",")
                        coords = Vector(*map(float, coord_parts[-2:])) * 10
                        if len(coord_parts) == 3:
                            relative_to = self.stations[coord_parts[0]]
                        else:
                            relative_to = None
                        if type == "station":
                            station_class = Station
                        elif type == "depot":
                            station_class = Depot
                        elif type == "sidings":
                            station_class = Sidings
                        elif type == "disstation":
                            station_class = DisusedStation
                        else:
                            station_class = Points
                        last_station = self.stations[code] = station_class(
                            code,
                            name,
                            coords,
                            relative_to=relative_to,
                        )
                        self.extents[0] = min(coords.x, self.extents[0])
                        self.extents[1] = max(coords.x, self.extents[1])
                        self.extents[2] = min(coords.y, self.extents[2])
                        self.extents[3] = max(coords.y, self.extents[3])

                    # Platform record
                    elif type == "platform":
                        # Add a platform to the last station
                        direction = getattr(Direction, parts[1])
                        try:
                            line = self.lines[parts[2]]
                        except (IndexError, KeyError):
                            line = self.lines["error"]
                        try:
                            platform_side_code = parts[3]
                            platform_side = {
                                "L": Segment.PLATFORM_LEFT,
                                "R": Segment.PLATFORM_RIGHT,
                                "B": Segment.PLATFORM_BOTH,
                                "N": Segment.PLATFORM_NONE,
                            }[platform_side_code.upper()]
                        except IndexError:
                            platform_side = Segment.PLATFORM_BOTH
                        self.stations[code].add_platform(
                            parts[0], direction, line, platform_side)

                    # Drawing order modifiers
                    elif type == "draw":
                        if parts[0] == "first":
                            draw_first.append(last_station)
                        elif parts[0] == "last":
                            draw_last.append(last_station)
                        else:
                            raise ValueError("Unknown draw position %r" %
                                             parts[0])

                    # Label placement modifiers
                    elif type == "label":
                        last_station.label_direction = getattr(
                            Direction, parts[0])
                    elif type == "label_offset":
                        last_station.label_offset = Vector(
                            map(int, parts[0].split(",")))

                    # Unknown
                    else:
                        raise ValueError("Unknown line type %r" % type)
        # Now reorder those with special draw clauses
        for station in draw_first:
            self.stations.insert(0, station.code, station)
        for station in draw_last:
            self.stations.insert(len(self.stations), station.code, station)