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!.
Solved! Go to Solution.
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:
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
Maybe it´s good to read these topics first:
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.
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:
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
Thanks - that got me running just fine. I owe you.
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...
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.
Thanks Dan Patterson for explaining the reason for checking the pnt object.
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.