Path ending with an arrow: need to improve symbology
It's kind of a workaround: save of copy of your line-layer (not duplicate layer), than on the copy choose explode line (make a separate line from each segment) and than set the size of your line with data driven overrride > assistant and define the source as $id, load max./min. values and set the thickness of the line from 0 to some value you'd like. You thus tell QGIS to set the thickness of each line-segment to it's id, thus it increasingly gets thicker.
Than combine it with the arrow on your other layer. If you use the exploded line-layer, the above solution to create the arrow will not work.
In the symbol layer type adjust the simple line for connecting- and end styles to round. Delete the last segment of the exploded line if necessary to avoid overlapping with the arrow.
If you want to have the arrow on the last line (segment) of your exploded line and if you want to extend this last line somewhat so that the arrow covers the underlying line, you can create a new symbol layer, select geometry generator and use the following expression (adjust the value 200000 to your needs), than set the generated line to symbol type arrow and style it accordingly:
extend(
geometry(
get_feature_by_id(
@layer ,
array_length( ( array_agg(collect( $geometry))))
)
),0,
200000
)
See screenshot:
1: Symbol layer for the arrow with the expression from above
2: Symbol layer for the line with line-thickness according to $id (assistant)
Taking inspiration from @Babel's answer, here is a variant that allows having a smoother width transition and the arrow in the same style.
- Create a virtual layer that will subdivide your line into around 100 segments.
Go the the menu layer / add layer / add-edit virtual layer
and enter the following query.
SELECT ST_Segmentize(geometry,ST_length(geometry)/100.0)
FROM myLayer
- Style the virtual layer to increase its width
Choose a single symbol
, then a geometry generator
line and enter the following to split every segment into its own line.
segments_to_lines( smooth( $geometry) )
Feel free to remove the smooth()
if your line is already curvy enough.
Select the generated line style and click the data override
icon beside the width
setting. Select edit
and enter the following expression.
It will set the width of all but the last segment. The width ranges from 2 * 1/100 for the 1st created segment to 2 * 100/100 for the last one.
if(@geometry_part_num < @geometry_part_count, 2.0* @geometry_part_num / @geometry_part_count,0)
Go to the simple line
style and set a round cap style
- set the arrow
Click on the "top" line, click the green +
beside it, add a new style, choose again a geometry generator. Enter the expression you have provided
select the arrow and set the width start
to 1.98 (because the last displayed segment in the previous step was 2 * 99/100 = 1.98) and the width
(end) at 2. You may want to play with the head length or thickness to make it look good.
An improved version of my first answer, without the need of duplicating layers. On a line layer, just define the line style as geometry generator > polygon and add this expression: tapered_buffer($geometry,0,2)
and replace 0 and 2 with the width at the start and the end of the line. You could add smooth()
to get smoother edges. Here is what you get (I added the white lines to show how the original line-geometry looks like):
Than simply add a second symbol layer (green +) and define again geometry generator as symbol layer style - this time, set line as geometry type. Use this expression and (again) change the values 0 and 2 according to your needs (the first value extends the line at it's beginning, the second one at its end):
extend(
geometry_n(
segments_to_lines(
$geometry),
num_geometries(
segments_to_lines($geometry)
)
),
0,
2
)
Than change the symbol layer type to arrow and style the arrow accordingly. This is how the result could look like: