0

I am trying to update a field using the arcpy.da.Update cursor where I can use the value from a select by location result to populate a new field. Ideally, I would like to be able to use a field value, GEN_UNITS, from a row selected by location from "JoinLayer" divided by "Lines" from the 'subLayer' feature class. What do I need to do to approach this correctly?

#Make feature layer
arcpy.MakeFeatureLayer_management(pp_trans_GUJoin, "JoinLayer")


with arcpy.da.UpdateCursor (subLayer, [GUCountField, "SHAPE@"]) as GUCalcCursor:
    for subrow in GUCalcCursor:
        arcpy.SelectLayerByLocation_management(
                "JoinLayer", 'WITHIN_A_DISTANCE', 
                subrow[1], .000002, "NEW_SELECTION") 
        result = pp_trans_GUJoin.GEN_UNITS/subLayer.LINES 
        subrow[0] = result
        GUCountField.updateRow(subrow)

print "GU_Count Updated"
del GUCalcCursor

Update* It seems like a more robust spatial join route may be the better approach here. Though I still need to use the update cursor to update the GC_Count field in the 'SubLayer' feature class. With this code, I am now receiving an error of 'tuple' object has no attribute 'GEN_UNITS' for the 'result = joinsubrow.GEN_UNITS/joinsubrow.LINES' line. Do I need to search out these field values separately in separate search cursors? What would be the best route here?

import arcpy
from arcpy import env

arcpy.env.OverwriteOutput = True

defaultGdbPath = 'C:\Topo_Check_Tess_V5.gdb'

subLayer='C:\Topo_Check_Tess_V5.gdb\Subs'
transLayer='C:\Topo_Check_Tess_V5.gdb\TLines'
ppLayer='C:\Topo_Check_Tess_V5.gdb\PPs'


arcpy.AddField_management(subLayer, "GU_Count", "SHORT", "", "", "", "", 
"NULLABLE", "NON_REQUIRED", "")
GUCountField = "GU_Count"



#Make feature layer
arcpy.MakeFeatureLayer_management(ppLayer, "ppLayerGU")

#Make feature layer
arcpy.MakeFeatureLayer_management(transLayer, "transLayerGU")

pp_trans_GUJoin ='C:\Topo_Check_Tess_V5.gdb\pp_trans_GU_SpatialJoin'

SubLayer_pp_trans_GUJoin = 
'C:\Topo_Check_Tess_V5.gdb\SubLayer_pp_trans_GUSpatialJoin'

#spatial join of feature layers
arcpy.SpatialJoin_analysis ("transLayerGU", "ppLayerGU", pp_trans_GUJoin, 
'JOIN_ONE_TO_ONE', 'KEEP_ALL', '#', 'WITHIN_A_DISTANCE', .000002) 

#Make feature layer
arcpy.MakeFeatureLayer_management(subLayer, "SubLayer_Layer")

#spatial join of feature layers
arcpy.SpatialJoin_analysis ("SubLayer_Layer", "ppLayerGU", 
SubLayer_pp_trans_GUJoin, 'JOIN_ONE_TO_ONE', 'KEEP_ALL', '#', 
'WITHIN_A_DISTANCE', .000002) 


#Make feature layer
arcpy.MakeFeatureLayer_management(SubLayer_pp_trans_GUJoin, "JoinLayer")

LINE_Fields = ['LINES','GEN_UNITS']


with arcpy.da.UpdateCursor (subLayer, [GUCountField, "SHAPE@"]) as 
GUCalcCursor:
    for subrow in GUCalcCursor:
        arcpy.SelectLayerByLocation_management("JoinLayer", 
        'WITHIN_A_DISTANCE', subrow[1], .000002, "NEW_SELECTION") 

        with arcpy.da.SearchCursor("JoinLayer", LINE_Fields) as 
        JoinLayerCursor:
            for joinsubrow in JoinLayerCursor:

                result = joinsubrow.GEN_UNITS/joinsubrow.LINES 

    subrow[0] = result

    GUCountField.updateRow(subrow)
  • 2
    You have to make a search cursor on the "JoinLayer" after selection and extract the value from the searched row(s)... if any, so be prepared for None! Note by the time you get to the del statement your cursor no longer exists and will probably cause an error, the with statement negates the need for del. – Michael Stimson Apr 12 '17 at 1:00
  • You're mixing old style cursors with new da style. pp_trans_GUJoin.GEN_UNITS/subLayer.LINES isn't valid. – Paul Apr 12 '17 at 4:53
1

I Think a spatial join might be better but anyway this should work (i might be mixing up your field names):

import arcpy

arcpy.MakeFeatureLayer_management(pp_trans_GUJoin, "JoinLayer")
subrowcount=1
with arcpy.da.UpdateCursor (subLayer, [GUCountField, "SHAPE@","LINES"]) as GUCalcCursor:
    for subrow in GUCalcCursor:
        arcpy.SelectLayerByLocation_management("JoinLayer", 'WITHIN_A_DISTANCE', subrow[1], .000002, "NEW_SELECTION")
        #Make sure only one feature is selected:
        if int(arcpy.GetCount_management(in_rows="JoinLayer").getOutput(0))==1:
            #From the selected feature get the GEN_UNITS value
            with arcpy.da.SearchCursor("JoinLayer","GEN_UNITS") as cursor:
                for row in cursor:
                    GEN_UNITS_value=row[0]
            result = GEN_UNITS_value/subrow[2]
            subrow[0] = result
            GUCalcCursor.updateRow(subrow)
        else:
            print 'Failed to update subrow {0}'.format(subrowcount)
        subrowcount+=1
print "GU_Count Updated"
  • Thanks a bunch! I am getting a 'unsupported operand type(s) for /: 'NoneType' and 'float' ' error for the 'result = GEN_UNITS_value/subrow[2]' line. GEN_UNITS and LINES in 'subLayer' both look like they currently have a data type of double. Thanks again for your help. Very helpful and super appreciated. – Tess Gardner Apr 12 '17 at 16:40
  • @TessGardner: Sounds like you have null/None values in the fields, do you? How do you want to handle them? – BERA Apr 14 '17 at 12:07

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.