span8
span4
span8
span4
# Python Script Example (PythonCaller) # Filters out spike vertices from input points and transforms remnants into lines without spikes. # Assuming that every input feature has a point geometry, # the features have a group ID attribute called "groupID" (positive integer), # the maximum spike angle is given by a user parameter called "SPIKEANGLE" (positive numeric), # and the order of input features is sorted by the group ID and connecting order. # Determination on whether a point is spike vertex will be performed by only the angle. # If you need to consider the spike length as well, modify and add some codes. # You can classify output features into points and lines using the GeometryFilter. import fme, fmeobjects, math class FeatureProcessor(object): def __init__(self): self.features, self.coords = [], [] # storage for input features and their coordinates self.groupID = -1 self.spikeAngle = float(FME_MacroValues['SPIKEANGLE']) def input(self, feature): # Retrieve group ID and coordinates from the input feature. gid = int(feature.getAttribute('groupID')) coord = feature.getCoordinate(0) # If the feature is the first one of a group, create and output line for the previous group, # clear the lists of features and coordinates, and update current group ID. if gid != self.groupID: self.outputLine() self.features, self.coords = [], [] self.groupID = gid # If the number of stored features is greater than 1, # determine wheter the last feature (point) in the lists is spike vertex or not. if 1 < len(self.features): x0, y0 = self.coords[-2][0], self.coords[-2][1] # second last point x1, y1 = self.coords[-1][0], self.coords[-1][1] # last point (candidate of spike vertex) x2, y2 = coord[0], coord[1] # current point (input feature) ax, ay = (x1 - x0), (y1 - y0) # vector: second last -> last bx, by = (x2 - x1), (y2 - y1) # vector: last -> current # Calculate the absolute angle formed by the two vectors. # If the angle is less than or equal to specified maximum spike angle, # output the last feature (point: x1,y1) and remove it from the lists. angle = 180 - abs(math.degrees(math.atan2(ax * by - ay * bx, ax * bx + ay * by))) if angle <= self.spikeAngle: self.pyoutput(self.features[-1]) # output the last feature (spike vertex) self.features.pop() self.coords.pop() # Append the input feature and its coordinates to the lists. self.features.append(feature) self.coords.append(coord) def outputLine(self): # Create a line geometry and set it to the first feature of the group, # then output the feature (line without spike). if 1 < len(self.features): self.features[0].setGeometry(fmeobjects.FMELine(self.coords)) self.pyoutput(self.features[0]) def close(self): # Create and output line for the final group. self.outputLine()
@takashi 's answer is a good one, but there is another way.
First you concatenate your input coordinates into a string (_coordinates).
Then
after the point is flagged, you extract and then concatenate its
coordinates. The two strings should be identical, and so all you need to
do is run them through a ListSearcher. Be sure to "Demote Found List Element".
I suspect this method
will be more efficient than takashi's for larger datasets as I'd hope
the ListSearcher is faster than the SpatialFilter which can be quite
resource intensive (and typically acts as a blocker for grouping purposes).
I've not tested it on larger datasets myself so may be wrong.
@jonathan_hrw, that's a good suggestion, agree that the ListSearcher could be more efficient than the SpatialFilter. The GeometryExtractor (Geometry Encoding: FME Binary) can also be used to create the search key :)
Attributes in a list transposed across as new columns in excel 5 Answers
How to Detect a Schema difference (Dataset1 has X attributes, Dataset2 has X+or-n attributes) 1 Answer
Creating a list from an attribute 2 Answers
Finding gaps in a list 4 Answers
How to turn elemtents of a list of dynamic length into attributes? 3 Answers
© 2019 Safe Software Inc | Legal