These days I've found very difficult to position my label points parallel to lines such as rivers and streets.

I have these two shapefiles, one is the point shape with names and the other is the polygon shape with the Streets.

This is the visualization:

enter image description here

Then when I'm trying to align the "Name" of the street parallel to the "Street" Shape with the label settings and there is no option to do it.

The result I am expecting is something like this:

enter image description here

Can anyone help me on this?

  • Welcome to GIS.SE! So obviously you have more than one label per line? How much lines do you have? And is manually placing/rotating the labels an option? And is your data in a database or do you have shapefiles or sth. like that? – Jochen Schwarze May 9 '17 at 8:03

This seems a data management problem for me at first sight. I strongly doubt if it's good practice to have n labels for a distinct line in form of point dataset (seems like a Smallworld approach for me, and if so, i think there must be an attribute for the text_rotation somewhere ...).

Some possible approaches:

a) If you really want to label your points automatically, the task would be to derive the orientation of the nearest line segment to each point, store this in an attribute and make use of 'data defined override' for the rotation of point labels (if you still don't have it, see above).

b) If you do not have too much data, you may consider placing the labels manually, refer to https://www.youtube.com/watch?v=JNQCaT9GH7A or Move label in QGIS? for example or g**** for 'qgis move labels'

c) My favourite solution would be an additional attribute to your linestings containing the road name, with very many blanks in between the words, then use placement option 'curved' to place the label as you desire. The result will look sth. like

enter image description here

  • Hi Jochen, That's very clear but I have to shapefiles, one containing the text and the other the streets: – Buben May 9 '17 at 11:41

To make it look good, keep data consistent etc. the best answer was already given by Jochen.

With that said there a possible solution might be to rotate the labels according to the current rotation of the line close to your point label. The result will however depend on:

  • how many shifts in directions /curves are in you lines
  • the scale: due to cartographic generalization (smoothing) of the line at smaller scales some curves may no be visible any more, but you labels are still rotated according to that curve...

How to do it:

  1. Determine where you point labels are relative to the length of the line, e.g. at the start of the line, right in the middle of the line etc...
  2. You can calculate the line angle at that point with the field calculator formula 'line_interpolate_angle'
  3. For this you need to get the geometry of the line features and you need the position (length in line - see 1.) of the point labels
  4. The result of the formula 'line_interpolate_angle' are the angles from 0-360° (North-East-South-West). You need to transform these angles to the label rotation system which works from -180° to 0° to +180° (0° is horizontal)


With the given layers:

  • road_lines
  • point_labels


  • connecting ID field with the same unique value for each feature in each layer, here: 'road_lines_ID' and 'road_point_ID'
  • assuming all the point labels are at 50% length of your lines.

Set the rotation of the labels of the "point_labels" layer in: Properties>Labels>Placement>Data defined>Rotation>'Edit' Enter the following formula:

((((((line_interpolate_angle(geometry( get_feature( 'road_lines','road_lines_ID', "road_point_ID" )), distance:= ( length(geometry( get_feature( 'road_lines','road_lines_ID', "road_point_ID" )))/2)))+270)%360)+180)%360)-180)*-1

To speed things up you can also calculate a field in the point_labels layer with the given formula and rotate the labels according to the calculated field value.

Result: (Depending on the zoom level the result can be like this: enter image description here

Formula in detail:

  • line_interpolate_angle(geometry, distance) : gets the angel/direction of the line at a certain length
  • geometry( get_feature( 'road_lines','road_lines_ID', "road_point_ID" )): gets the corresponding 'ID' feature from road_lines
  • distance:= ( length(geometry( get_feature( 'road_lines','road_lines_ID', "road_point_ID" )))/2): get the distance along the line, where the label is place --> here /2 --> at 50% of the lines length.
  • )+270)%360)+180)%360)-180)*-1: transfer from 0-360° (0 = north) system to -180 to +180° (0 = horizontal) system

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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