def draw_crossing_lines(ctx, frame: Polygon):
    """Draw a crossing area for pedestrian, which is only marked by dashed lines, in the
    given frame.

    The dashed lines are perpendicular to the road.

    Args:
        frame: Frame of the crossing area.
            **Points of the frame must be given in the right order!**
            first point : start on left line
            second point: end on left line
            third point : end on right line
            fourth point: start on right line
    """
    points = frame.get_points()
    dash_length = 0.04
    utils.draw_line(
        ctx,
        MarkedLine(
            [points[0], points[3]],
            style=RoadSection.DASHED_LINE_MARKING,
        ),
        dash_length=dash_length,
    )
    utils.draw_line(
        ctx,
        MarkedLine(
            [points[1], points[2]],
            style=RoadSection.DASHED_LINE_MARKING,
        ),
        dash_length=dash_length,
    )
def draw_start_lane(ctx, frame: Polygon):
    """Draw the checkerboard pattern to mark the beginning of a parking area in the given
    frame.

    Args:
        frame: Frame of the start lane.
            **Points of the frame must be given in the right order!**
            first point : start on left line
            second point: end on left line
            third point : end on right line
            fourth point: start on right line
    """
    TILE_LENGTH = 0.02

    points = frame.get_points()
    left = Line([points[0], points[1]])
    right = Line([points[3], points[2]])
    for i in range(3):
        utils.draw_line(
            ctx,
            MarkedLine(
                [
                    left.interpolate(TILE_LENGTH * (i + 0.5)),
                    right.interpolate(TILE_LENGTH * (i + 0.5)),
                ],
                style=RoadSection.DASHED_LINE_MARKING,
                prev_length=(i % 2 + 0.5) * TILE_LENGTH,
            ),
            dash_length=TILE_LENGTH,
        )
Пример #3
0
    def render_to_file(self, roads_path: str):
        """Render an image of the tile and save it to a file.

        Args:
            roads_path: Directory in which all roads are located.
        """
        surface = cairo.ImageSurface(cairo.FORMAT_RGB24,
                                     int(self.resolution.x),
                                     int(self.resolution.y))
        ctx = cairo.Context(surface)

        # Adjust scale
        ctx.scale(self.resolution.x / self.size.x,
                  self.resolution.y / self.size.y)
        # Inverse y-axis
        ctx.translate(0, self.size.y / 2)
        ctx.scale(1, -1)
        ctx.translate(0, -self.size.y / 2)

        # Move to center of the tile
        ctx.translate(self.size.x / 2, self.size.y / 2)

        # Create black background
        ctx.set_source_rgb(0, 0, 0)
        ctx.rectangle(0, 0, self.size.x, self.size.y)
        ctx.fill()

        # Invert the render transform
        ctx.translate(-self.transform.translation.x,
                      -self.transform.translation.y)

        # Draw lines for all sections
        for sec in self.sections.values():
            for line in sec.lines:
                utils.draw_line(ctx, line)
            for marking in sec.surface_markings:
                render_surface_markings.draw(ctx, marking)

        sha_256 = hashlib.sha256()
        sha_256.update(surface.get_data())
        hash = sha_256.hexdigest()

        self.id = f"tile-{hash}"

        dir = os.path.join(roads_path, self.road_folder_name, self.id)
        if not os.path.exists(dir):
            try:
                os.makedirs(dir)
            except OSError as exc:  # Guard against race condition
                if exc.errno != errno.EEXIST:
                    raise

        surface.write_to_png(os.path.join(dir, self.id + ".png"))

        with open(os.path.join(dir, self.id + ".material"), "w+") as file:
            file.write(self.get_material_string())
def draw_parking_spot_x(ctx, frame: Polygon):
    points = frame.get_points()
    utils.draw_line(
        ctx,
        MarkedLine([points[0], points[2]],
                   style=RoadSection.SOLID_LINE_MARKING))
    utils.draw_line(
        ctx,
        MarkedLine([points[1], points[3]],
                   style=RoadSection.SOLID_LINE_MARKING))
def draw(ctx, surface_marking: SurfaceMarking):
    ctx.save()

    if (surface_marking.kind == SurfaceMarking.LEFT_TURN_MARKING
            or surface_marking.kind == SurfaceMarking.RIGHT_TURN_MARKING):
        ctx.translate(surface_marking.center.x, surface_marking.center.y)
        ctx.rotate(surface_marking.orientation)
        image_file = os.path.join(
            os.environ.get("KITCAR_REPO_PATH"),
            "kitcar-gazebo-simulation",
            "simulation",
            "models",
            "meshes",
            f"Fahrbahnmarkierung_Pfeil_" + (
                "L" if surface_marking.kind !=
                SurfaceMarking.LEFT_TURN_MARKING  # Weird
                else "R") + ".svg",
        )
        svg = Rsvg.Handle().new_from_file(image_file)
        ctx.scale(0.001, 0.001)
        svg.render_cairo(ctx)

    if (surface_marking.kind == SurfaceMarking.GIVE_WAY_LINE
            or surface_marking.kind == SurfaceMarking.STOP_LINE):
        ctx.translate(surface_marking.center.x, surface_marking.center.y)
        ctx.rotate(surface_marking.orientation)

        v = 0.5 * Vector(surface_marking.width, 0)
        line = MarkedLine(
            [-1 * v, v],
            style=(RoadSection.DASHED_LINE_MARKING
                   if surface_marking.kind == SurfaceMarking.GIVE_WAY_LINE else
                   RoadSection.SOLID_LINE_MARKING),
        )

        utils.draw_line(
            ctx,
            line,
            line_width=0.04,
            dash_length=0.08,
            dash_gap=0.06,
        )
    if surface_marking.kind == SurfaceMarking.START_LINE:
        draw_start_lane(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.ZEBRA_CROSSING:
        draw_zebra_crossing(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.PARKING_SPOT_X:
        draw_parking_spot_x(ctx, surface_marking.frame)

    ctx.restore()
def draw_start_lane(ctx, frame: Polygon):
    TILE_LENGTH = 0.02

    points = frame.get_points()
    left = Line([points[0], points[1]])
    right = Line([points[3], points[2]])
    for i in range(3):
        utils.draw_line(
            ctx,
            MarkedLine(
                [
                    left.interpolate(TILE_LENGTH * (i + 0.5)),
                    right.interpolate(TILE_LENGTH * (i + 0.5)),
                ],
                style=RoadSection.DASHED_LINE_MARKING,
                prev_length=(i % 2 + 0.5) * TILE_LENGTH,
            ),
            dash_length=TILE_LENGTH,
        )
def draw_parking_spot_x(ctx, frame: Polygon):
    """Draw two crossing lines (X) in the given frame to represent a blocked spot.

    Args:
        frame: Frame of the parking spot.
            **Points of the frame must be given in the right order!**
            first point : left lower corner of parking spot
            second point: left upper corner
            third point : right upper corner
            fourth point: right lower corner
    """
    points = frame.get_points()
    utils.draw_line(
        ctx,
        MarkedLine([points[0], points[2]],
                   style=RoadSection.SOLID_LINE_MARKING))
    utils.draw_line(
        ctx,
        MarkedLine([points[1], points[3]],
                   style=RoadSection.SOLID_LINE_MARKING))
def draw(ctx, surface_marking: SurfaceMarking):
    ctx.save()

    if (surface_marking.kind == SurfaceMarking.LEFT_TURN_MARKING
            or surface_marking.kind == SurfaceMarking.RIGHT_TURN_MARKING):
        ctx.translate(surface_marking.center.x, surface_marking.center.y)
        ctx.rotate(surface_marking.orientation)
        # Translate to left upper corner of png
        ctx.translate(
            surface_marking.depth / 2,
            -surface_marking.width / 2,
        )
        # Then rotate by 90 degrees to align png properly!
        ctx.rotate(math.pi / 2)
        image_file = os.path.join(
            os.environ.get("KITCAR_REPO_PATH"),
            "kitcar-gazebo-simulation",
            "simulation",
            "models",
            "meshes",
            "surface_marking_turn_" +
            ("left" if surface_marking.kind != SurfaceMarking.LEFT_TURN_MARKING
             else "right") + ".png",
        )
        img = cairo.ImageSurface.create_from_png(image_file)
        ctx.scale(0.001, 0.001)
        ctx.set_source_surface(img, 0, 0)
        ctx.paint()

    if (surface_marking.kind == SurfaceMarking.GIVE_WAY_LINE
            or surface_marking.kind == SurfaceMarking.STOP_LINE):
        ctx.translate(surface_marking.center.x, surface_marking.center.y)
        ctx.rotate(surface_marking.orientation)

        v = 0.5 * Vector(0, surface_marking.width)
        line = MarkedLine(
            [-1 * v, v],
            style=(RoadSection.DASHED_LINE_MARKING
                   if surface_marking.kind == SurfaceMarking.GIVE_WAY_LINE else
                   RoadSection.SOLID_LINE_MARKING),
        )

        utils.draw_line(
            ctx,
            line,
            line_width=0.04,
            dash_length=0.08,
            dash_gap=0.06,
        )
    if surface_marking.kind == SurfaceMarking.START_LINE:
        draw_start_lane(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.ZEBRA_CROSSING:
        draw_zebra_crossing(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.PARKING_SPOT_X:
        draw_parking_spot_x(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.BLOCKED_AREA:
        draw_blocked_area(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.ZEBRA_LINES:
        draw_crossing_lines(ctx, surface_marking.frame)
    if surface_marking.kind == SurfaceMarking.TRAFFIC_ISLAND_BLOCKED:
        draw_traffic_island_blocked(ctx, surface_marking.frame)
    if surface_marking.kind[1].startswith("ZONE_"):
        _, limit, type = surface_marking.kind[1].split("_")
        draw_speed_limit(ctx, surface_marking, limit, type.lower() == "start")

    ctx.restore()