7

Is it possible to align the lable text of point layers perpendicular to the course of a polyline?

enter image description here

2 Answers 2

13

The solution

Use a data defined override for the label rotation, based on the azimuth of the line at the line segment next to the point. To do so, use this expression in the Label setting's Placement tab > Rotation (see screenshot) to create parallel lines. For perpendicular ones, simply delete +90 at the end of the expression:

with_variable(
    'line',  
    overlay_nearest ('line', $geometry)[0], -- replace line with the name of your line layer
    line_interpolate_angle ( 
        @line,
        line_locate_point ( 
            @line,
            closest_point (@line, $geometry)
        )
    )
) + 90

enter image description here


Refining the solution: offset

To offset the label from the line, in label placement tab, activate Geometry Generator to create a buffer around the line and the point to define the area in which the label can be placed. Add this expression and replace 20000 and 8000 by values that fit your needs (see screenshot below):

difference (
    buffer ($geometry, 20000),
    buffer(
        overlay_nearest ('line', $geometry)[0],
        8000
    )
)

Blue buffer just for visualization: radius of the blue circle around the points corresponds to the first value (20000 in the example above), white area cut out from the blue circles corresponds to the buffer around the line, the second value (8000): enter image description here

Further options

On which side of the line the label appears depends on the line direction - normally, they appear on the left side of the line. However, you can create an attribute side with 1 (positive value, for default: left side) and -1 (negative value, override: right side). Then you can create single sided buffers and define for each point on which side the label should be:

intersection  (
    buffer ($geometry, 30000),
    difference (
        single_sided_buffer(
            overlay_nearest ('line', $geometry)[0],
            25000 * "side"
        ),
        single_sided_buffer(
            overlay_nearest ('line', $geometry)[0],
            8000 * "side"
        )
    )
)

This creates label placed in the blue areas (these, again, are added just for demonstration purpose); an additional label shows 1/-1 values that decide on which side of the line the label is placed:

enter image description here

2
  • For a perpendicular alignment it must be +180, I assume? When I define the offset in the quadrant to be right from the center the offset is very small. changing x and y values hast a bad effect depending on the rotation of the polyline, so I helped myself by adding textspace between the label value and the point (' ' || "Piontlabelvalue"). or is there a better approach?
    – Marek
    Commented Mar 21, 2023 at 22:58
  • 1
    See updated solution that creates what you want.
    – Babel
    Commented Mar 22, 2023 at 8:04
5

I suggest you split your line into segments (either extract vertices, then split lines at points, or subdivide with 2 vertices per segment), then add the azimuth() to the segments, then join attributes by nearest to add the azimuth values of your line segments to the points, and finally use data defined override to rotate your labels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.