Skip to main content
Is it possible to create a " trapezoids" shaped line buffer?
sorry.. to complete my question :

 

For example, a 10m buffer on one end that expands to a 30m buffer on the other end of the line (it will be more useful if we can get the distances from table attributes)

 

thanks
Hi, the Extender might help you.

 

Takashi
May be my question was not clear 🙂.. I have polyline roads (the center line) and I want to create polygonal roads.. So I have for example a road which have a width of 8m at the beginning and the road-end have a width of 10m .. (I do not need to clean the polyline.. I have already a topological roads).. thanks for your help...
Got it :)

 

 

For a line segment (having only two nodes - start and end), the trapezoidal buffered area can be created with this procedure.

 

Assume that the segment has unique id (e.g. "_segment_id"), and the start and end widths of the segment are stored by attributes (e.g. "_start_width", "_end_width").

 

1) Branch the data flow into two streams.

 

2) On one stream, transform the line segment into the start node point; create a buffered area of the point by "_start_width" * 0.5 (Snipper and Bufferer).

 

3) On another stream, transform the line segment into the end node point; create a buffered area of the point by "_end_width" * 0.5 (Snipper_2 and Bufferer_2).

 

4) Send the two areas into a HullAccumulator to create a convex hull grouping by "_segment_id". 

 

 

 

Apply the procedure to the road lines (polylines).

 

Assume that each road has unique ID (e.g. _road_id).

 

1) Add the road length (e.g. "_road_length") as an attribute (LengthCalculator).

 

2) Create a set of measures (MeasureGenerator).

 

3) Split the road into individual line segments (Chopper, Mode: By Vertex, Maximum Vertices: 2).

 

4) Extract measure values as a list attribute "_measures{}" (MeasureExtractor, Type: Whole Line). Here, _measures{0} will store the distance from the beginning of the road to the start node of the segment; _measures{1} will store the distance from the beginning of the road to the end node of the segment, measureing along the road line.

 

5) Add "_segment_id" to each segment (Counter).

 

6) Create trapezoidal buffered area for each segment with the procedure mentioned above.

 

7) Dissolve them grouping by "_road_id" (Dissolver).

 

 

In the step 6), "_start_width" and "_end_width" of each segment can be calculated with these expressions if the beginning and ending widths of the road are 8m and 10m.

 

_start_width =  8 + (10 - 😎 * _measures{0} / _road_length

 

_end_width = 8 + (10 - 😎 * _measures{1} / _road_length

 

The buffer amounts are half of them.

 

For simplifying explanation, I wrote the widths (8 and 10) as constants in the expressions, but you can set them as attributes to each road beforehand, and refer to the values in the expressions of course.

 

Just be aware the trap of dividing integers if operands could be integer number. i.e. 3 / 2 = 1, is not 1.5.

 

 

Hope this helps.
P.S. If you don't need round end caps, clip the resulting area by another buffered area which can be created from the original road line using a Bufferer (Buffer Amount: <max width/2>, End Cap Style: None).

 


Supplement. Both "_road_id" and "_segment_id" have to be set to the "Group By" parameter of the HullAccumulator in the step 6).
waaaaaaaaaw... thanks alot for your effort.. I'll try it.. it seem great.. thanks again..
I suspect most fme fiddlers have built at least one version of this....

 

and as straight lines are just too easy..

 

 

 

 

..bit complexish workench..and still some tiny flaws in there..hav'nt worjked on it awhile

 

 

 

 

 
Thanks a lot Takashi.. I got it..  I tried the workbench for some polylines and it works.. I will test it for all polylines..

 

Have a nice weekend..
Good to hear you got it :)

 

 

Upgrade version. This may be a little more efficient.

 

Assume that every road line has unique ID and beginning/ending widths as attributes (_road_id, _beg_width, and _end_width).

 

 

1) AttributeCreator

 

_num_coords = @NumCoords()

 

_ratio = @double(@Value(_end_width)-@Value(_beg_width))/@Length()

 

2) MeasureGenerator

 

3) Chopper

 

Mode: By Vertex

 

Maximum Vertices: 1

 

4) MeasureExtractor

 

Type: Individual Vertex by Index

 

Destination Attribute of Point or Vertex: _point_measure

 

Index: 0

 

5) Counter

 

Count Output Attribute: _segment_id

 

Counter Name: _road_id <Attribute>

 

Count Start: 0

 

6) Cloner

 

Number of Copies: 2

 

Copy Number Attribute: _copynum

 

7) ExpressionEvaluator

 

_segment_id = @Value(_segment_id)+@(_copynum)

 

8) Tester

 

0 < _segment_id AND _segment_id < _num_coords

 

9) Bufferer

 

Buffer Amount: (@Value(_beg_width)+@Value(_ratio)*@Value(_point_measure))*0.5

 

10) HullAccumulator

 

Group By: _road_id, _segment_id

 

Hull Type: Convex ()

 

11) Dissolver

 

Group By: _road_id

 

 

In addition, all the transformers in the Bookmark can be replaced with a PythonCaller. I posted a script example in another site.

 

Find it with googling by "Takashi FME Memo" if you are interested. ;)

 


The procedure might be useful also to other users, so I published a custom transformer named "TaperLineBufferer" in the FME Store.

 

Please find it in your Transformer Gallery and evaluate.

 

Requirement: FME 2014 SP4 build 14433+
hi.. I have finally tested the transformer and it is great and very quick.. Anyway I still have a small problem .. when I use the buffer to eliminate the round area (as you told me : clip the resulting area by another buffered area which can be created from the original road line using a Bufferer) I still get the small round area because it is inside the adjacent road .. How can i clip every result surface-road with the second buffer (with end cap style non ).. thanks
Possibly the problem can be resolved by using the "Group By" parameter of the Clipper. Try setting unique ID attribute of the road features to the parameter.

 

If the original road features don't have ID, you can use a Counter to add sequential number as temporary ID to them.
yes... it works.. it is very quick ... great ... thanks a lot

Reply