2

I am trying to update an existing field in a polygon fc with an existing field in a point fc. There is only ever one point fc located within each polygon fc. The field names in the polygon fc can not change as it needs to have a matching schema for a later append.

Lotnumber is the point fc while fcUpdate is the polygon fc in the below code. I was trying to create a search cursor that would iterate through each point and store the value in the TEXTSTRING field. the code should then select the polygon that contains the current point, insert an update cursor, and update the Housenumber field with the value obtained from the point.

# Enter the point feature class containing lot numbers
Lotnumber = arcpy.GetParameterAsText(4)

# Make a layer from previously created new feature class
arcpy.MakeFeatureLayer_management(fcUpdate, "Parcels_Temp")

# open a search cursor to iterate through each point
with arcpy.SearchCursor(Lotnumber, "TEXTSTRING") as cursor1:
    # Iterate through each point in the point fc
    for row in cursor1:
        lotnum = row.getValue("TEXTSTRING")
        # Select the parcel that contains the point
        parcel = arcpy.SelectLayerByLocation_management(fcUpdate, "COMPLETELY_CONTAINS", row)
        cursor2 = arcpy.da.UpdateCursor(parcel, 'HouseNumber')
        for row in cursor2:
            row[0] = lotnum

# delete the cursor
del cursor

My code is based on a question answered here: Using Select By Location to update field in feature class using ArcPy?

I'm very new to Python. I've tried running the script in ArcMap and get an error stating invalid SQL statements were used.

4
  • 1
    I think selectLayerByLocation does not return anything, instead it selects features in your layer. try using the UpdateCursor in fcUpdate like cursor2 = arcpy.da.UpdateCursor(fcUpdate, 'HouseNumber'), it should iterate only over your selected features
    – xlDias
    Commented Mar 14, 2018 at 20:54
  • What is the precise and full error message that you are receiving?
    – PolyGeo
    Commented Mar 14, 2018 at 21:33
  • 1
    Why not spatial join the points to the polygons then attribute join the spatial joined points to the polygon and calculate the field in the joined table? This method, to me, sounds a lot less complicated. Ensure your points and polygons have the same coordinate system before trying anything though. please note that arcpy.SearchCursor is not compatible with the 'with' statement, use an arcpy.da.SearchCursor or you will get an error message at the end of the with block Commented Mar 14, 2018 at 22:18
  • @Michael Stimson, I need to be able to perform a Test append, preferably using Python, to another polygon fc. As such, I need the schema to be exactly identical. Joining the points to the polygon would add join fields and counts, which would prevent a test append from working. Or so I understand. I suppose I could spatially join the fields, field calculate HouseNumber to be int(TEXTSTRING) and then delete the join fields? Commented Mar 16, 2018 at 16:08

1 Answer 1

1

Short answer is that the error is coming from the following line: with arcpy.SearchCursor(Lotnumber, "TEXTSTRING") as cursor1:The "TEXTSRING" at the end isn't a field (because you aren't calling arcpy.da.SearchCursor), but is a where_clause that is invalid and throwing the error. You could delete the "TEXTSTRING" from that line and you won't get that error.

If that didn't fail, though, you use the same name to declare row object variables in both cursors, and finally I don't think you can use a row object as a search parameter in your select by location. Also, at the very end you would need a cursor2.updateRow(row) line.

With this cleaned up, you might still have issues from calling nested cursors, one inside the other. That should be avoided where possible. You can go through one at a time, get your "TEXTSTRING" values from the Lotnumber layer, and then go through with each value selected and update the intersected fcUpdate feature. Like this:

# Enter the point feature class containing lot numbers
Lotnumber = arcpy.GetParameterAsText(4)

# Make a layer from previously created new feature class
arcpy.MakeFeatureLayer_management(fcUpdate, "Parcels_Temp")

#Get all the unique strings from the first layer
unique_strings = []
with arcpy.da.SearchCursor(Lotnumber, 'TEXTSTRING') as cursor:
    for row in cursor:
        unique_strings.append(row[0])

#Select each feature in sequence and get intersecting feature, then update
for unique in unique_strings:
    arcpy.SelectLayerByAttribute_management(Lotnumber, 'NEW_SELECTION', "TEXTSTRING = '{}'".format(unique))
    arcpy.SelectLayerByLocation_management("Parcels_Temp", 'INTERSECTS', Lotnumber)
    with arcpy.da.UpdateCursor("Parcels_Temp", 'HouseNumber') as cursor:
        for row in cursor:
            row[0] = unique
            cursor.updateRow(row)
    #Clear the selections before the next iteration
    arcpy.SelectLayerByAttribute_management(Lotnumber, 'CLEAR_SELECTION')
    arcpy.SelectLayerByAttribute_management("Parcels_Temp", 'CLEAR_SELECTION')

#Using a with statement, you don't need to delete the cursor 
1
  • I couldn't get this section to work. I decided to try working on using a spatial join instead, and got a bit further, but am still having issues with it. as a result, i'll be closing out this question and asking one with more code and a bit more clarity..hopefully. Commented Mar 20, 2018 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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