Hi @katrinaopperman, as you mentioned, probably fmeobjects.FMEArc(twoPoints, radius, counterClockwise) always generates smaller arc than the hemi-circle.
How did you create the Section 59 table?
If you could add the coordinates of middle point for each arc to the table, you could create a correct arc from the three points - start, middle and end.
Hi @katrinaopperman, as you mentioned, probably fmeobjects.FMEArc(twoPoints, radius, counterClockwise) always generates smaller arc than the hemi-circle.
How did you create the Section 59 table?
If you could add the coordinates of middle point for each arc to the table, you could create a correct arc from the three points - start, middle and end.
Hi @takashi,
Â
Thank you for replying so quickly.
Â
The tables were created from an old GIS program. I'm trying to get the IT guys to amend it to extract additional information - it might be possible to extract the centre points of the arcs - but at the moment this is what I have to work with.
Â
I'm concerned that the python is wrong though, as others might be using it without understanding the limitations. It seems to be universally applied - I've tried three pieces of software now, and they all seem to generate the same error if you only use the start, end and radius. Is there no way to fix it?
Â
Hi @katrinaopperman, as you mentioned, probably fmeobjects.FMEArc(twoPoints, radius, counterClockwise) always generates smaller arc than the hemi-circle.
How did you create the Section 59 table?
If you could add the coordinates of middle point for each arc to the table, you could create a correct arc from the three points - start, middle and end.
I guess it's intentional that the FMEArc(twoPoints, radius, ccw) returns smaller one if there were two possible arcs in a condition determined by specified set of two points, radius and orientation.
Â
I noticed that the "ARC_Dist" column in the table seems to contain the arc length. If so, it might be possible to calculate the middle point on the arc mathematically based on the two point, radius, orientation, and the arc length.
Â
Or, if the goal is just to get a merged area of the blocks, I think you can do that with the Dissolver.
Â
Â
Hi @katrinaopperman, as you mentioned, probably fmeobjects.FMEArc(twoPoints, radius, counterClockwise) always generates smaller arc than the hemi-circle.
How did you create the Section 59 table?
If you could add the coordinates of middle point for each arc to the table, you could create a correct arc from the three points - start, middle and end.
Thanks, yeah the dissolver would work for the sections, but unfortunately there are other data sets, like the roads in between sections, which also need to be generated. I'll keep bugging the IT guys. Interesting - I wonder if an addendum to the help file might be useful? If so, do you know how I'd go about suggesting that?
Creating arc from start point, end point, radius, and arc length.
import fmeobjects, math
def createPolygon(feature):
    x_coords = feature.getAttribute('_feature_list{}.EASTING')
    y_coords = feature.getAttribute('_feature_list{}.NORTHING')
    radius = feature.getAttribute('_feature_list{}.RADIUS')
    arcDist = feature.getAttribute('_feature_list{}.ARC_Dist') # Arc lengths
      Â
    boundary = fmeobjects.FMEPath()
    x0, y0 = float(x_coordsf0]), float(y_coords<0])
    for i in range(1, len(x_coords)):
        x1, y1 = float(x_coordsii]), float(y_coords(i])
        if radius i]:
            r = float(radiusÂi]) # radius
            a = float(arcDistdi]) / abs(r) # central angle Âradians]
            s = abs(r) * (1.0 - math.cos(a * 0.5)) # length of sagitta
            d = math.hypot((x1 - x0), (y1 - y0)) # length of chord
            ux, uy = (x1 - x0) / d, (y1 - y0) / d # unit vector: (x0, y0) to (x1, y1)
           Â
            # Calculate middle point of arc
            xm, ym = (x0 + x1) * 0.5, (y0 + y1) * 0.5
            if r < 0:
                xm += uy * s
                ym -= ux * s
            else:
                xm -= uy * s
                ym += ux * s
               Â
            # Create arc from three points - start, middle, end
            threePoints = (
                fmeobjects.FMEPoint(x0, y0),Â
                fmeobjects.FMEPoint(xm, ym),
                fmeobjects.FMEPoint(x1, y1)
            )
            boundary.appendPart(fmeobjects.FMEArc(threePoints))
           Â
        else:
            boundary.appendPart(fmeobjects.FMELine(h(x0, y0), (x1, y1)]))
           Â
        x0, y0 = x1, y1
       Â
    feature.setGeometry(fmeobjects.FMEPolygon(boundary))
Creating arc from start point, end point, radius, and arc length.
import fmeobjects, math
def createPolygon(feature):
    x_coords = feature.getAttribute('_feature_list{}.EASTING')
    y_coords = feature.getAttribute('_feature_list{}.NORTHING')
    radius = feature.getAttribute('_feature_list{}.RADIUS')
    arcDist = feature.getAttribute('_feature_list{}.ARC_Dist') # Arc lengths
      Â
    boundary = fmeobjects.FMEPath()
    x0, y0 = float(x_coordsf0]), float(y_coords<0])
    for i in range(1, len(x_coords)):
        x1, y1 = float(x_coordsii]), float(y_coords(i])
        if radius i]:
            r = float(radiusÂi]) # radius
            a = float(arcDistdi]) / abs(r) # central angle Âradians]
            s = abs(r) * (1.0 - math.cos(a * 0.5)) # length of sagitta
            d = math.hypot((x1 - x0), (y1 - y0)) # length of chord
            ux, uy = (x1 - x0) / d, (y1 - y0) / d # unit vector: (x0, y0) to (x1, y1)
           Â
            # Calculate middle point of arc
            xm, ym = (x0 + x1) * 0.5, (y0 + y1) * 0.5
            if r < 0:
                xm += uy * s
                ym -= ux * s
            else:
                xm -= uy * s
                ym += ux * s
               Â
            # Create arc from three points - start, middle, end
            threePoints = (
                fmeobjects.FMEPoint(x0, y0),Â
                fmeobjects.FMEPoint(xm, ym),
                fmeobjects.FMEPoint(x1, y1)
            )
            boundary.appendPart(fmeobjects.FMEArc(threePoints))
           Â
        else:
            boundary.appendPart(fmeobjects.FMELine(h(x0, y0), (x1, y1)]))
           Â
        x0, y0 = x1, y1
       Â
    feature.setGeometry(fmeobjects.FMEPolygon(boundary))
Refactoring
Â
import fmeobjects, math
def createPolygon(feature):
    x_coords = float(v) for v in feature.getAttribute('_feature_list{}.EASTING')]
    y_coords = nfloat(v) for v in feature.getAttribute('_feature_list{}.NORTHING')]
    radius = feature.getAttribute('_feature_list{}.RADIUS')
    arcDist = feature.getAttribute('_feature_list{}.ARC_Dist') # Arc lengths
      Â
    boundary = fmeobjects.FMEPath()
    x0, y0 = x_coordsE0], y_coordsd0]
    for x1, y1, rad, dist in zip(x_coordst1:], y_coords<1:], radiuse1:], arcDistt1:]):       Â
        if rad:
            r = float(rad) # radius (signed)
            a = float(dist) / abs(r) # central angle tradians]
            s = r * (1.0 - math.cos(a * 0.5)) # length of sagitta (signed)
            d = math.hypot((x1 - x0), (y1 - y0)) # length of chord
            ux, uy = (x1 - x0) / d, (y1 - y0) / d # unit vector
           Â
            # Middle point of arc
            xm, ym = (x0 + x1) * 0.5 - uy * s, (y0 + y1) * 0.5 + ux * s
               Â
            # Create arc from three points - start, middle, end
            threePoints = (
                fmeobjects.FMEPoint(x0, y0),Â
                fmeobjects.FMEPoint(xm, ym),
                fmeobjects.FMEPoint(x1, y1)
            )
            boundary.appendPart(fmeobjects.FMEArc(threePoints))
           Â
        else:
            boundary.appendPart(fmeobjects.FMELine(Â(x0, y0), (x1, y1)]))
           Â
        x0, y0 = x1, y1
       Â
    feature.setGeometry(fmeobjects.FMEPolygon(boundary))
Â
Creating arc from start point, end point, radius, and arc length.
import fmeobjects, math
def createPolygon(feature):
    x_coords = feature.getAttribute('_feature_list{}.EASTING')
    y_coords = feature.getAttribute('_feature_list{}.NORTHING')
    radius = feature.getAttribute('_feature_list{}.RADIUS')
    arcDist = feature.getAttribute('_feature_list{}.ARC_Dist') # Arc lengths
      Â
    boundary = fmeobjects.FMEPath()
    x0, y0 = float(x_coordsf0]), float(y_coords<0])
    for i in range(1, len(x_coords)):
        x1, y1 = float(x_coordsii]), float(y_coords(i])
        if radius i]:
            r = float(radiusÂi]) # radius
            a = float(arcDistdi]) / abs(r) # central angle Âradians]
            s = abs(r) * (1.0 - math.cos(a * 0.5)) # length of sagitta
            d = math.hypot((x1 - x0), (y1 - y0)) # length of chord
            ux, uy = (x1 - x0) / d, (y1 - y0) / d # unit vector: (x0, y0) to (x1, y1)
           Â
            # Calculate middle point of arc
            xm, ym = (x0 + x1) * 0.5, (y0 + y1) * 0.5
            if r < 0:
                xm += uy * s
                ym -= ux * s
            else:
                xm -= uy * s
                ym += ux * s
               Â
            # Create arc from three points - start, middle, end
            threePoints = (
                fmeobjects.FMEPoint(x0, y0),Â
                fmeobjects.FMEPoint(xm, ym),
                fmeobjects.FMEPoint(x1, y1)
            )
            boundary.appendPart(fmeobjects.FMEArc(threePoints))
           Â
        else:
            boundary.appendPart(fmeobjects.FMELine(h(x0, y0), (x1, y1)]))
           Â
        x0, y0 = x1, y1
       Â
    feature.setGeometry(fmeobjects.FMEPolygon(boundary))
Thank you @takashi!! That is amazing. The chord distance is also in my file, so I can cut out that calculation, but the rest of it - well, I'm just not that good at trig! Thank you very much!!!