9

I'm trying to obtain the same label style than Perpendicular Placement Orientation from ArcGIS in QGIS. As QGIS doesn't have this feature as default, the option would be using custom placement for this.

An ArcGIS example:

enter image description here

A workaround in QGIS

Settings:

Data defined coordinate X (label in the middle of he line):

$x_at( num_points( $geometry)/2)

Data defined coordinate Y (same as X's location):

$y_at( num_points( $geometry)/2)

Data defined Rotation:

angle_at_vertex( $geometry , num_points( $geometry)/2)

enter image description here

For only for 2/3 labels, the placement is acceptable. For lines with a lot of breaks with different angles, it's more difficult to obtain a nice label.

ArcGIS seems to search the line segment with fewer breaks or a straight segment. Is there a way to obtain coordinates or geometry of the straightest line segment using Expression builder for a better label placement?

4
  • how about taking an average of the angles at several vertices
    – csk
    Jan 22, 2018 at 18:06
  • @csk I've tried with line_interpolate_angle($geometry, some lenght) and taking several angle_at_vertex( $geometry , num_points( $geometry)). A loop over this function could be an aproach, but I can't do it directly in Expresion builder
    – aldo_tapia
    Jan 22, 2018 at 18:11
  • it seems you want to find a section of the line where the angle at each vertex is approximately equal to the line_interpolate_angle
    – csk
    Jan 22, 2018 at 18:21
  • @csk yes, something like that. A straight line segment to place labels
    – aldo_tapia
    Jan 22, 2018 at 18:24

1 Answer 1

2

Actual workaround

Suppose this kind of geometries:

enter image description here

I tried to find a good placement. I'm working with atlas also, so I used a 3% distance of atlas feature from the mid part of the interpolation line per feature's vertices to place labels:

Something like this:

enter image description here

And I create an arrow from the feature's middle vertex to the label:

enter image description here


Settings:

Arrow:

Geometry generator

make_line(make_point($x_at( num_points( $geometry)/2) , $y_at( num_points( $geometry)/2)),
  project( line_interpolate_point(make_line(make_point($x_at(1),$y_at(1)),make_point($x_at(-1),$y_at(-1))),
  length(make_line(make_point($x_at(1),$y_at(1)),make_point($x_at(-1),$y_at(-1))))/2),length(@atlas_geometry)*0.03,
   (radians(line_interpolate_angle(make_line(make_point($x_at(1),$y_at(1)),make_point($x_at(-1),$y_at(-1))),
  0.0001)))+ pi() *0.5))

Label

Data define X

x(project( line_interpolate_point(make_line(make_point($x_at(1),
  $y_at(1)),make_point($x_at(-1),$y_at(-1))),
  length(make_line(make_point($x_at(1),$y_at(1)),
  make_point($x_at(-1),$y_at(-1))))/2),length(@atlas_geometry)*0.03,
   (radians(line_interpolate_angle(make_line(make_point($x_at(1),
  $y_at(1)),make_point($x_at(-1),$y_at(-1))),0.0001)))+ pi() *0.5))

Data define Y

y(project( line_interpolate_point(make_line(make_point($x_at(1),
  $y_at(1)),make_point($x_at(-1),$y_at(-1))),
  length(make_line(make_point($x_at(1),$y_at(1)),
  make_point($x_at(-1),$y_at(-1))))/2),length(@atlas_geometry)*0.03,
   (radians(line_interpolate_angle(make_line(make_point($x_at(1),
  $y_at(1)),make_point($x_at(-1),$y_at(-1))),0.0001)))+ pi() *0.5))

Maybe this could be helpful for someone.

If there is a better approach, glad to receive it.

Your Answer

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

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