I am trying to make a polyline endpoint snapping tool in Python using ArcGIS 10. using a Search Cursor I read in the values to an array of line objects (which contain the feature id of the line, and two "EndPoint" objects – first and last – which contain the X and Y coord of each), then process some data interpolation of the points to give all points their correct values.
So far, that part works perfectly. However, when I try to go back and edit the shapefile, I can see the data that I am changing, but I can't seem to edit it.
Here is the code for updating the fields:
# --------------------------
#
# Update the file with the new EPs
#
# --------------------------
# Create update cursor
#
rows = arcpy.UpdateCursor(outputDirectory + "\\" + trails_fc + ".shp")
# Enter for loop for each feature/row
#
i = 0
for row in rows:
# Create the geometry object
#
feat = row.getValue(shapefieldname)
partnum = 0
if feat.getPart(partnum)[0].X != allLines[i].startEP.x:
arcpy.AddMessage("Change: " + str(feat.getPart(partnum)[0].X) + " to " + str(allLines[i].startEP.x) )
feat.getPart(partnum)[0].X = allLines[i].startEP.x
rows.updateRow(row)
arcpy.AddMessage("Now is: " + str(feat.getPart(partnum)[0].X))
i+=1
My readout consists of statements like this:
Change: -105.512166832 to -105.699533165
Now is: -105.512166832
For some reason, the rows are not updating. And for the life of me, I can't find a tutorial or instructions on how to edit a particular point in a polyline. I can only find how to edit a point as a field in a point shapefile.
Anyone have any ideas?
Best Answer
Unfortunately you can't directly assign new values to the existing geometry of a feature - rather, you have to create a new geometry object, and update the shape field of the feature with that new object. Fortunately, the array objects have a
replace
method. So rather than trying to directly modify the X coord of the point inside the array, you need to:arcpy.Point
object with the correct coordinates (looks like you might have done this already)replace
method to set the desired point in your array with your modified pointsetValue
method to update the Shape field with your new, correct PolylineupdateRow
method to insert the changed row into the dataset.Concretely:
Note the
replace
method takes an index and a value. Unfortunately it doesn't accept e.g. -1 as an index to the last point in the array. However you can saymy_array[my_array.count]
.It looks like you're precomputing the X-coordinates somewhere else and retrieving them later. If this is the case, I'd probably go the whole hog and create new Polyline objects with the correct points for each line while you're computing the correct coordinates. This will likely be easier & cleaner. That way your code could be more like
Which, at least for me, is a bit more clear... but that's stylistic!
Edit to add:
I couldn't fit this in a comment. Without seeing your code it's hard to tell where it might be falling over. Here's a complete tested script which works for me. Hopefully it will serve as a reference. Note that here I'm calculating the new geometry directly from the old one, rather than doing two passes; that may or may not be possible depending on how you're doing your snap position calculations. Also this time I'm constructing a brand new array based on the old one rather than using the
replace
method, in case that's necessary.Hopefully that helps clear it up.