2014-02-02

Merge Two Lists so that Elements will be Alternate

(FME 2014 build 14234)

There is a dataset storing sea routes. Each feature has two attributes; "Ports" contains every port name on the route (departure port, 0 or more ports of call, arrival port), "Prefectures" contains prefecture names of the ports. Both of them are comma separated values.
RouteIDPortsPrefectures
1Hachinohe,Tomakomai,KawasakiAomori,Hokkaido,Kanagawa
2Osaka,Naha,Hakata,NahaOsaka,Okinawa,Fukuoka,Okinawa

Based on the dataset, I need to create an attribute whose format should be:
<port>(<prefecture>)-<port>(<prefecture>) ... -<port>(<prefecture>)

For example, the first route feature (RouteID = 1) finally should have an attribute which stores
"Hachinohe(Aomori)-Tomakomai(Hokkaido)-Kawasaki(Kanagawa)".

First, divide the feature flow into two streams, and create list attribute named "_list{}" in each stream.

1) Transform CSV port names into a list attribute
The following workflow creates a list attribute named "_list{}" which contains these elements.
_list{0} = Hachinohe
_list{1} = <missing>
_list{2} = -Tomakomai
_list{3} = <missing>
_list{4} = -Kawasaki
There are <missing> elements between every two ports; 2nd or later port names are headed by a hyphen. Be aware that _list{1} and _list{3} are missing.







2) Transform CSV prefecture names into a list attribute
The following workflow creates a list attribute named "_list{}" which contains these elements.
_list{0} = <empty>
_list{1} = (Aomori)
_list{2} = <empty>
_list{3} = (Hokkaido)
_list{4} = <empty>
_list{5} = (Kanagawa)
The list contains <empty> elements between every two prefectures; the first element is <empty>; every prefecture name is enclosed by parens.










Merge the two streams with a FeatureMerger, then the list attribute will contain these elements. i.e. prefecture names would be assigned into <missing> elements.
_list{0} = Hachinohe
_list{1} = (Aomori)
_list{2} = -Tomakomai
_list{3} = (Hokkaido)
_list{4} = -Kawasaki
_list{5} = (Kanagawa)









Finally concatenate the list elements with a ListConcatenator, then required attribute would be created.










The point is that the NullAttributeMapper in the first stream removes list elements which contain "[to_missing]", so that the FeatureMerger could assign prefecture names to <missing> elements.

Although Transformers can do that, scripting might be easier...
-----
# Python Script Example
import fmeobjects
def concatenatePorts(feature):
    ports = feature.getAttribute('Ports')
    prefs = feature.getAttribute('Prefectures')
    values = []
    for port, pref in zip(ports.split(','), prefs.split(',')):
        values.append('%s(%s)' % (port, pref))
    feature.setAttribute('_ports', '-'.join(values))
-----
# Tcl Script Example
proc concatenatePorts {} {
    set ports [FME_GetAttribute "Ports"]
    set prefs [FME_GetAttribute "Prefectures"]
    set values {}
    foreach port [split $ports {,}] pref [split $prefs {,}] {
        lappend values [format "%s(%s)" $port $pref]
    }
    return [join $values {-}]
}
-----

=====
2014-09-20: See also the ListMerger in FME Store / Pragmatica.
=====

No comments:

Post a Comment