Hi @jdh, if you eventually need to remove the vertex, how will you go about it without breaking up the polygon?
Hi @jdh, if you eventually need to remove the vertex, how will you go about it without breaking up the polygon?
Since there are several thousand polygons, some of which are quite complex, I'm looking for a solution that works on the polygons individually, rather than the blocking explode/reconstruct option.
Â
What I had hoped to do, was identify the index of the vertex to remove, use the VertexCreator Replace Point at Index to set it to NaN and then the GeometryValidator to remove the NaN.
Â
Â
Since there are several thousand polygons, some of which are quite complex, I'm looking for a solution that works on the polygons individually, rather than the blocking explode/reconstruct option.
Â
What I had hoped to do, was identify the index of the vertex to remove, use the VertexCreator Replace Point at Index to set it to NaN and then the GeometryValidator to remove the NaN.
Â
Â
very nifty, but if you do match the index how are you going to use it in the VertexCreator? it only accepts parameter values or direct input, so an attribute value wont help....
Â
Â
very nifty, but if you do match the index how are you going to use it in the VertexCreator? it only accepts parameter values or direct input, so an attribute value wont help....
Â
Â
The was my road block, and why I posted the question, hoping someone else has a brilliant solution.
Â
Â
Hi @jdh, I have no ideas except PythonCaller scripting.
import fme
import fmeobjects
class FeatureProcessor(object):
    def __init__(self):
        self.points = Â]
        self.polygons = /]
       Â
    def input(self, feature):
        geomType = feature.getGeometryType()
        if geomType == fmeobjects.FME_GEOM_POINT:
            self.points.append(feature)
        elif geomType == fmeobjects.FME_GEOM_POLYGON:
            self.polygons.append(feature)
           Â
    def close(self):
        points = set(Âp.getCoordinate(0) for p in self.points])
        for polygon in self.polygons:
            vertices = polygon.getAllCoordinates()
            vertices = .p for p in vertices if p not in points]
            if verticesÂ0] != vertices -1]:
                vertices.append(verticesr0])
            boundary = fmeobjects.FMELine(vertices)
            polygon.setGeometry(fmeobjects.FMEPolygon(boundary))
            self.pyoutput(polygon)
If it's guaranteed that all the points are input before the first polygon, you can modify the script so that the "input" method processes one by one whenever it receives a polygon feature.Depending on the data condition, it might be necessary to snap each point to the closest polygon vertex beforehand, in order to absorb a tolerance between them, like this.
Hi @jdh, I have no ideas except PythonCaller scripting.
import fme
import fmeobjects
class FeatureProcessor(object):
    def __init__(self):
        self.points = Â]
        self.polygons = /]
       Â
    def input(self, feature):
        geomType = feature.getGeometryType()
        if geomType == fmeobjects.FME_GEOM_POINT:
            self.points.append(feature)
        elif geomType == fmeobjects.FME_GEOM_POLYGON:
            self.polygons.append(feature)
           Â
    def close(self):
        points = set(Âp.getCoordinate(0) for p in self.points])
        for polygon in self.polygons:
            vertices = polygon.getAllCoordinates()
            vertices = .p for p in vertices if p not in points]
            if verticesÂ0] != vertices -1]:
                vertices.append(verticesr0])
            boundary = fmeobjects.FMELine(vertices)
            polygon.setGeometry(fmeobjects.FMEPolygon(boundary))
            self.pyoutput(polygon)
If it's guaranteed that all the points are input before the first polygon, you can modify the script so that the "input" method processes one by one whenever it receives a polygon feature.Depending on the data condition, it might be necessary to snap each point to the closest polygon vertex beforehand, in order to absorb a tolerance between them, like this.
Thanks takashi.  I've passed this on to my team.
You ca also use python factory in a python caller and be able to use the VertexCreatorFactory.
Please refer to the answer to this question to see how to do it.
Your factory string will look like this:
FACTORY_DEF * VertexCreatorFactory                                     \
   FACTORY_NAME VertexCreator                                          \
   INPUT  FEATURE_TYPE Input_Port                                      \
   MODE REPLACE_AT_INDEX                                               \
   INDEX <index>                                                       \
   CONTINUE_ON_ERROR YES                                               \
   XVAL "<x>"                                                          \
   YVAL "<y>"                                                          \
   ZVAL "<z>"                                                          \
   OUTPUT OUTPUT FEATURE_TYPE VertexCreator_OUTPUT
You'll have to dynamically replace the <index> by the value of the attribute value holding your point index to replace and <x>, <y> and <z> by the coordinates values.
Regards,
Larry
You ca also use python factory in a python caller and be able to use the VertexCreatorFactory.
Please refer to the answer to this question to see how to do it.
Your factory string will look like this:
FACTORY_DEF * VertexCreatorFactory                                     \
   FACTORY_NAME VertexCreator                                          \
   INPUT  FEATURE_TYPE Input_Port                                      \
   MODE REPLACE_AT_INDEX                                               \
   INDEX <index>                                                       \
   CONTINUE_ON_ERROR YES                                               \
   XVAL "<x>"                                                          \
   YVAL "<y>"                                                          \
   ZVAL "<z>"                                                          \
   OUTPUT OUTPUT FEATURE_TYPE VertexCreator_OUTPUT
You'll have to dynamically replace the <index> by the value of the attribute value holding your point index to replace and <x>, <y> and <z> by the coordinates values.
Regards,
Larry
Hi @larry,
Â
Â
That's a good workaround to the initial problem of the VertexCreator not accepting attributes.   I was able to get it functioning with a little help from @DaveAtSafe.   We'll have to run some tests to see if this solution is more or less efficient than @takashi's.