Solved

Adjust positions of non-end nodes in a line?

  • 11 January 2017
  • 3 replies
  • 3 views

Badge +1

I have the following issue:

A bridge and the road below, standard 2D lines, both have nodes with identical coordinates - i.e. they share a "node location". When I want to output this dataset to OSM XML, the writer creates a connection in this point, even though they are not connected in realit". I've tried to separate them by Z-coordinate, but that had no effect. Therefore, my guess is that it creates a "node cache" with the coordinates as key, which means they will share a node because they share a coordinate.

With this in mind, my solution would be to slightly adjust the position of these internal nodes that overlap. Probably with just a minor change(cm? mm?), the nodes will not be cached to the same location. However, I've got no idea how to A) access all non-start or non-end nodes of a line and subsequently B) slightly and randomly alter their position.

icon

Best answer by redgeographics 11 January 2017, 10:28

View original

3 replies

Badge +16

Hi @fhilding, For A see the CoordinateExtractor, mode Specify Coordinate, Coordinate Index =-1 and for B you can use the RandomNumberGenerator to generate a value between 0.001 and 0.010 (if your data is in meters) to add to the last coordinate via the Offsetter transformer.

Hope this helps.

Userlevel 5
Badge +25

An alternative approach would be to use the CoincidentPointOffsetter transformer from the FME Hub. Since it works on points only you'll have to deconstruct your lines and keep track of both a line id and a point id so you can later on reconstruct the lines using the PointConnector.

offset-points.fmw

Hope this helps.

Badge +1

I went the Python route on this, inspired by redgeographics. The following snippet did the trick:

(Although it corrects ALL internal nodes, the offset is so small that it's acceptable for the data provided.)

    line = feature.getGeometry()
    ptTupleList = line.getPoints()
    ptTupleListNoEnds = ptTupleList[1:len(ptTupleList)-1]
    randomDifference = 0
    while -0.01 < randomDifference < 0.01:
        randomDifference = random.uniform(-0.10,0.10)
    correctedPoints = []
    for point in ptTupleListNoEnds:
        point.setXYZ(point.getXYZ()[0]+randomDifference, point.getXYZ()[1], point.getXYZ()[2])
        correctedPoints.append(point)
    for i in range(len(correctedPoints)):
        line.setPointAt(i+1, correctedPoints[i].getXYZ())
    feature.setGeometry(line)
    #feature.setAttribute("corr",randomDifference)
    return feature

Reply