Fairly new to python and I have a issue with writing new values to an existing text field in a feature class/shapefile. I want to update the existing text values by taking the Shape@ geometry of the polygon and making a series of text values seperated by a comma. I got it to work to create the text line and I can write the lines to a file - but now I want to take that text string and replace the values in a field that are already there using UpdateCursor. I want to make sure that all the polygon vertices are written to one filed, then move onto the next polygon as well - here I am trying to compare the OID's - if they change then move on. I am having issues accomplishing that feat - I can get the values to display in the python window - but then I get a "Runtime error Traceback (most recent call last): File "", line 21, in TypeError: value #1 - unsupported type: list"
Here is my code so far:
import arcpy
infc = "H:\GIST_8125\Oil_Gas\Gail_test\clip_project.shp"
for row in arcpy.da.SearchCursor(infc, ["OID@", "SHAPE@", "Coord_stri"]):
# iterate through polygon parts
partnum = 0
for part in row [1]:
# list polygon part points
for pnt in part:
print (str(pnt.X) + ',' + str(pnt.Y))
partnum += 1
# update coord_string
with arcpy.da.UpdateCursor(infc, ["OID@", "Coord_stri"]) as uCursor:
#iterate through rows and update values
for row in uCursor:
if row [0] == row [0]:
row [1] = ([pnt.X, pnt.Y])
uCursor.updateRow(row)
del uCursor, row
The first part of the polygon is correctly being written to the field - now just need to find a way to write the 4 other points to the same line:
import arcpy
infc = "H:\GIST_8125\Oil_Gas\Gail_test\clip_project.shp"
uCursor = arcpy.da.UpdateCursor(infc, ["OID@", "SHAPE@", "Coord_stri"])
for row in uCursor:
# iterate through polygon parts
partnum = 0
for part in row [1]:
# list polygon part points
for pnt in part:
print (str(pnt.X) + ',' + str(pnt.Y))
row[2] = (str(pnt.X) + ',' + str(pnt.Y))
uCursor.updateRow(row)
partnum += 1
del uCursor, row
2 Answers 2
Add the shape token (SHAPE@
) to the UpdateCursor and you dont need the SearchCursor:
import arcpy
fc = r"H:\GIST_8125\Oil_Gas\Gail_test\clip_project.shp"
with arcpy.da.UpdateCursor(fc,['SHAPE@','Coord_stri']) as cursor:
for row in cursor:
coords = []
part = row[0].getPart(0)
for pnt in part:
coords.extend([pnt.X, pnt.Y])
row[1]=', '.join(str(c) for c in coords)
cursor.updateRow(row)
-
BERA - thank you SO much for the editing - it works like a charm! All the parts of the polygon are correctly added to the "coord_stri: field as needed. I do have a question though - why only specify the (str(x) for x in coords) - and not mention the y?Gail Robertson– Gail Robertson2018年05月03日 17:44:35 +00:00Commented May 3, 2018 at 17:44
-
Nice! x is just a variable name, I should have called it something else less confusing. x is in this case each coordinate (both x and y's) in the list called coords. I have changed it to c. Could you accept my answer with the checkbox?Bera– Bera2018年05月03日 17:49:43 +00:00Commented May 3, 2018 at 17:49
-
1Thank you for the clarity BERA - good stuff! Checked as requested - this stack exchange dedicated to Geo is a fantastic resource - could not have done it without you and smiller!Gail Robertson– Gail Robertson2018年05月03日 18:11:22 +00:00Commented May 3, 2018 at 18:11
Your "Coord_stri" field is a text field and can't support a list. Instead of using the list [pnt.X, pnt.Y]
, convert the list to a string. e.g. coordlist = [pnt.X, pnt.Y]
coordstr = ",".join(coordlist)
row[1] = coordstr
.
(You could also combine these statements as below):
with arcpy.da.UpdateCursor(infc, ["OID@", "Coord_stri"]) as uCursor:
#iterate through rows and update values
for row in uCursor:
if row [0] == row [0]:
row [1] = ",".join(map(str, [pnt.X, pnt.Y])) #creates a list from the pnt values, joins the list by comma into a string, uses that string as value for "Coord_stri"
uCursor.updateRow(row)
-
Thanks smiller - I think it is so close... when I run in Arc - I get an error:Runtime error Traceback (most recent call last): File "<string>", line 20, in <module> TypeError: sequence item 0: expected string, float found - I think that is coming from the Shape@ geometry as numbers - do I need to covert from float to string in the update cursor... ?Gail Robertson– Gail Robertson2018年05月03日 16:04:38 +00:00Commented May 3, 2018 at 16:04
-
Yes, I think you're on the right track -- or you could just do this all at once (either with
map
python function, orrow[1] = ",".join([str(pnt.X), str(pnt.Y]))
SMiller– SMiller2018年05月03日 16:12:23 +00:00Commented May 3, 2018 at 16:12 -
I think this is the one-liner:
row[1] = " ,".join(map(str,[pnt.X, pnt.Y]))
SMiller– SMiller2018年05月03日 16:18:45 +00:00Commented May 3, 2018 at 16:18
coordlist = [pnt.X, pnt.Y]
coordstr = ",".join(coordlist)
row[1] = coordstr
.