2014-02-05

Create Line from Comma Separated Coordinates

(FME 2014 build 14234)

I received a CSV data which contains coordinates of line geometries.
This is a simplified example. All coordinates of a line is described in a CSV row, and number of coordinates is variable between 2 and 10. Each line has two attributes (LineID and NumPoints) other than coordinates.
-----
LineID,NumPoints,X1,Y1,X2,Y2,X3,Y3,X4,Y4,X5,Y5,X6,Y6,X7,Y7,X8,Y8,X9,Y9,X10,Y10
1,4,0,0,1,1,2,1,3,0
2,2,2,1,3,2
3,6,3,0,4,0,4,1,5,1,5,2,6,2
-----

The task is to create line geometries based on the CSV data.
My idea is simple. That is to say, if I could transform Comma separated coordinates into Space separated coordinates, it can be replaced with a line geometry using the GeomatryReplacer (GML Encoding). I tried two ways to create Space separated coordinates.

CSV Reader and List Manipulation
1) Read the data with a CSV reader (uncheck "File Has Field Names"), skip the header row.
2) Replace useless attribute values (LineID, NumPoints) with empty strings (AttributeCreator).
3) Transform all attributes into a list attribute (ListPopulator).
4) Concatenate the list elements with white space as delimiter (ListCocnatenator).








TEXTLINE Reader and String Manipulation
1) Read the data with a TEXTLINE reader, skip the header row.
2) Split a row into useless columns and CSV coordinates part (StringSearcher).
3) Rename matched parts (AttributeRenamer).
4) Replace every comma with white space (StringReplacer).









And then, surround the Space separated coordinates with GML tags so that it can be replaced with a line geometry using the GeometryReplacer. This process is common to two ways above.
=====
2014-02-14: The GML fragment can be created directly on "Geometry Source" of the GeometryReplacer using the Text Editor. If you do so, the StringConcatenator can be removed.
=====










Both of them worked fine. Since the coordinate values had to be written into the destination data as attributes, I finally adopted the first way (CSV Reader and List Manipulation).

If "File Has Field Names" option was unchecked when adding the CSV reader, it would generate default attribute names such as "col0, col1, col2 ...". Therefore, all attributes can be transformed into a list attribute with the ListPopulator. It is the point of the first way.

Well, old Excel reader (FME 2013 or earlier) generated default attribute names which were formatted in "col_*" or "F*" (* is 1-based sequential number),  so it was possible to do the same trick after just creating a temporary attribute named "col_0" or "F0". But the current Excel reader (FME 2014) generates "A, B, C..." (same as Excel column names) by default. The trick cannot be applied easily to Excel spread sheet now. > Default Attribute Names of XLSXR in FME 2014

Scripting is also possible.
-----
# Python Example
import fmeobjects
def createLine(feature):
    i = 2
    while True:
        x = feature.getAttribute('col%d' % i)
        y = feature.getAttribute('col%d' % (i + 1))
        if not x or not y:
            break
        feature.addCoordinate(float(x), float(y))
        i += 2
-----
# Tcl Example
proc createLine {} {
    for {set i 2} {1} {set i [expr $i + 2]} {
        set x [FME_GetAttribute "col$i"]
        set y [FME_GetAttribute "col[expr $i + 1]"]
        if {![string is double -strict $x] || ![string is double -strict $y]} {
            break
        }
        FME_Coordinates addCoord $x $y
    }
}
-----

No comments:

Post a Comment