Hi,
You can use
the DistanceMarker_2013 custom transformer from FME Store to create points at the same interval (e.g. 5m) along the line. After this, the PointOnLineOverlayer transformer can be used to divide the line at those points.
If you want, you can also create a custom transformer which divides a line at the same interval. The Snipper, LengthCalculator, Tester etc. and the Looping functionality should be used. I think it's an interesting challenge
Takashi
There is more suitable custom transformer; have a look at t
he IterativeSnipper_2013 from FME Store.
Hi,
you can also use the Chopper to split a line into a specified (approximate, see help) lengths.
I would also recommend looking under the "Linear referencing" category of the transformer gallery and the FME Store. Should be lots of functionaltiy there that might be relevant to your task.
David
hi Takashi, I keep getting an error message when I try to open this transformer from the FMEStore.
Is there any way you can attach it to this message or email it to me?
Cheers,
Shane
What kind of error has occurred? I could download the IterativeSnipper_2013 on the Canvas window of Workbench (2013 SP4) by typing some characters of the transformer name, like "iterative....".
Error communicating with FME Server. FME Server may not be running. Contact your FME Server administrator who can investigate the log files for further details.
I'm running (2013, SP2). It doesnt see it when typing on the canvas.
I'm not sure the reason for that error. Another way to download and install custom transformer from FME Store: You can see "Open in Workbench" button in
the custom transformer page. Click the button to download "*.fmc" file. If download was success, open this file with Workbench. Then installing will start. Try this way to download.
To do that i calcultate the number of subsectionlengths that fit in a certain length. This yields attributes like Numberofpieces (as integer), Start, End .
Start might be nescessary if n*subseqtionlength <> sectionlength. If not i symetrically start the subsectioning:
(start=(@Value(Straatlengte)-($(Benamingfrequentie)*@round(@Value(Straatlengte)/($(Benamingfrequentie)*1.0))))/2.0
Then i clone the sections by this amount. Coner number_of_copies=Numberofpieces+1.
Prior to this u need a tester to test wether the section is larger then your desired subsectioninglength.
Now u got all u need.
Use a snipper and set as start and end:
@Value(Start)+(@Value(_copynum)*$(Nsubsectionlengths)
U get all the points distributed.
U can connect those as they are neatly order by cpoynumber and grouped by (in my case) road_ID
Oh! U must deagregate prior to this operation!. Aggregates wont get processed.
(as u can see i made subsectionlengths a parameter, os i can easily choose a different distribution)
The trick in this is actually using the cloner, as snipper only snips a line(section) once.
This is also easily adapted to output the linesections rather then just the points.
(I was after streetname insertionpoints.)
To do City of Leiden, where i live, this way takes 26sec using FME 2012, on a quadcore xeon graphics system with 16Gb and a quadro 4000 graphics card(kinda monster of a machine :))
..actually it took 13sec.
ths svg writer took up rest of the procestime..
Hi Takashi, it ended up being a proxy setting error at our end. I.T. have sorted it out and I'm now able to download.
Gio, hi. So you used cloner and snipper only to achieve your result?
Torro
I tried Gio's method (Cloner and Snipper) with this workflow. Assume input line feature has an attribute named "_interval" holding segment length (e.g. 5m). 1) LengthCalculator: Calculate lenght of the original line. Length Attribute: _length
2) ExpressionEvaluator: Calculate number of segments to create. _num_pieces <-- @int(@Value(_length)/@Value(_interval))
3) AttributeCreator: Increment "_num_pieces" if there is a remnant part. Use Conditional Value. If 0 < @Evaluate(@Value(_length)-@Value(_interval)*@Value(_num_pieces)) _num_pieces <-- @Evaluate(@Value(_num_pieces)+1) Else <Do Nothing>
4) Cloner Number of Copies: _num_pieces Copy Number Attribute: _copynum
5) Snipper Snipping Mode: Distance (Value) Starting Location: @Evaluate(@Value(_interval)*@Value(_copynum)) Ending Location: Use Conditioinal Value. If _copynum < @Value(_num_pieces)-1 @Evaluate(@Value(_interval)*(@Value(_copynum)+1)) Else (for final piece) -1 I did that with a PythonCaller before. This is a simplified example. ----- # Assume geometry of input feature is a curve (line, arc or path). # Input feature must have "_interval" attribute (0 < interval length). # Measure length in 2D. import fmeobjects class SimpleLineDivider(object): def __init__(self): self.geomCloner = fmeobjects.FMEFeature() def input(self, feature): remnant = feature.getGeometry() if not isinstance(remnant, fmeobjects.FMECurve): return coordSys = feature.getCoordSys() def output(geom): segment = feature.cloneAttributes() segment.setGeometry(geom) segment.setCoordSys(coordSys) self.pyoutput(segment) interval = float(feature.getAttribute('_interval')) while interval < remnant.getLength(False): self.geomCloner.setGeometry(remnant) curve = self.geomCloner.getGeometry() curve.snip(fmeobjects.SNIP_DISTANCE, False, 0, interval) output(curve) remnant.snip(fmeobjects.SNIP_DISTANCE, False, interval, -1) if 0.0 < remnant.getLength(False): output(remnant) def close(self): pass -----
For your information.
Yes, cloner as main solution.
I adapted the wb for nodes, to do the linesections.
The wb is the same apart form 1 extra attr.creator. This because in FME 2012 the snipper does not accept evaluations. (I see by mr. Takashi's script that 2013 does. Well i just tested it toady for packaging, so next week i can finaly work it on a daily basis..
)
So i created start and end prior to snipper.
Also for ease of tcl reader, i seperate the lines wich are shorter then required subsectioning-length using a thester on length.
Those get
1st creator holds:
startingpoint
and
numbeofsections))
Straatlengte is dutch for streetlength, benamingsfrequentie is frequency of naamtags i want.
then
cloner does
copynumber @Value(Aantalnaam_intstanties)+1.
and then a creator to make attriubtes
start ))
end))
end and start go into snipper.
Lines with length shorter then subsectioning:
start)
end)
Nice thing is, this is exactly the same as the wb for extracting the node. Just slightly different settings in the creators.
So now my script outputs both!
Hi Gio, Yes, I'm using FME 2013. In FME 2013, many transformers accept an expression as its parameter value. Furthermore, the expression can contain not only FME Feature / String / Math Functions but also Tcl commands. Very effective in some cases.
About the Cloner, I didn't notice such an effective usage you suggested. I've always used Python or custom transformer with Loop in cases like this subject. Thank you for the tip.
And, just call me Takashi. "mr." is too formal
Takashi
Hi all,
Cloner is one.
The other is listbuilder, in case u got the data in a table and the data is not described by a matimathical function but more random. M
Built List on the data grouped by ID. Merge with features by same ID and then explode. (i.e. 3 features and say 10 rows of data concerning these features will yield 10 features)
Then u have the features multiplied..and ready to process.
I wil do so Takashi.
bye all
Takashi, Im trying to use your method below:
Assume input line feature has an attribute named "_interval" holding segment length (e.g. 5m). 1) LengthCalculator: Calculate lenght of the original line. Length Attribute: _length 2) ExpressionEvaluator: Calculate number of segments to create. _num_pieces <-- @int(@Value(_length)/@Value(_interval))
3) AttributeCreator: Increment "_num_pieces" if there is a remnant part. Use Conditional Value. If 0 < @Evaluate(@Value(_length)-@Value(_interval)*@Value(_num_pieces)) _num_pieces <-- @Evaluate(@Value(_num_pieces)+1) Else <Do Nothing>
4) Cloner Number of Copies: _num_pieces Copy Number Attribute: _copynum
5) Snipper Snipping Mode: Distance (Value) Starting Location: @Evaluate(@Value(_interval)*@Value(_copynum)) Ending Location: Use Conditioinal Value. If _copynum < @Value(_num_pieces)-1 @Evaluate(@Value(_interval)*(@Value(_copynum)+1)) Else (for final piece) -1
Since I am new to FME can you spell out how I enter this code in the condition value in AttributeCreator and Snipper?
Cheers,