Select to view content in your preferred language

Spatial Join & Dictionary transfer

1084
10
07-27-2022 08:58 AM
2Quiker
Occasional Contributor II

I have a two layers, I need to transfer a field attribute to the other layer of the selected feature.

The EMS layer has a filed "SiteCity" and so does the "Ass_Parcels" layer.

I need to transfer the Ass_Parcels SiteCity attribute to the EMS's SiteCity field.

I have the following but I am not able to get it to work.

I don't get an error, but the EMs's SiteCity field doesn't get populated.

pointLayer = 'EMS'
parcel = 'Ass_Parcels'

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

dsc = arcpy.Describe(pointLayer)     
selection_set = dsc.FIDSet             
if len(selection_set) == 0:
    print "There are no features selected"

elif ptCount >= 1:
elif ptCount >= 1:

    arcpy.SpatialJoin_analysis(pointLayer, parcel, sjpoints)
    search_feats ={f[0]:(f[1:]) for f in arcpy.da.SearchCursor(sjpoints,'SiteCity_1')}
    print(search_feats)

    with arcpy.da.UpdateCursor(pointLayer,["SHAPE@","SiteCity"]) as upd_cur:
        for upd_row in upd_cur:
            try:
                if search_feats[upd_row[0]][1] == "Sea":              
                    upd_row[1] == "Seattle"
                elif search_feats[upd_row[0]][1] == "Spo":
                    upd_row[1] == "Spokane"
                elif search_feats[upd_row[0]][1] == "Tac":
                    upd_row[1] == "Tacoma"
                upd_cur.updateRow(upd_row)
            except:
               continue

 

 

0 Kudos
10 Replies
RhettZufelt
MVP Notable Contributor

One thing I see is that you are not setting the upd_row[#] to anything, == is to compare, not set.

Try something like this, see if it works:

    with arcpy.da.UpdateCursor(pointLayer,["SHAPE@","SiteCity"]) as upd_cur:
        for upd_row in upd_cur:
            try:
                if search_feats[upd_row[0]][1] == "Sea":              
                    upd_row[1] = "Seattle"
                elif search_feats[upd_row[0]][1] == "Spo":
                    upd_row[1] = "Spokane"
                elif search_feats[upd_row[0]][1] == "Tac":
                    upd_row[1] = "Tacoma"
                upd_cur.updateRow(upd_row)

 

R_

2Quiker
Occasional Contributor II

I did catch that after I posted, but I still get the same thing. No errors but nothing is updated. I did look into the field a little and found that the pointLayer "SiteCity" field has domains, not sure if this has any effect or not.

0 Kudos
by Anonymous User
Not applicable

Make sure your conditionals are working as expected by adding some print statements

if search_feats[upd_row[0]][1] == "Sea"
    arcpy.AddMessage(f'{search_feats[upd_row[0]][1]} setting Seattle')

 

0 Kudos
by Anonymous User
Not applicable

Just a note... if you are going to have a long list of if/elif, you can use a dictionary lookup to save you some elifs.

 

place_dict = {"Sea":"Seattle", "Spo":"Spokane", "Tac":"Tacoma", ...}

for upd_row in upd_cur:
    try:
        upd_row[1] = place_dict.get(search_feats[upd_row[0]][1], upd_row[1])

 

... at 3.10 they introduced pattern matching structural-pattern-matching 

 

2Quiker
Occasional Contributor II

i have tried the following and get this error.

Runtime error SyntaxError: can't assign to operator (<string>, line 35)

Not sure what that means but one thing I did find out about that field is that there is domains to that field.

 

pointLayer = 'EMS'
parcel = 'Ass_Parcels'

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

dsc = arcpy.Describe(pointLayer)     
selection_set = dsc.FIDSet             
if len(selection_set) == 0:
    print "There are no features selected"

elif ptCount >= 1:

    arcpy.SpatialJoin_analysis(pointLayer, parcel, sjpoints)
    search_feats ={f[0]:(f[1:]) for f in arcpy.da.SearchCursor(sjpoints,'SiteCity_1')}
    print(search_feats)

##    with arcpy.da.UpdateCursor(pointLayer,["SHAPE@","SiteCity"]) as upd_cur:
##        for upd_row in upd_cur:
##            try:
##                if search_feats[upd_row[0]][1] == "Sea":              
##                    upd_row[1] = "Seattle"
##                elif search_feats[upd_row[0]][1] == "Spo":
##                    upd_row[1] = "Spokane"
##                elif search_feats[upd_row[0]][1] == "Tac":
##                    upd_row[1] = "Tacoma"
##                upd_cur.updateRow(upd_row)
##            except:
##               continue

    place_dict = {"Sea":"Seattle", "Spo":"Spokane", "Tac":"Tacoma"}

    with arcpy.da.UpdateCursor(pointLayer,["SHAPE@","SiteCity"]) as upd_cur:
        for upd_row in upd_cur:
            try:
                upd_row[1] = place_dict.get(search_feats[upd_row[0]][1], upd_row[1])
                upd_cur.updateRow(upd_row)
            except:
               continue

 

 

 

0 Kudos
by Anonymous User
Not applicable

I don't know what they structure of search_feats looks like once its created, but it looks like the only field you have in the SearchCursor isnt a shape(?) "SiteCity_1", but are trying to match the Shape@ in your updatecursor to it since "Shape@" is at the 0 index.

with arcpy.da.UpdateCursor(pointLayer,["SHAPE@","SiteCity"])
...
    search_feats[upd_row[0]]

Id suggest adding some print statements or debugging to check what values you are getting, and sharing them to this thread if it is still having problems.

...

I think you'll need to get the corresponding code value of string value and use it instead of the string.

You can get the domains and convert it into a dictionary- this should get you started:

list domains  

0 Kudos
2Quiker
Occasional Contributor II

Adding the print statement give the following error.

print (search_feats[upd_row[0]])
error KeyError: <PointGeometry object at 0x3900e790[0x3900e620]>

0 Kudos
by Anonymous User
Not applicable

That is expected because you are using the feature shape@ at upd_row[0] in your update cursor.  Like @RhettZufelt pointed to, and I pointed to in previous posts, you need to adjust the fields that you are using in your cursors to get past this and to create a usable dictionary.

I'd highly suggest getting to know how to use the debugger so you can examine what your code is doing and what your variables values are.  This would save you a lot of time and increase your knowledge of the language.

 

 

0 Kudos
RhettZufelt
MVP Notable Contributor

What does the sjpoints table look like?  is there a field with the abbreviation and one with the fullname that you are trying to load into the dictionary?  If so, you are only loading the SiteCity_1 field into the cursor, but trying to assign the key and value from it?

I believe your issue is probably in this line:

 

search_feats ={f[0]:(f[1:]) for f in arcpy.da.SearchCursor(sjpoints,'SiteCity_1')}

 

 Not sure what f[1:] is supposed to do, but is only returning an empty set of parrens when I try it.

What does the print(search_feats) show?  Probably something like below?  If so, that would tell it to update with empty value.

 

{"Sea":(), "Spo":(), "Tac":()}

 

If there is a fullname field in sjpoints table, suspect you were looking for something like this (add the other field and remove the colon from f[1]):

 

search_feats ={f[0]:(f[1]) for f in arcpy.da.SearchCursor(sjpoints,['SiteCity_1','fullnamefield'])}

 

Just need to make sure the search_feats prints out like:

{"Sea":"Seattle", "Spo":"Spokane", "Tac":"Tacoma"}

Also, describe can slow stuff down a lot, and the GetCountManagement will only return selected records if there is a selection, so no need for the extra load of the describe/compare.

R_