2

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
  • 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. – smiller May 3 '18 at 15:38
  • Actually I wonder if a Field Calculator might be a better option in this case. I think the Field Calculator (available in interactive mode or via arcpy) can access the SHAPE@ field and break it down. – smiller May 3 '18 at 15:59
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 May 3 '18 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 May 3 '18 at 17:49
  • 1
    Thank 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 May 3 '18 at 18:11
2

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 May 3 '18 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, or row[1] = ",".join([str(pnt.X), str(pnt.Y])) – smiller May 3 '18 at 16:12
  • I think this is the one-liner: row[1] = " ,".join(map(str,[pnt.X, pnt.Y])) – smiller May 3 '18 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.