Skip to the content.

Expressions for forced labelling… and animated

french version - summary

If you are unable to label (in curved mode) a linear object along its entire length, and before this becomes possible natively, here is an expression that will allow you to label regardless of the radius of curvature and repeat the text infinitely.

alt text

The principle:

In the function parameters: the text to be labelled, the layer ID (for technical reasons).

All that remains is to adjust the size, spacing, etc.

alt text

# Examples:
# static text
charloop( ABCDE..., @layer_id)
# or a field from your layer
charloop( "toponym"||' ', @layer_id)

How does it work?

The QGis labelling engine scans the line to place each graphic element at regular intervals and, by chance, requests the expression at each location, the expression then simply distributes the characters one by one.

It handles any ordering issues (the rendering engine switches from one entity to another, from one layer to another, and complicates things).

A dictionary (python) stores the index of the character currently displayed for each entity.

alt text

Expressions

In your profile folder, under python/expressions, place this script (or go through the ‘function editor’ interface and copy the content into your new script):

Animated version

alt text

The functions animated_charloop(), charloop_shift (for a subtle shift of characters), combined with the use of the “time manager”, and the text flows!

alt text

Procedure

animated_charloop('ABCDE', @layerid, @frame_number, @total_frame_count)

where @frame_number is a native variable (the index of the current step of the time manager) and @total_frame_count is the total number of steps (native variable or to be defined in the project properties in versions < 3.40)

However, this produces an animation that is too jerky (the function simply shifts the text by one character).

We can refine the positioning using an expression on the ‘shift along the line’ parameter:

charloop_shift('ABCDE', @typo_gap, @frame_number, @total_frame_count)

where @typo_gap corresponds to the value of the interval chosen for your symbol line (variable to be defined or replaced by a numerical value)

Additional functions

Problems/difficulties

case when line_direction_we()
	then ($geometry)
    else reverse($geometry)
end

Files

The script to be placed in your profile folder, under python/expressions

An example project and its layers: