2014-11-15

Sorting Lines Divided by PointOnLineOverlayer

PointOnLineOverlayerによって分割されたラインの並べ替え

The PointOnLineOverlayer can be used to divide a line at one or more points located onto the line. But the output order of the resultant lines is arbitrary, they will not be sorted along the original line in the direction to the end node from the start node.
The outputting order may not be important in many cases, but there could also be some cases where sorting is required.
PointOnLineOverlayerは、ライン上にあるひとつ以上のポイントによってそのラインを分割するのに使えます。しかし、作成されたラインの出力順は任意であり、元のラインの始点から終点の方向の順になるとは限りません。
多くの場合、出力順は重要ではないかも知れませんが、並べ替えが必要になる場合もあり得ます。

























If the original line is always pointing to east (max X) from west (min X) like the image, divided lines can be sorted by the X coordinate of the start node. In general cases, similarly, they can be sorted by measure values of their start nodes.
1) Insert a MeasureGenerator before the PointOnLineOverlayer.
2) Add a MeasureExtractor to extract measure value of the start node for each resulting line.
Type: Individual Vertex by Index
Destination Attribute of Point or Vertex: _point_measure
Index: 0
3) Add a Sorter to sort the lines by "_point_measure" ascending.
Naturally, use the original line ID attribute as the primary sort key if there are multiple input lines.
図のように、元のラインが常に西(X最小)から東(X最大)の方向を向いているならば、分割されたラインは始点のX座標によって並べ替えることができます。同様に、一般的にはそれらの始点のメジャー値によって並べ替えられます。
1) MeasureGeneratorをPointOnLineOverlayerの前に挿入する。
2) MeasureExtractorを追加し、結果として得られた各ライン始点のメジャー値を抽出する。
Type: Individual Vertex by Index
Destination Attribute of Point or Vertex: _point_measure
Index: 0
3) Sorterを追加し、"_point_measure"の昇順によってラインを並べ替える。
入力ラインが複数ある場合は、当然、元のラインのID属性を第一ソートキーとして使用します。

























Another approach.
Once transform the divided lines into a path (a line consisting of one or more segment lines) using a LineJoiner, and then split again the path into individual segment lines with the PathSplitter. LineJointer parameter setting is:
Preserve Original Orientation: yes
Input Feature Topology: End noded
Preserve Lines as Path Segments: yes
別のアプローチ。
LineJoinerを使って、一旦、分割されたラインをひとつのパス(ひとつ以上のセグメントラインで構成されるライン)に変換し、PathSplitterによって再度それを個々のセグメントラインに分割します。LineJoinerのパラメーター設定は次のとおり。
Preserve Original Orientation: yes
Input Feature Topology: End noded
Preserve Lines as Path Segments: yes

Notes for the another approach:
1) Since the LineJoiner removes all the attributes except ones that were specified to the "Group By" parameter, you will have to restore the attributes afterward if necessary (FeatureMerger etc.).
-----
I've overlooked a way to retain attributes when using the LineJoiner.
- Specify a list name to the "List Name" parameter of the LineJoiner.
- Add a ListIndexcer to demote attributes of the list element.
- Remove the list by an AttributeRemover if you don't use it any more.
a little bit troublesome...
-----
2) In this case, the PathBuilder cannot be used to transform the divided lines into a path, since the order of segments output from the PointOnLineOverlayer is not preferable.
3) If an input line could be a path, it will have to be transformed into a non-path line beforehand. Because the PointOnLineOverlayer preserves path segment boundaries and the PathSplitter will split the path at segment boundaries including the original ones.
別のアプローチに関する注:
1) LineJoinerは"Group By"パラメーターに設定したもの以外の全ての属性を削除するので、必要に応じて後でそれを復元しなければなりません(FeatureMergerなど)。
-----
LineJoinerを使う際に属性を維持する方法を見落としていました。
- LineJoinerの"List Name"パラメーターにリスト名を指定する。
- ListIndexcerを追加してリストの要素を通常の属性に変換する。
- それ以降リストが必要なければ、AttributeRemoverによって削除する。
ちょっと面倒な。。。
-----
2) この場合、PointOnLineOverlayerから出力されるセグメントの順番が望ましいものではないので、PathBuilderは分割されたラインをパスに変換するのに使用できません。
3) 入力ラインがパスである可能性がある場合は、それは、事前にパスではないラインに変換する必要があります。PointOnLineOverlayerはパスのセグメント境界を維持し、PathSplitterはオリジナルを含むセグメント境界によってパスを分割するからです。

Oops, looks like there isn't a simple way to transform a path to a non-path line.
The PathSplitter+LineJoiner does that, but it requires an extra procedure to restore attributes.
Use Python?
おっと、パスを非パスラインに変換する簡単な方法はないみたいだ。
PathSplitter+LineJoinerはそれをしますが、属性を復元するための余分な手続きを必要とします。
Pythonを使う?
-----
# Script Example for PythonCaller
# Converts Path to Line.
import fmeobjects
def convertToLine(feature):
    geom = feature.getGeometry()
    if isinstance(geom, fmeobjects.FMEPath):
        feature.setGeometry(fmeobjects.FMEGeometryTools().convertToLine(geom))
-----

FME 2014 SP4 build 14433

No comments:

Post a Comment