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.
RouteID | Ports | Prefectures |
---|---|---|
1 | Hachinohe,Tomakomai,Kawasaki | Aomori,Hokkaido,Kanagawa |
2 | Osaka,Naha,Hakata,Naha | Osaka,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