2013-12-01

Create Line Segments from Coordinates List

Consider creating line segments from a coordinates list like this.
id  |  x  |  y  |  attr
0  0  0  val0
1  2  2  val1
2  5  2  val2
3  6  0

Resultant line segments should be (id 0 - id 1), (id 1 - id 2) and (id 2 - id 3), and also they should have attributes of the start node ("id" and "attr").
Just to create line segments, connect all points to create a polyline (2DPointReplacer + PointConnector), and then chop it into individual line segments (Chopper). It would be the quickest way, but will be necessary to recover attributes for every segment after chopping.

About one year ago, I provided a workflow like this image for a similar subject in the Community. > Community: connect the dots











I think it was an enough elegant solution. However, in FME 2013 SP2+, since we can use both "Multiple Feature Attribute Support" and "Conditional Value" in the AttributeCreator, there could be more elegant and / or efficient solutions currently.
(FME 2013 SP4 Build 13547)

Example 1: Use the 2DPointReplacer and the 2DPointAdder
I think this is one of the plainest ways.










Example 2: Use @XValue and @YValue from FME Feature Functions
In this example I used the FMEFunctionCaller to call @XValue and @YValue. Those functions can be also called in the AttributeCreator etc..











Example 3: Create XML describing geometry and use the GeometryReplacer
Excessive?















Anyway, the point is the "Multiple Feature Attribute Support" functionality of the AttributeCreator.

=====
2013-12-02
Example 4: Call @XValue and @YValue in the AttributeCreator
This is just an experiment. It works, but maybe is not a standard usage.



















Example 5: Python script
And, a PythonCaller of course can do that. No need to use other transformers.
-----
import fmeobjects

class LineSegmentCreator(object):
    def __init__(self):
        self.prior = None

    def input(self, feature):
        xy = lambda f: (float(f.getAttribute('x')), float(f.getAttribute('y')))
        if self.prior:
            line = fmeobjects.FMELine([xy(self.prior), xy(feature)])
            self.prior.setGeometry(line)
            self.pyoutput(self.prior)
        self.prior = feature

    def close(self):
        pass
-----

Example 6: Tcl script
I don't know whether Tcl is suitable in this case, but it's not impossible.
For example, two FMEFunctionCallers in the Example 2 can be replaced with a TclCaller which calls this procedure.
-----
proc createLineSegment {} {
  FME_Execute XValue "_x{}"
  FME_Execute YValue "_y{}"
}
-----
Naturally, the 2DPointReplacer and the 2DPointAdder in the Example 1 can be also replaced with a TclCaller.
-----
proc createLineSegment {} {
  foreach {x y} {"x" "y" "_x1" "_y1"} {
    FME_Execute XValue [FME_GetAttribute $x]
    FME_Execute YValue [FME_GetAttribute $y]
  }
}
-----

Although there could be more variations, end here.

No comments:

Post a Comment