MeasureGenerationFromZ
From fmepedia
| Table of contents |
Overview
The FME geometry model supports attaching measures on to features; however the only transformer to do this creates the measures as distances along the feature. In some cases a user may wish to transfer Z values to a measure, and this is what the MeasureGenerationFromZ custom transformer does.
Input
This transformer accepts as input any feature that may legitimately have a measure attached; points, lines, areas, text features.
All other geometry types are filtered out and returned via the Invalid_Geometry port.

Above: Input features should have a Z value.
Output
The output from this transformer is the same set of features, but with a set of measures attached.

Above: Output features have their Z values as measures (nb: features are normally still 3D on output - I made these 2D just to emphasize the point).
Detailed Description
As you may notice, this transformer is a classic example of a looping transformer, as it loops through every vertex in a feature collecting Z values in a list before going on to process them.

Above: The custom transformer definition.
The first thing the transformer does is filter out invalid geometries with the GeometryFilter transformer. For valid features it calculates the number of vertices using the CoordinateCounter transformer, so that we know how many times to repeat the loop. An AttributeCreator creates a loop counter attribute so we can keep count of how many times we have looped, plus resets the list of Z values back to a null string.

Above: The first section of transformer that filters out bad geometry and sets up loop management attributes.
The next section is the meat of the loop, but it is surprisingly simple.

Above: The looping section of the transformer.
First off in the loop section we fetch the next Z value with a CoordinateFetcher transformer. We know which is the next vertex by the value of the loop counter attribute (below):
Now we add this value to a comma-separated list of Z values using a Concatenator; essentially we're creating a string of Z values. Next we increment the loop counter by 1, to denote we've done this index (actually in the workspace these two steps are the other way around, but it doesn't really matter).
Then we use a Tester to check whether the loop counter = number of vertices. If not then there are more Z values to fetch and so we loop back to get the next one.
If the looping is complete, then we move onto the next step; turning the Z values string into true measures.

Above: The section that converts Z values into measures.
This section is remarkably simple too, thanks to the little-known ListMeasureSetter transformer (many transformers like this are little-known because they are less used - but when you do need one, they are extremely useful).
The first thing to do is remove an extra comma character from the front of the string, which is done with a StringReplacer.
Next the comma-separated list is turned into a true FME list using an AttributeSplitter transformer.
Finally the list is converted into true measures using the ListMeasureSetter.
The final section is just a cleanup of temporary attributes - the Counters and the list:

Above: It's important to cleanup attributes you no longer require - for both the sake of tidiness, and for performance reasons!
Here we clean up temporary attributes. Because we sensibly named all the temporary attributes with the prefix _MEAS we can remove them easily with an AttributeExpressionRemover. The temporary list can be removed with a ListRemover.
One final interesting point. Did you notice how the main output port is located half-way up the canvas, rather than next to where it is connected? That's because the location of the port determines it's position on the transformer. By putting the 'Output' port above the 'Invalid_Geometry' port, it will also appear above it on the transformer itself.

Above: The transformer in a canvas. Notice how the 'OUTPUT' output port is uppermost.

