Solved

Generate lines out of points depending on multiple attributes

  • 11 July 2018
  • 4 replies
  • 11 views

Badge

This seems like a fairly simple task but I'm struggling to think my way around the problem.

Middle point:

  • master = it's unique id
  • previous = the id of the point to the left of it
  • next = the unique id on the point to the right of it

How would I connect these points to form lines by relating the master, previous and next attributes.

icon

Best answer by takashi 14 July 2018, 10:36

View original

4 replies

Userlevel 5
Badge +25

Surprisingly tricky indeed, I came up with this, but I'm not sure it's the best way to do it. Now, I am assuming the situation is so complex we can't use the adjacent feature handling in the AttributeManager so I'm doing 2 FeatureJoins to get the previous and next coordinates, then build lines and remove duplicates through a LineCombiner.

connect-points.fmwt

Badge +3

@kyle_d_wade

Create a GroupBy column.

Merge the set to itself twice, master=Previous and Master=Next. Make sure to pass the GroupBy value.

Create an attribute like "nr" at merge output of master=Previous give it value 0 and at Master=Next give it value 2. At master itself nr=1.

Sort original set and both merged outputs by GroupBY and nr.

Now use point connector connection break by GroupBy.

Badge +22

The last time I encountered this scenario, I used a connected component graph in python,  but I don't think your requirements needs that complicated a structure.

 

 

Here's a quick and dirty version that should work,  though it will fail if your data references a missing point.

 

class FeatureProcessor(object):
    def __init__(self):
        #initialize reference dictionaries
        self.FeatureDict={}
        self.NeighbourDict={}
    
    def input(self,feature):
        #add each feature to the reference dictionaries, key for both is the ID
        ID = feature.getAttribute('master')
        Next = feature.getAttribute('next')
        self.FeatureDict[ID]=feature
        self.NeighbourDict[ID]=Next
   
   def close(self):
       #search for starting points, could also be previous is None, depending on the data
        for id, feature in self.FeatureDict.items():
            prev = feature.getAttribute('previous')
            if prev == '0':
                #create a new line
                line = fmeobjects.FMELine()
                line.appendPoint(feature.getGeometry())
                #find the next vertex and add it to the line, until there are no more vertixes to add
                nextId = self.NeighbourDict[id]
                while nextId !='0':
                    geom = self.FeatureDict[nextId].getGeometry()
                    line.appendPoint(geom)
                    nextId = self.NeighbourDict[nextId]
                
                #replace the original point geometry with the new line
                feature.setGeometry(line)
                self.pyoutput(feature)
Userlevel 2
Badge +17

Basically the same approach as @redgeographics's solution. If resulting lines won't touch each other at their end nodes, you can remove the ListCombiner (from FME Hub) and unset Group By in the LineCombiner.

Reply