0

How do I create a dictionary that has the linkID of a link as key and linkID of touching links as values?

enter image description here

I have used this code in ArcPy but it takes a very long time.

arcpy.CopyFeatures_management(link,link1)
arcpy.MakeFeatureLayer_management(link,"link")
arcpy.MakeFeatureLayer_management(link,"link1")

fid_fid_dict = {} #the dictionary that has linkID and its connecting linkIDs

with arcpy.da.SearchCursor(link, ["FID"]) as curs:
    for row in curs:
        arcpy.SelectLayerByAttribute_management("link", "NEW_SELECTION", '"FID" = {}'.format(row[0])) #selects a link
        arcpy.SelectLayerByLocation_management('link1', "INTERSECT", "link", "", "NEW_SELECTION") #selects touching links
        fid_fid_dict[row[0]] = [_row_[0] for _row_ in arcpy.da.SearchCursor("link1", ['FID'])] #gets the IDs of touching links

The final dictionary should be:

dict = {linkID:[linkID1, linkID2, linkID3, linkID4]}
  • 2
    Use the spatial join tool to get a table of spatially intersecting IDs. – Emil Brundage Nov 5 '19 at 18:13
  • @EmilBrundage you should post that as an answer. One spatial join and join the link feature class to itself. Then read the table once using da.SearchCursor. Multiple selections like you try will be very slow. You can also use networkx python module. – BERA Nov 8 '19 at 15:48
  • I agree with @BERA, using spatial selections is a very slow way of doing it. What other attribution does your data have, looks like a network so is it encoded with node ID? Passing through the data loading node information into dictionaries might be more complex but it would be significantly faster. Also using pre-existing modules like networkx would abstract the code away into just a few lines of code. – Hornbydd Nov 8 '19 at 17:12
1

I think some of things you can try to speed up the processing.

  1. Use Spatial Indices. This is default if your data is in a geodatabase, but if you are using shapefiles you should create an index.

  2. Loading data into memory can improve performance.

  3. Reducing the number of select calls as these can be slow.

Here is some code to try and see if it helps improve the process.

links = [ (row[0],row[1]) for row in arcpy.da.SearchCursor(link,["OID@","SHAPE@"])]
links = arcpy.CopyFeatures_management(link,r"in_memory\links1")
fid_fid_dict = {k:[] for k,g in links}
for fid,geom in links:
    arcpy.SelectLayerByLocation_management("links1","INTERSECT",geom,"","NEW_SELECTION")
    fid_fid_dict[fid] = [row[0] for row in arcpy.da.SearchCursor("Links1",["OID"])]
| improve this answer | |

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.