# QGIS - Buffer distance as portion of polygon variable width

Is it possible to create a buffer of for example 3/4 of the polygons local width?

I have a polygon of river body, somewhere the river has 20 meters in width, somewhere 70 m. I need to extract the cunette, which varies based on the rivers width. So i need to create a negative buffer that is 3/4 of the current river body polygon width, so it copies its current geometry.

I think this must be feasible, however i can't find a way...

Any ideas? • do u have the river width information somewhere available (as attribute in your table) ? Mar 3 at 10:44
• Can you provide an example of your current data and what you are trying to produce? Because if you created a negative buffer of 3/4 of the rivers width, you'd get no area.
– Erik
Mar 3 at 11:08
• @snaileater There is no information on the width, the width is changing with each vertex, river body is irregular object, there can't simply be attributes with width Mar 3 at 11:18
• @Erik It's a polygon, not polyline, it has a geometry. Mar 3 at 11:20
• If you could create a central axis of the river polygon, you could use this to calculate the width of the river. Possible with PostGIS: postgis.net/docs/ST_ApproximateMedialAxis.html Apr 5 at 8:21

I think you could work on a raster based approach to solving your problem. What you ideally would like to have is some sort of inversed Euclidian Distance calculation (from the polygon's exterior towards its inside.

You could attempt this as followed, I haven't tested but can get you started:

• use Polygon to Lines tool to convert the river to a line segment.
• Use Euclidian distance tool to calculate the distance towards the outside.
• Use the river polygon shape as the mask or extent of the Euclidian Distance calculation.
• If needed, convert the Euclidian Distance Raster back to a polygon using the polygonize tool, after resampling and extracting desired distance from the internal river line.

There are some articles that try to attempt this that might be of use as well:

• Thanks, these tips are helpful, and so are the links. I think this is the way to do it Mar 3 at 12:09

I'm sure someone else can come up with a more elegant solution using PostGIS or python, but here's something I cobbled up using regular tools that should work if you're only concerned with a few river polygons. I hope I understood the size you want your resulting polygon relative to the original:

• v.voronoi.skeleton to find centerlines

• clean up the "dangles" at both ends

• Simplify with appropriate tolerance distance (to reduce the number of transects)

• Transect with a length large enough to be wider than the river polygon, both sides

• Clip the transect layer with the river polygon

• Points along geometry with these parameters:

• Distance: `\$length * (1/3)`
• Start offset: `\$length * (1/3) + 0.05` (the +0.05 is to make sure the third point is not created)
• In the new point layer, add a field called something like Order and run field calculator on it with this expression which gives all adjacent points an incremental value:

`if("distance" = minimum("distance",group_by:="TR_SEGMENT"),"TR_SEGMENT","TR_SEGMENT" + ((maximum("TR_SEGMENT")-"TR_SEGMENT")*2) + 1)`

• Points to path on the point layer using the new field as the order

• Lines to polygons to get the result

Here's what the layers look like, it gives an idea of the process, with the result being the orange polygon. I don't think it could easily be turned into a model to deal with large polygon sets because it requires manually fixing the voronoi centerlines and simplifying it. I need to do something similar, but I don't seem to find the Euclidean distance tool.

I have a polygon which represents a riverbed area and I would like to make a buffer based on the river width.

So I am wondering if the proposed procedure is suited to achieve what I am trying to do.

The buffer would be n*width with n an integer number I choose. If you look at the picture you see that the buffer would be larger at the width1 cross-section, and it would be thinner at the width2 cross-section.

I tried using the percentage buffer tool, but with no luck.

I also tried applying a buffer with a geometry expression such as

``````width(\$geometry)*2
``````

but "width" is not a characteristic of "geometry", so no luck here either. Probably the best way to do this is to draw some cross-section (e.g. one each 10-50 m), calculate the width and build kind of a skeleton of your river as you do for instance in HECRAS.