Update point fields with fields in intersecting polygon

491
5
Jump to solution
07-20-2021 10:48 AM
AliciaShyu
Occasional Contributor

I have 2 feature classes events (points)  and districts (polygons). PolygonsPolygonsPointsPoints

I get new points every day and they need polygon (district) information. 

I would like to copy over the fields Week, RecycleRt and RecyCollDay from the polygon feature class to the points.

This is the script that I have so far. I know the arcpy.da.UpdateCursor section is wrong, because I don't understand UpdateCursor and I'm getting a runtime error: Cannot find field 'Week'

 

 

import arcpy

arcpy.env.workspace = "\\\\gis\\RecyclingAuditUpdate"
PW = "\\\\Projects\\RecyclingAuditUpdate\\UpdateAudits.gdb"
VPub = "\\\\connections\\AuthUser@VPub_Prd.sde"
RecyAudit = PW +"\\RecyclingAudit"
RecyDistrict = VPub + "\\RecyclingDistrict"

# Select new records 
NewSelection = arcpy.SelectLayerByAttribute_management (RecyAudit,"NEW_SELECTION",["Week IS NULL AND RecycleRt IS NULL AND RecyCollDay IS NULL"],"NON_INVERT")

# Select intersecting districts
UpDistricts = arcpy.SelectLayerByLocation_management (RecyDistrict,"INTERSECT",NewSelection, "","NEW_SELECTION")

 Start edit session
edit = arcpy.da.Editor(PW)
edit.startEditing(True, False)

# Update Week, RecycleRt and RecyCollDay fields in RecyclingAudit layer
updateFields = ["Week", "RecycleRt", "RecyCollDay"]
with arcpy.da.UpdateCursor(NewSelection, updateFields) as update_cursor:
    for row in update_cursor:
        row[1] = "Week"
        row[2] = "RecycleRt"
        row[3] = "RecyCollDay"
        update_cursor.updateRow(row)

 

 

 Any guidance would be really appreciated. Thanks!

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
AliciaShyu
Occasional Contributor

OK, I figured out the error. I had to add a common field to both field lists (RecyAuditFieldList and SpatialJoinFields) which are OBJECTID and TARGET_FID.

The edited list looks like this:

RecyAuditFieldList = ["OID@","Week","RecycleRt","RecyCollDay"]
SpatialJoinFields = ["TARGET_FID","Week", "RecycleRt", "RecyCollDay"]

I will most likely have to update this script in the future since it updates all the records, not just the ones with missing fields. 

View solution in original post

0 Kudos
5 Replies
DanPatterson
MVP Esteemed Contributor

rows are zero based, so I am guessing 

row[0] = "Week" on line 23


... sort of retired...
0 Kudos
AliciaShyu
Occasional Contributor

That fixed the error and the script works but not the way I was thinking :grinning_face_with_sweat:

Instead of updating the fields with the corresponding selected polygon's fields. It's just updating them with the words Week, RecycleRt and RecyCollDay :persevering_face:

SelectDistricts.png

0 Kudos
curtvprice
MVP Esteemed Contributor

I believe it would be far more efficient to run the Spatial Join tool, add a join from the input to the result, and copy over the values from the result to the input feature class using Calculate Field, or an update cursor.

0 Kudos
AliciaShyu
Occasional Contributor

I believe you're correct. I found this post Update points attributes based on there location and updated my script to

import arcpy

arcpy.env.workspace = "\\\\gis\\RecyclingAuditUpdate"
PW = "\\\\Projects\\RecyclingAuditUpdate\\UpdateAudits.gdb"
VPub = "\\\\connections\\AuthUser@VPub_Prd.sde"
RecyAudit = PW +"\\RecyclingAudit"
RecyDistrict = VPub + "\\RecyclingDistrict"
RecyAudit = PW +"\\RecyclingAudit"
RecyAuditFieldList = ["Week","RecycleRt","RecyCollDay"]
SpatialJoin = PW + "\\SpatialJoin_RA"
SpatialJoinFields = ["Week", "RecycleRt", "RecyCollDay"]

arcpy.env.overwriteOutput = True
# Scratch spatial join feature
arcpy.SpatialJoin_analysis(RecyAudit, RecyDistrict, SpatialJoin, "JOIN_ONE_TO_ONE", "KEEP_ALL",
                           'Crdt "Crdt" false true false 8 Date 0 0,First,#,RecyclingAudit,Crdt,-1,-1;'
                           'Address1 "address" true true false 255 Text 0 0,First,#,RecyclingAudit,Address1,0,255;'
                           'Classification "Classification" true true false 255 Text 0 0,First,#,RecyclingAudit,Classification,0,255;'
                           'Status "Status" true true false 10 Text 0 0,First,#,RecyclingAudit,Status,0,10;'
                           'Compliance "Compliance" true true false 5 Text 0 0,First,#,RecyclingAudit,Compliance,0,5;'
                           'Week "Week" true true false 50 Text 0 0,First,#,SolidWasteRecyclingDistrict,Week,0,50;'
                           'RecycleRt "RecycleRt" true true false 50 Text 0 0,First,#,SolidWasteRecyclingDistrict,RecycleRt,0,50;'
                           'RecyCollDay "RecyCollDay" true true false 50 Text 0 0,First,#,SolidWasteRecyclingDistrict,RecyCollDay,0,50',
                           "INTERSECT", None, '')

# Start edit session
edit = arcpy.da.Editor(PW)
edit.startEditing(True, False)
edit.startOperation()

# Populate the dictionary from recycling district
valueDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(SpatialJoin, SpatialJoinFields)}
with arcpy.da.UpdateCursor(RecyAudit, RecyAuditFieldList) as updateRows:
    for updateRow in updateRows:
        keyValue = updateRow[0]
        if keyValue in valueDict:
            for n in range (1,len(SpatialJoinFields)):
                updateRow = valueDict[keyValue][n-1]
            updateRows.updateRow(updateRow)
    del valueDict


# Stop edit operation, stop edit session and save changes
edit.stopOperation()
edit.stopEditing(True)

 

This script has the following error:

Traceback (most recent call last):
File "S:/Scripts/ShortRecyclingAuditUpdate.py", line 39, in <module>
updateRows.updateRow(updateRow)
TypeError: sequence size must match size of the row

I don't understand how UpdateCursor works. 

0 Kudos
AliciaShyu
Occasional Contributor

OK, I figured out the error. I had to add a common field to both field lists (RecyAuditFieldList and SpatialJoinFields) which are OBJECTID and TARGET_FID.

The edited list looks like this:

RecyAuditFieldList = ["OID@","Week","RecycleRt","RecyCollDay"]
SpatialJoinFields = ["TARGET_FID","Week", "RecycleRt", "RecyCollDay"]

I will most likely have to update this script in the future since it updates all the records, not just the ones with missing fields. 

0 Kudos