Is it possible to align the lable text of point layers perpendicular to the course of a polyline?
2 Answers
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
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
):
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:
-
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?– MarekMar 21 at 22:58
-
1
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.