2

I have labelled a points layer by defining a line between points and labels, so as I could remove the label to outside the map area (Figure 1). Using additional columns in the points layer attributes table (x and y), I can move the labels manually.

To make a line from the point to the label, I have added a 'Geometry Generator' in the Style section of the layer's Properties dialog. To define the geometry generator, I have used the following expression where $x and $y are the features' coordinates and "x" and"y" are the labels' coordinates:

make_line(make_point($x,$y),make_point("x","y")).

My issue is that labels do not align with the line connecting them to features. The labels are basically where I want them, but the line heads elsewhere (see Figure 1). How do I get these lines to basically be positioned from the first letter of the town name to the point? Image shows map with points being towns and the labels their town name. The lines are supposed to connect the town name label (e.g. Warrnambool) to the point (the town location), but the lines are fixed in odd directions

3

Proposed expression for geometry generator:

-- algorithm inspired by https://github.com/haubourg/EasyCustomLabeling/blob/master/EasyCustomLabeling/EasyCustomLabeling.py line 260 and next

case when "auxiliary_storage_labeling_positionx" < $x and "auxiliary_storage_labeling_positiony" > $y and abs("auxiliary_storage_labeling_positiony"-$y) < abs("auxiliary_storage_labeling_positionx"-$x) THEN 
 make_line($geometry, make_point($x-abs("auxiliary_storage_labeling_positiony"-$y),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))
when  "auxiliary_storage_labeling_positionx" < $x and "auxiliary_storage_labeling_positiony" > $y and abs("auxiliary_storage_labeling_positiony"-$y) >= abs("auxiliary_storage_labeling_positionx"-$x) then 
  make_line($geometry, make_point($x,abs("auxiliary_storage_labeling_positionx"-$x)+$y),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))
when "auxiliary_storage_labeling_positionx" < $x and "auxiliary_storage_labeling_positiony" < $y and abs("auxiliary_storage_labeling_positiony"-$y) < abs("auxiliary_storage_labeling_positionx"-$x) THEN 
  make_line($geometry, make_point($x-abs("auxiliary_storage_labeling_positiony"-$y),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))  
when  "auxiliary_storage_labeling_positionx" < $x and "auxiliary_storage_labeling_positiony" < $y and abs("auxiliary_storage_labeling_positiony"-$y) >= abs("auxiliary_storage_labeling_positionx"-$x) then 
  make_line($geometry, make_point($x,$y-abs("auxiliary_storage_labeling_positionx"-$x)),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))
when "auxiliary_storage_labeling_positionx" >= $x and "auxiliary_storage_labeling_positiony" > $y and abs("auxiliary_storage_labeling_positiony"-$y) > abs("auxiliary_storage_labeling_positionx"-$x) then --quadrant ur alternatif
  make_line($geometry, make_point($x,"auxiliary_storage_labeling_positiony"-abs("auxiliary_storage_labeling_positionx"-$x)),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony")) 
when "auxiliary_storage_labeling_positionx" >= $x and "auxiliary_storage_labeling_positiony" > $y and abs("auxiliary_storage_labeling_positiony"-$y) < abs("auxiliary_storage_labeling_positionx"-$x) then 
   make_line($geometry, make_point($x+abs("auxiliary_storage_labeling_positiony"-$y),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))  
when "auxiliary_storage_labeling_positionx" >= $x and "auxiliary_storage_labeling_positiony" <= $y and abs("auxiliary_storage_labeling_positiony"-$y) > abs("auxiliary_storage_labeling_positionx"-$x) THEN 
  make_line($geometry, make_point($x,$y-abs("auxiliary_storage_labeling_positionx"-$x)),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))  
when "auxiliary_storage_labeling_positionx" >= $x and "auxiliary_storage_labeling_positiony" <= $y and abs("auxiliary_storage_labeling_positiony"-$y) < abs("auxiliary_storage_labeling_positionx"-$x) THEN 
 make_line($geometry, make_point($x+abs("auxiliary_storage_labeling_positiony"-$y),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx", "auxiliary_storage_labeling_positiony"))  
   END 

and for label position (horizontal alignment) :

case 
when "auxiliary_storage_labeling_positionx" < $x  THEN 'right'
ELSE 'left'  
END

see sample.

  • THANK YOU for this! It is exactly what I have been looking for in QGIS3. I'd award a bounty if I could – she_weeds Sep 20 '18 at 2:03
2

Short answer: use the expression below.

make_line($geometry, 
          make_point("auxiliary_storage_labeling_positionx",
                     "auxiliary_storage_labeling_positiony"))

[Background]

It is not stated in your question, but the captured image suggests that these labels were moved using Easy Custom Labeling function. Because QGIS 3 does not show the leader lines (connectors) automatically, Geometry generator approach seems to be the good workaround.

[Steps]

(1) On your point layer, move your labels to desired locations.

(2) Duplicate your point layer and open Layer properties

(3) Switch it to Geometry generator and select LineString/MultiLineString

(4) The expression is the one on top of this answer.

enter image description here

Then you will get lines, as expected:

enter image description here

NB. If you move your labels afterwords, you need to redo these steps again.

  • This worked! Thanks for the advice it was completely accurate. But now I have a new related issue. How can I change the position that the leader lines meet the label? At the moment they meet the label at a point at the lower left hand side of the label text ''box''. I want them to meet the label at either the top left side or the top centre of the label. Any advice? – eclectus Jun 5 '18 at 11:02
  • Hi @eclectus What I know is doing it manually and it is tedious... I will update the answer to include that. Hope you do not get astounded. – Kazuhito Jun 5 '18 at 11:41
  • @eclectus Moved it to your new question. HTH. – Kazuhito Jun 5 '18 at 12:05
1

It could be caused by your labeling option, try to change the label alignement and/or placement (offset from point should give you best result)

-1

Aquí esta el código adaptado para polígonos. (Translated "Here is the code adapted for polygons.")

> >CASE  WHEN "auxiliary_storage_labeling_positionx" < (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" >
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) <
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) )  THEN  
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))),
> make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*')))-abs("auxiliary_storage_labeling_positiony"-(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony")) WHEN 
> "auxiliary_storage_labeling_positionx" <
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" >
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) >=
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN   
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))),
> make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*'))),abs("auxiliary_storage_labeling_positionx"- (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))+
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony")) WHEN
> "auxiliary_storage_labeling_positionx" <
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" <
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) <
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN   
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))), make_point(
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*')))-abs("auxiliary_storage_labeling_positiony"- (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony"))   WHEN 
> "auxiliary_storage_labeling_positionx" <
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" <
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) >=
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN   
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))),
> make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*'))),(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))-abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*'))))),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony")) WHEN
> "auxiliary_storage_labeling_positionx" >=
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" >
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) >
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN --quadrant ur alternatif  
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))), make_point(
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*'))),"auxiliary_storage_labeling_positiony"-abs("auxiliary_storage_labeling_positionx"-(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*'))))),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony"))  WHEN
> "auxiliary_storage_labeling_positionx" >=
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" >
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) <
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN    
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))),
> make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*')))+abs("auxiliary_storage_labeling_positiony"-(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony"))   WHEN
> "auxiliary_storage_labeling_positionx" >=
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" <=
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) >
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN   
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))), make_point(
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*')))
> ,(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))-abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*')))
> )),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony"))   WHEN
> "auxiliary_storage_labeling_positionx" >=
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))) and
> "auxiliary_storage_labeling_positiony" <=
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)'))) and
> abs("auxiliary_storage_labeling_positiony"-(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))) <
> abs("auxiliary_storage_labeling_positionx"-
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))))  THEN  
> make_line(make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*) -?\\d+\\.?\\d*'))),
> (toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d* (-?\\d+\\.?\\d*)')))),
> make_point((toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '(-?\\d+\\.?\\d*)
> -?\\d+\\.?\\d*')))+abs("auxiliary_storage_labeling_positiony"-(toreal(regexp_substr(geom_to_wkt(centroid($geometry)),
> '-?\\d+\\.?\\d*
> (-?\\d+\\.?\\d*)')))),"auxiliary_storage_labeling_positiony"),make_point("auxiliary_storage_labeling_positionx",
> "auxiliary_storage_labeling_positiony"))      END
  • 1
    Please edit add an english explanation to your answer. What does your code do and why is it your choice to solve the issue in the question? – MrXsquared Dec 8 '18 at 15:23
  • and please improve the formatting of your code – Mesa Dec 8 '18 at 17:10
  • All you have said is "Here is the code adapted for polygons". What is your question? – MappaGnosis Dec 8 '18 at 17:38
  • I am new to this forum and how to post answers. The code is used to make the lines for the labels with a layer of polygons. – Lepe Dec 14 '18 at 19:15

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.