6

Based on @BERAs answer to Arrow head at the last path segment of Bezier curve I made an arrow at the end of a path with geometry generator

make_line(point_n( $geometry, -2), end_point($geometry))

enter image description here

I need to improve my symbology:

  1. When I adjust the thickness of the line, it goes beyond my arrow.
  2. How can I get a thin line beginning like on my other arrows?

enter image description here

0

3 Answers 3

5

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.

enter image description here

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)

enter image description here

4
  • thank you for helping. It's a good idea but it is a solution with many setps !
    – Wilcar
    Nov 18, 2020 at 14:00
  • Let's hope together there's someone with an easier solution!
    – Babel
    Nov 18, 2020 at 14:01
  • Yes. But Thank you !
    – Wilcar
    Nov 18, 2020 at 14:01
  • 1
    Great to have another way to achieve this by @JGH. Still strange enough that there seems to be no really solution to style arrows accordingly. Would be a great improvement for further QGIS versions as I guess that this use of arrows is not so exotic. Exporting this as a style could be a workaround for the time being.
    – Babel
    Nov 18, 2020 at 21:46
4

Taking inspiration from @Babel's answer, here is a variant that allows having a smoother width transition and the arrow in the same style.

enter image description here

  1. 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
  1. 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)

enter image description here

Go to the simple line style and set a round cap style

enter image description here

  1. 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

enter image description here

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.

enter image description here

2

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):

enter image description here

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:

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.