Is it possible to create a " trapezoids" shaped line buffer?
Page 1 / 1
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