How to adjust polyline / polygon vertices in ArcMap 10.0

4309
7
Jump to solution
11-27-2014 08:01 AM
GaryCrowley
New Contributor II

Hi - I am new to using Python and have a database with a lot of polygons and polylines that need to have their vertex coordinates adjusted based on another calculation.  I cannot add new fields to the tables, so I want to edit them directly using arcpy code.

I have looked around the web and have not found a clear (to me) procedure (using Arcmap 10.0) to edit and save the new vertex coordinates for each feature.

Our company won't be upgrading Arcmap for at least 6 months or more, so using the da tools in 10.1 is out.

BTW, there are no rings to iterate thru. 

I would be happy to buy someone a virtual beer for their assistance.  Thanks a bunch!.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

OK, to throw in an example using 10.0 syntax (although in run it on 10.2.2) would be:

import arcpy

fc = r"C:\Forum\EditVertices\test.gdb\polygons"
oid = 2 # objectid to change geometry

# Identify the required fields
desc = arcpy.Describe(fc)
shapefieldname = desc.ShapeFieldName
oidfieldname= desc.OIDFieldName

# create a where clause
where = "{0} = {1}".format(arcpy.AddFieldDelimiters(fc, oidfieldname), oid)

# Create update cursor
rows = arcpy.UpdateCursor(fc, where_clause=where)

# Enter for loop for each feature/row
for row in rows:

    # Create the geometry object
    feat = row.getValue(shapefieldname)

    # create an array for the updated feature
    arr_feat = arcpy.Array()

    # Step through each part of the feature
    partnum = 0
    for part in feat:

        # create an array for the part
        arr_part = arcpy.Array()

        # Step through each vertex in the feature
        for pnt in feat.getPart(partnum):
            if pnt:
                x = pnt.X
                y = pnt.Y

                # do something with the point coordinates
                x += 5
                y += 5

                # add the point to the part array
                arr_part.add(arcpy.Point(x, y))

            else:
                # If pnt is None, this represents an interior ring
                pass

        # add part to feature array
        arr_feat.add(arr_part)
        partnum += 1

    # create polygon
    polygon = arcpy.Polygon(arr_feat)

    # set polygon to shapefield and update row
    row.setValue(shapefieldname, polygon)
    rows.updateRow(row)

What happens in the code is that the polygon with OBJECTID is moved (x+5 and y+5). See image below:

MoveVertices.png

If you want to edit vertices of a polygon individually, make sure that the first and last point coincide to force closure of the polygon.

Kind regards, Xander

View solution in original post

7 Replies
XanderBakker
Esri Esteemed Contributor

Maybe it´s good to read these topics first:

reading geomeries and writing geometries.

GaryCrowley
New Contributor II

Yes, I read those and have no trouble reading the vertex information.  It's the part about creating a new point in the array and reassigning the array to the original feature that is stumping me.  Thanks.

0 Kudos
XanderBakker
Esri Esteemed Contributor

OK, to throw in an example using 10.0 syntax (although in run it on 10.2.2) would be:

import arcpy

fc = r"C:\Forum\EditVertices\test.gdb\polygons"
oid = 2 # objectid to change geometry

# Identify the required fields
desc = arcpy.Describe(fc)
shapefieldname = desc.ShapeFieldName
oidfieldname= desc.OIDFieldName

# create a where clause
where = "{0} = {1}".format(arcpy.AddFieldDelimiters(fc, oidfieldname), oid)

# Create update cursor
rows = arcpy.UpdateCursor(fc, where_clause=where)

# Enter for loop for each feature/row
for row in rows:

    # Create the geometry object
    feat = row.getValue(shapefieldname)

    # create an array for the updated feature
    arr_feat = arcpy.Array()

    # Step through each part of the feature
    partnum = 0
    for part in feat:

        # create an array for the part
        arr_part = arcpy.Array()

        # Step through each vertex in the feature
        for pnt in feat.getPart(partnum):
            if pnt:
                x = pnt.X
                y = pnt.Y

                # do something with the point coordinates
                x += 5
                y += 5

                # add the point to the part array
                arr_part.add(arcpy.Point(x, y))

            else:
                # If pnt is None, this represents an interior ring
                pass

        # add part to feature array
        arr_feat.add(arr_part)
        partnum += 1

    # create polygon
    polygon = arcpy.Polygon(arr_feat)

    # set polygon to shapefield and update row
    row.setValue(shapefieldname, polygon)
    rows.updateRow(row)

What happens in the code is that the polygon with OBJECTID is moved (x+5 and y+5). See image below:

MoveVertices.png

If you want to edit vertices of a polygon individually, make sure that the first and last point coincide to force closure of the polygon.

Kind regards, Xander

GaryCrowley
New Contributor II

    Thanks - that got me running just fine.  I owe you.

images?q=tbn:ANd9GcRw97KAjyAP9QeIJFSTwiOspCohOqfbKo-_DU6JvD-GSHLe9qcz

In your snippet:

        for pnt in feat.getPart(partnum): 

               if pnt: 

what is  if pnt: checking for?  This seems to be a shortened version of if pnt = something.  Can you elaborate?  Sorry, I'm a Python newbie...

images?q=tbn:ANd9GcSO240-AH8n61U2Bs7E8DqaOca7OPBbdb7qFUVjVtHh5-kCuR5R

DanPatterson_Retired
MVP Emeritus

Xander's if pnt line checks to see if the object in the list is a point object...if it isn't, it skips the "if" section.  This can occur when a feature is a multipart feature and/or has inner rings.

0 Kudos
XanderBakker
Esri Esteemed Contributor

Thanks Dan Patterson‌ for explaining the reason for checking the pnt object.

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi Gary Crowley‌, Thanx for the virtual beer!

For now I think it's best to mark the answer as correct so other people may find the solution more easy.