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, )
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()