6

I'm new to GIS software and I've been introduced to QGIS 2.18 as part of my internship.

I was tasked with creating new styles for the company's maps, however I've encountered a problem with one of the requested styles.

I was to create a style for a line that would create a buffer for a line and then apply a gradient depending on the angle of the line (This part I manage to get using geometry generator). However, it returns the line buffers as an oval and I would like it to be flat ended (take a shape as a rectangle).

I am aware that v.buffer.distance allows for creation of flat-ends but I'm hoping for the same result but by using geometry generator so that it could be saved as a style.

Buffer, and bounds(Buffer example

The picture above shows what I've managed to create the buffer($geometry,0.05) vs the bounds method in Using QGIS Geometry Generator to get rectangle from point?

To specify again, I want to rectangularize(?) the result I got from buffer($geometry, 0.05)

2
  • Perhaps this post might help: Using QGIS Geometry Generator to get rectangle from point?, the bounds method might be useful depending on how you created your geometries :)
    – Joseph
    Jul 12, 2018 at 9:58
  • I did have a look at the post. While I couldn't get all of them to work (probably because they are for points), the one with bounds worked and generated a polygon that has flat ends but it goes from corner to corner. I will edit the question and insert a picture of examples. Jul 12, 2018 at 10:28

2 Answers 2

6

In QGIS 3.2, there are additional buffer functions you can use to style your lines. Each function has a set of properties you could set such as the number of segments and, most importantly in your case, setting the join style (i.e. round, miter (flat) or bevel). These are not available in QGIS 2.x but if you can get access to the latest QGIS version, you could follow the steps below:


  1. At the moment, there is only the single_sided_buffer function which uses the join style property. This creates a buffer on either side of the line but we can use two of these and split the difference in width so that it will look like a single buffer. We can use an expression like:

    single_sided_buffer( geometry, distance, segments, join)
    

    where:

    • geometry - Current geometry
    • distance - Buffer distance (positive values = left of line; negative values = right of line)
    • segments - Number of segments used to represent circles. This is supposed to be optional but for some reason, I need to include it otherwise it won't work.
    • join - Join property (1 = round, 2 = miter and 3 = bevel)

  1. Add a symbol layer for the geometry generator and we will create one side of the buffer with an expression like:

    single_sided_buffer( $geometry, 0.05, 0, 2)
    

    Symbology


  1. Add another and use negative values:

    single_sided_buffer( $geometry, -0.05, 0, 2)
    

  1. This should give the appearence of a rectangular buffer (the red lines are the original line features):

    Buffer

4
  • 1
    I was going to suggest this. But with curved lines it does not look very good, the ends do not line up. Jul 12, 2018 at 12:55
  • 1
    Thank you very much for sharing this. I assume that if I created a style in 3.2 it wouldn't work in 2.18? If not, I will keep this in mind for the future. Jul 12, 2018 at 13:12
  • @HeikkiVesanto - You're right, it does look 'blocky'. I wonder if there's additional properties which could smooth this out.
    – Joseph
    Jul 12, 2018 at 13:14
  • @MateuszDąbkowski - Most welcome! Chances are styles created from QGIS 3.2 would not work in 2.28, although the opposite might be fine.
    – Joseph
    Jul 12, 2018 at 13:16
4

You can create a virtual layer that transforms your line into a polygon. You would then style this new layer.

Go to layer / add layer / add - edit virtual layer and type the following query. Rename a by your line layer, and add fields as needed. 0.01 is the 1/2 buffer size (here in degrees) and the ending 0 / 1 is for right or left side.

You can at the same time compute the line azimuth (angle between the horizontal and the 1st/last point of the line, expressed in radians)

select id, 
 st_union(ST_SingleSidedBuffer(geometry,0.01,0) ,  ST_SingleSidedBuffer(geometry,0.01,1)),
 st_azimuth(st_startpoint(geometry),st_endpoint(geometry)) azim 
from a

enter image description here

2
  • This method works perfectly, but it seems to upset my fill a bit, my fill was a gradient that would be dependent on how the line was drawn. Do you know of a way to keep that information so that the gradient fill would follow that angle? (Currently it seems to follow the line but whatever the point is higher in y axis seem to be classified as the zero point, so if i draw top point first then bottom it would result in the same gradient as when I draw bottom point first then top) Jul 12, 2018 at 13:19
  • @MateuszDąbkowski see edit. You can compute the line azimuth at the same time.
    – JGH
    Jul 12, 2018 at 13:42

Your Answer

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

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