Question

Road Chainage

  • 25 November 2013
  • 16 replies
  • 66 views

Ok all you FME Guru's, heres one I hope you can help me with.

 

 

I have a file 'Road Segments' and as it implies each segment has a start and finish chainage.  So for e.g. the first section of road might be 0start - 150m, the second section may be 150m - 250m and so on.

 

What I need to do is to give the chainage for somthing along the road.  So there may be a culvert that crosses somewhere along segment 150m - 250m.  I think I need to break these road segments into 5 m sections and use those 5 m sections as the chainage.  Therefore Road Segment 150m - 250m would be broken into 155,200,205,210,215.......etc and if the culvert fell into the zone of say 210, then 210 would = the chainage for that culvert.

 

What transformers would you recommend to achieve this?

16 replies

Userlevel 3
Badge +17
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
Userlevel 3
Badge +17
There is more suitable custom transformer; have a look at the IterativeSnipper_2013 from FME Store.
Userlevel 5
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
Userlevel 3
Badge +17
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. :(
Userlevel 3
Badge +17
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.
Badge +3
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 :))
Badge +3
..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
Userlevel 3
Badge +17
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.
Badge +3
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!
Userlevel 3
Badge +17
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
Badge +3
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,

Reply