By Troy Buerge


2019-04-13 20:36:49 8 Comments

I am trying to improve callout lines on maps I'm making. I'm currently using the method in this link to make my callout lines. That works fine, bu I'd like the lines to always go to the closest point of the label like this:

enter image description hereenter image description here

enter image description hereenter image description here

I think it would work if I used code down the line of this in the expression editor for the geometry generator.

make_line(
  make_point($x, $y),
    make_point((CASE
      WHEN "auxiliary_storage_labeling_positionx" > $x
        THEN "auxiliary_storage_labeling_positionx"
      WHEN ("auxiliary_storage_labeling_positionx"  + "labelwidth") > $x  
            AND ("auxiliary_storage_labeling_positionx") < $x
        THEN ("auxiliary_storage_labeling_positionx" + "labelwidth")
      ELSE $x
      END )
    ,(CASE
      WHEN "auxiliary_storage_labeling_positiony" < $y
        THEN "auxiliary_storage_labeling_positiony"
      WHEN ("auxiliary_storage_labeling_positiony"  + "labelHeight") < $y
            AND ("auxiliary_storage_labeling_positiony") > $y
        THEN ("auxiliary_storage_labeling_positiony"  + "labelHeight")
      ELSE $y
      END )
  )
)

I'm not sure if I have all the < and > correct but that's beside the point. The issue with that is that I can't seem to figure out how to get the width and the height of the label.

I am not very good with the expression editor, and have never done anything with the function editor.

1 comments

@eurojam 2019-04-14 08:06:19

you can also use the data defined 'Alignment' to achieve it and use only a simple line within the geometry generator without any AND conditions:

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

enter image description here

and an expression like this for the horizontal:

if(x(closest_point($geometry,
 make_point( "auxiliary_storage_labeling_positionx" ,
"auxiliary_storage_labeling_positiony" ))) 
 > x(make_point( 
"auxiliary_storage_labeling_positionx" , 
"auxiliary_storage_labeling_positiony"
)),'Right','Left')

and something similar for the vertical alignment:

if(y(closest_point($geometry,
make_point( 
"auxiliary_storage_labeling_positionx" , 
"auxiliary_storage_labeling_positiony" ))) < 
y(make_point( 
"auxiliary_storage_labeling_positionx" , 
"auxiliary_storage_labeling_positiony" 
)),'Bottom','Top')

the 'closest_point' statement you'll only need if the geometry is polygon or line.

for the Centered position you can change the expression and add a variable d for a treshold (e.g. in meters) in which the label will be centered:

with_variable ('d', 200,
CASE
WHEN 
(x(closest_point($geometry,
 make_point( "auxiliary_storage_labeling_positionx" ,
"auxiliary_storage_labeling_positiony" ))) 
< x(make_point( 
"auxiliary_storage_labeling_positionx" , 
"auxiliary_storage_labeling_positiony"
))[email protected])
THEN 'Left' 
WHEN
(x(closest_point($geometry,
 make_point( "auxiliary_storage_labeling_positionx" ,
"auxiliary_storage_labeling_positiony" ))) 
> @d+x(make_point( 
"auxiliary_storage_labeling_positionx" , 
"auxiliary_storage_labeling_positiony"
))) THEN 'Right'
ELSE 'Center' END)

enter image description here

@Troy Buerge 2019-04-14 20:43:42

That works really good, with the exception of the situation where the label is directly above the geometry. in that case it moves the label off to one side or the other. I'd like to also be able to place a label like the first picture in my question..

@eurojam 2019-04-15 05:00:15

I have added a expression for the horizontal with something like a treshold (variable d in meters) . between +d and -d around the label it will be centered.

@Troy Buerge 2019-04-16 00:26:04

That's getting better. The issue is that it fails quit badly when there are a large range in label lengths, or when changing zoom levels. Is there any way to get the length of the label in meters on the map?

Related Questions

Sponsored Content

0 Answered Questions

Create label from different fields in ArcGIS Desktop?

4 Answered Questions

2 Answered Questions

[SOLVED] Finding which side of closest polyline point lies on in QGIS?

  • 2018-09-07 09:38:51
  • radouxju
  • 164 View
  • 7 Score
  • 2 Answer
  • Tags:   qgis line qgis-3

0 Answered Questions

QGIS API Label expression for vector layer

2 Answered Questions

[SOLVED] Straight Lines from Label to Feature in QGIS?

1 Answered Questions

[SOLVED] Adding lines connecting labels to points in QGIS?

1 Answered Questions

[SOLVED] Getting the height and width of labels in QGIS?

2 Answered Questions

[SOLVED] Creating leader lines for moved labels

1 Answered Questions

[SOLVED] Creating multiple lines label in QGIS?

2 Answered Questions

[SOLVED] Placement for Label

  • 2015-04-03 12:53:55
  • Nikhil Murarka
  • 182 View
  • 2 Score
  • 2 Answer
  • Tags:   qgis labeling

Sponsored Content