2

QGIS 3.8, Win 10. I have labels that are connected with the points they represent with a leader-line. The line is generated with geometry generator (going from the point-layer to the position where I placed the labels manually):

make_line(make_point($x,$y), make_point( "auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony" ))

The line sometimes continues below the label. How is it possible to shorten the line so that it stops when it touches the label? I tried to mask it with text-buffers. However, this is not an option here (see the link to see why). Changing horizontal/vertical alignement is also no option since I have labels clockwise around a circle - so if it would fix the problem for some of the labels, the problem would consist on the opposit site.

I tried the expression extend with negative value, but it seems it accepts only positive values, making the line longer. I look for a function that is a counterpart-expression (someting like shorten) - how to achieve this?

enter image description here

3
  • 2
    It's not a direct answer - but qgis 3.10 includes native callout support which doesn't suffer this issue.
    – ndawson
    Sep 23, 2019 at 9:27
  • You can try something like this: difference(make_line(make_point($x,$y), buffer(make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony",0.001)))) modify 0.001 based on your needs.
    – ahmadhanb
    Sep 23, 2019 at 9:38
  • @ahmadhanb: the expression does not work. I guess it is because the syntax of make_line expects two points - with buffer(), you don't get a point, but the buffer of a point (thus something like a polygon, I guess)?
    – Babel
    Sep 23, 2019 at 9:41

2 Answers 2

5

Thanks to ahmadhanb's proposal, I found a solution, using the intersection-function to create a point where the line intersects the buffer. Expression looks scary, however is not so complicated to understand:

make_line(($geometry),make_point(x ( intersection(  (buffer  (make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony"), 0.25)), (make_line(make_point($x,$y), make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony"))))), y( intersection(  (buffer  (make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony"), 0.25)), (make_line(make_point($x,$y), make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony")))))))

Looking for QGIS 3.10!

Edited: found yet another way to accomplish the same aim: duplicate the layer with the points/labels, so that there are two identical layers. The first layer (on top) shows only the points and the label (inscription). The last layer (no. 2, at the bottom) shows the line only, created with geometry-generator: no points, no labels. On the top layer, the layer-background-tab is set to show a background (or again using text-buffer). It is this background or buffer that masks the line in the layer below.

0
2

Similar but different from @Babel answer: for if you are trying to create separation between a feature (be it a point, line or polygon) and the leader line:

Here is a working code for making a leader line that has good separation (3500m) from the point feature it points to; this was useful for me to ensure the leader line arrow was not interfering with my point symbology.

   make_line(
    make_point(
    x (intersection(
    buffer(make_point($x,$y), 3500),
    (make_line(make_point($x,$y), make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony"))))) ,
    y( intersection(
    buffer(make_point($x,$y), 3500),
    make_line(make_point($x,$y), make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony"))))) ) ,
    make_point("auxiliary_storage_labeling_positionx" , "auxiliary_storage_labeling_positiony")
    )

Here's colour code to make it more clear what's happening: leader_line_length_example

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.