Making use of the Geometry generator symbol layer type, I draw rectangles of dimensions @nv_bg_w (width) and @nv_bg_h (height) (project variables) to line features, either at coordinates text_x, text_y (attributes, if not NULL) or alternatively at the center of the line by the following expression:

    'POLYGON((' ||
    COALESCE("text_x", x(point_on_surface($geometry))) ||' '||  COALESCE("text_y", y(point_on_surface($geometry))) || ','||
    (to_real(COALESCE("text_x", x(point_on_surface($geometry)))+ @nv_bg_w )) ||' '||  COALESCE("text_y", y(point_on_surface($geometry))) || ','||
    (to_real(COALESCE("text_x", x(point_on_surface($geometry)))+ @nv_bg_w  )) ||' '||  (to_real(COALESCE("text_y", y(point_on_surface($geometry))))- @nv_bg_h ) || ','||
    COALESCE("text_x", x(point_on_surface($geometry))) ||' '||  (to_real(COALESCE("text_y", y(point_on_surface($geometry))))- @nv_bg_h ) || ','||
    COALESCE("text_x", x(point_on_surface($geometry))) ||' '||  COALESCE("text_y", y(point_on_surface($geometry)))|| '))'

As can be seen x(point_on_surface($geometry)) and y(point_on_surface($geometry)) occur very often. At least in this simple example, this makes the code harder to read than it would have to.

So my question is: Is there a way to store the latter expressions in some temporary variables, something like (pseudocode):

'POLYGON((' ||
... #and so on
  • Jochen, did you find any solution to the problem described in your question? I'm facing a similar need and am searching for the same thing
    – iulian
    Mar 19, 2018 at 9:03

1 Answer 1


Yes, there is a way in QGIS 3.x. You can set a variable by means of with_variable() function within an expression. So I expect the expression below will work for you.

with_variable( 'mx', x(point_on_surface($geometry)),
    with_variable( 'my', y(point_on_surface($geometry)),
            'POLYGON((' ||
            COALESCE("text_x", @mx) ||' '||  COALESCE("text_y", @my) || ','||
            (to_real(COALESCE("text_x", @mx)+ @nv_bg_w )) ||' '||  COALESCE("text_y", @my) || ','||
            (to_real(COALESCE("text_x", @mx)+ @nv_bg_w  )) ||' '||  (to_real(COALESCE("text_y", @my))- @nv_bg_h ) || ','||
            COALESCE("text_x", @mx) ||' '||  (to_real(COALESCE("text_y", @my))- @nv_bg_h ) || ','||
            COALESCE("text_x", @mx) ||' '||  COALESCE("text_y", @my)|| '))'

Documentation in expression dialog window:

enter image description here

Your Answer

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

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