SearchCursor\UpdateCursor with spatial join

1067
4
10-18-2017 02:30 PM
CCWeedcontrol
Occasional Contributor III

I am trying to update points, so say i select 30 points in arcmap and i want to update just those 30 points attributes from the parcels polygons BUT only for those 30 and they it must have "Match" in the Verifi3 field if the feature has "No" or is "Null" i want it to be ignored or just pass.

I have the following code it works but it updates all the selected points whether it has "Match" or "No" or "Null".

I appreciate the help.

import arcpy, os 
from datetime import datetime as d
startTime = d.now()
import traceback

arcpy.env.overwriteOutput = True
arcpy.env.workspace = r'C:\Temp\Default.gdb'

ptSelection = "PointsTest"  
pointLayer = arcpy.env.workspace + os.sep + "PointsTest"
parcel = 'TaxParcels' #Taxparcels
sjpoints = "In_memory\sjpoints"
poly = "ACCOUNT_1" 
Pnt =  "Account"


with arcpy.da.SearchCursor(ptSelection , "Verifi2") as cursor:  
    for row in cursor:
        if row[0] == "Match":
            #Run the Spatial Join tool, using the defaults for the join operation and join type
            arcpy.SpatialJoin_analysis(ptSelection, parcel, sjpoints)

            # define the field list from the spatial join
            sourceFieldsList = ['ACCOUNT_1', poly,'SiteAddress','SiteNum_1', 'SiteStreet_1','SiteNumSfx_1','Predir_1', 'Postdir_1', 'SiteCity_1', 'SiteZIP_1', 'OwnerName_1','StreetType_1', 'SubName_1']    #,'StreetType_1'

            # define the field list to the original points
            updateFieldsList = ['Account', Pnt,'SiteAddres', 'SiteNum', 'StreetName', 'SiteNumSfx','Predir', 'Postdir', 'SiteCity', 'SiteZip', 'OwnerName','StreetType', 'SubName'] #, 'StreetType'

            # populate the dictionary from the polygon
            valueDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(sjpoints, sourceFieldsList)}    

            with arcpy.da.UpdateCursor(ptSelection, updateFieldsList) as updateRows:    
                for updateRow in updateRows:    
                    keyValue = updateRow[0]
                    if keyValue in valueDict:
                        for n in range (1,len(sourceFieldsList)):      
                            updateRow = valueDict[keyValue][n-1]
                        updateRows.updateRow(updateRow)
                del updateRows
                del updateRow
        
        else:
            row[0] == 'No'
            pass

if arcpy.Exists("In_memory\sjpoints"):
    arcpy.Delete_management("In_memory\sjpoints")
0 Kudos
4 Replies
DanPatterson_Retired
MVP Emeritus

before I read further line 11

parcel = 'TaxParcels #Taxparcels

# perhaps you mean

parcel = 'TaxParcels' # ---- missing a ' ...Taxparcels
0 Kudos
CCWeedcontrol
Occasional Contributor III

Yes i meant 'TaxParcels', my bad.

I was trying to clean up code before posting.

0 Kudos
DarrenWiens2
MVP Honored Contributor

Without really paying attention to what your code is doing, just a couple thoughts:

- Running any geoprocessing tool (e.g. spatial join) inside a cursor is a red flag. Tools are for datasets, not individual features, so there's probably a better way if you need to work with individual features.

- Nesting any combination of search and update cursors is a red flag. Read the search cursor into a dictionary, like how you did with valueDict.

- To address your main question, update (and search) cursors only operate on selected features if there is a selection, so just add a where clause to the update cursor to work on selected features meeting some criteria.

CCWeedcontrol
Occasional Contributor III

Thanks Darren, something like like 31?

#Spatial joins the points to taxparcels if "Match" is in Verifi2 field, updates points attributes.
arcpy.env.overwriteOutput = True
arcpy.env.workspace = r'C:\Temp\Default.gdb'

ptSelection = "PointsTest" #points 
pointLayer = arcpy.env.workspace + os.sep + "PointsTest"
parcel = 'TaxParcels' #Taxparcels
sjpoints = "In_memory\sjpoints"
poly = "Filed_1" 
Pnt =  "Filed"

ptCount = int(arcpy.GetCount_management(pointLayer).getOutput(0))

dsc = arcpy.Describe(ptSelection)     
selection_set = dsc.FIDSet             
if len(selection_set) == 0:           
    print "There are no features selected"        
                 
elif ptCount >= 1:
    #Run the Spatial Join tool, using the defaults for the join operation and join type
    arcpy.SpatialJoin_analysis(lyr2, parcel, sjpoints)

    # define the field list from the spatial join
    sourceFieldsList = ['Filed_1', poly,'Field1_1','Field2_1', 'Field3_1']

    # define the field list to the original points
    updateFieldsList = ['Field', Pnt,'Field1', 'Field2', 'Field3']

    # populate the dictionary from the polygon
    valueDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(sjpoints, sourceFieldsList)}    
    whereclause = "Verifi2 = 'Match'"
    with arcpy.da.UpdateCursor(ptSelection, updateFieldsList ,whereclause) as updateRows:    
        for updateRow in updateRows:    
            keyValue = updateRow[0].title()
            if keyValue in valueDict:
                for n in range (1,len(sourceFieldsList)):      
                    updateRow[n] = valueDict[keyValue][n-1]
                updateRows.updateRow(updateRow)
        del valueDict
0 Kudos