2014-09-20

RandomPointGenerator

I created a custom transformer named RandomPointGenerator, which creates random points within entire input area features.
Find the transformer in Transformer Gallery (FME Store / Pragmatica).
FME 2014 SP3 build 14391

The implementation has been inspired by this thread in FME Community Answers.
Stratified random point in FME

Here, I illustrate outline of the procedure.

1. Input areas example.
Assume that these areas belong to a same group; these could be parts of an aggregated feature; there may be overlapped areas.











2. Resolve the overlapped area; calculate area for every area.

Deaggregator
AreaOnAreaOverlayer
AreaCalculator







3. Create bounding boxes for each individual area.

BoundingBoxReplacer









4. Dissolve the boxes, and create bounding boxes again; calculate area for every box.

Dissolver
BoundingBoxReplacer
AreaCalculator







5. Compute preferable number of points for each box  (based on the area calculation results and the required number of points), and then randomly create points within the boxes, so that the density will be approximately identical.

StatisticsCalculator
BoundsExtractor
AttributeCreator
ExpressionEvaluator
VertexCreator
Cloner
Offsetter



6. Filter the points by the original areas.

SpatialFilter









7. Randomly take points of specified number.

ExpressionEvaluator
Sorter
Sampler

2014-09-19

Concatenate Attribute Values based on Attribute List Parameter

A custom transformer can receive space delimited attribute names through "Attribute List (space delimited)" type user parameter.












Typically, a parameter of this type would be used to link to "Group By" of transformer(s) in the custom transformer. In such a case, it's not necessary to retrieve values of the attributes.
But there could also be some cases where those values are necessary. e.g. use concatenated attribute values as Counter Name of a Counter.

Value of the parameter is a string. If specified attributes are "attr1", "attr2", and "attr3", for example, the value of parameter will be "attr1 attr2 attr3" (space delimited attribute names). And if an attribute name contains white spaces, it will be quoted by double quotations.

I think Tcl scripting is an easy way to concatenate specified attribute values.
First, use a ParameterFetcher to store the parameter value (i.e. specified attribute names) as an attribute. e.g. named "_attr_names".
And then, use a TclCaller with this script to create a concatenated string.
If no attributes were specified, this procedure returns an empty string.
-----
proc concatAttributeValues {} {
    set values {}
    foreach attr [FME_GetAttribute "_attr_names"] {
        lappend values [FME_GetAttribute $attr]
    }
    return [join $values {_}]
}
-----

It worked fine even if specified attribute names contain white spaces.









FME 2014 SP3 build 14391

2014-09-17

Computational Error in DMSCalculator

The DMSCalculator is useful to convert decimal degree value to degrees, minutes and seconds. But there may be cases where the slight computational error causes a trouble.




















=====
2014-10-03: I had discussed about the computational error in the DMSCaluculator (Version 0) with Safe's developer, then the new DMSCaluclator (Version 1) has become available in FME 2015 Beta build 15187. It's better on handling the computational error than the previous version, you will not need to consider the following workaround, in FME 2015.
=====
Although computational error cannot be avoided, there are ways to reduce it in some cases.
In the DMS calculation, I prefer to define math expressions myself, rather than using the DMSCalculator, so that the computational error can be reduced.
For example:

1) ExpressionEvaluator









2) AttributeCreator
=====
2014-09-24: Sorry, I didn't take care of negative source values - i.e. south/west hemisphere latitude/longitude. I'm living in north/east hemisphere of the earth.
Try these expressions for calculating minutes and seconds, if the source may be negative.
When the source is negative, a minus sign will be added to degrees value only.
-----
_minutes: @int(@abs(@Value(_seconds)))%3600/60
_seconds: @fmod(@abs(@Value(_seconds)),60)
=====












3) Result





















(FME 2014 SP3 build 14391)

2014-09-11

Transform 3D Triangular Polygons into TIN Surface

Assume that the source polygons are clean. i.e.
- There are no gaps and no overlaps between adjoining triangles.
- Common vertex of adjoining triangles has same elevation (z-coordinate).

There is a solution in this article.
How to clip TIN Surfaces

Summary:
1) FaceReplacer replaces the triangular polygons with faces.
2) Aggregator creates a multi-surface from the faces.
3) Triangulator transforms the multi-surface into a TIN surface.
If orientation of triangles could be Right Hand Rule, their orientation should be changed to Left Hand Rule before the FaceReplacer.

The purpose of the article is not to create new TIN surface, is to clip a given TIN surface. So, the solution is appropriate one. But it's not so efficient for newly creating a TIN surface based on millions triangular polygons.
If you allow that the original triangle shapes will not be preserved exactly as parts of the resulting TIN, this may be a much more efficient approach.

1) Chopper decomposes the triangles into vertex points.
2) CoordinateExtractor extracts x, y of each point.
3) AttributeRounder rounds x, y to avoid mismatching caused by slight computational error.
4) StringConcatenator concatenates x, y to create a string value.
5) DuplicateRemover removes duplicate points using the coordinate string as key.
6) TINGenerator creates a TIN surface based on the points.
In general, the Matcher can be used to remove duplicate points. But it's too inefficient (consumes long time and huge memory space) if there are millions points.

There could be more efficient solutions. If you know, please inform to me!

FME 2014 SP3 build 14391

2014-09-06

Split Polygons Retaining Attributes

I needed to split given land use polygons (Esri Shape format) according to actual land usage which can be guessed based on images taken by a satellite.

At first, I planned to split the polygons with the Cut Polygons tool in ArcGIS.
But the client frequently requests to me modifying the cutting lines. Once I cut a polygon with the tool, I have to move 2 lines simultaneously without any gaps to modify the line, since the line immediately becomes boundaries shared by adjoining areas. It's so troublesome.

Therefore, I stopped using the Cut Polygons tool. I decided to create a new layer which represent cutting lines using ArcMap, and create split polygons as new dataset using FME.








Splitting polygons is easy. Intersect the polygons with the cutting lines, and build areas from the Intersected lines.








But the step cannot retain attributes of the original polygons. To retain attributes, migrate attributes of the original polygons based on spatial relationships.













Modifications of the cutting lines became much easier by this method.
FME 2014 SP3 build 14391