Calculating fields equal to the distance of points in one layer to another (using searchcursor, near tables)

920
4
11-30-2016 02:28 PM
KristenM
New Contributor II

I have a set of several points, "pts", and a large dataset, "observations", of thousands of points. I would like to calculate the distance from each point in the small dataset to all points in the large dataset (within 100km). 

My current strategy is to loop over the smaller dataset, select all relevant points in the larger datset (within 100km) and create a near table. I then try joining the near table for each of the smaller points to the large dataset. This would ideally mean that "observations" would have extra columns entitled, "Dist_pt1", "Dist_pt2", etc. equal to the distance between that observation and the given point (or blank if the observation and point are far away).

I'm running into two errors. First, the near tables appear to have zero or just one observation (corresponding to the closest point). Also, the JoinField command (which I've been commenting out for now) causes the code (and ArcGIS) to crash. 

I'd appreciate any help!

fc = "pts"
with arcpy.da.SearchCursor(fc,['Shape@','Name']) as cursor:
    for row in cursor:
        name=str(row[1])
        arcpy.AddField_management("observations", name, "FLOAT")
        query= "\"Name\" = \'"+name+"\'"
        arcpy.SelectLayerByAttribute_management (fc, "NEW_SELECTION", query)
        arcpy.GenerateNearTable_analysis(fc, "observations", "near_"+name, \
                                         "100 Kilometers")
        arcpy.AddField_management("near_"+name, "Name_"+name, "TEXT")
        arcpy.CalculateField_management("near_"+name, "Name_"+name, repr(row[1]), "PYTHON")
        arcpy.AddField_management("near_"+name, "Dist_"+name, "TEXT")
        arcpy.CalculateField_management("near_"+name, "Dist_"+name, "!Near_Dist!", "PYTHON")        
        arcpy.JoinField_management(fc, "Name", "near_"+name, "Name_"+name, "Dist_"+name)

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
4 Replies
RebeccaStrauch__GISP
MVP Esteemed Contributor

Seems to be a populate topic today.

Have you looked at

Near—Help | ArcGIS for Desktop

Calculates distance and additional proximity information between the input features and the closest feature in another layer or feature class.

or Point Distance—Help | ArcGIS for Desktop 

Determines the distances from input point features to all points in the near features within a specified search radius.

Legacy:

This is a deprecated tool. This functionality has been replaced by Near and Generate Near Table tools that now calculate distances between point, polyline and polygon features.

  to see if any of that will work....before going thru the process of writing your own.

You might want to looks at these two current threads too

Find all points located at 100feet in the same layer 

https://community.esri.com/thread/186699-find-distances-between-power-poles 

KristenM
New Contributor II

Yes, I actually use Generate Near Table in my current approach (see above). I seems to be running into challenges using this tool in a loop, however.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

If you only want the distance between multiple origins and multiple destinations, you can use the cdist or pdist in SciPy if you have it installed.  But everyone should have numpy installed and you might find it less painful to do the calculations using it

/blogs/dan_patterson/2016/04/20/distance-calculations-revisited 

once the matrix of distance is complete, then you can query for those values within the threshold.

If you are familiar with python and perhaps numpy, then the code is in the pdf from last year.  I also have a newer variant on github

KristenM
New Contributor II

I fixed several errors in my script that were preventing it from functioning, and I've included it below for anyone who is interested.

I changed the purpose of my code slightly (searched for 50 closest observations, kept rank rather than distance, etc.) but the general idea is the same.

fc = "pts"
with arcpy.da.SearchCursor(fc,['Shape@','Name']) as cursor:
    for row in cursor:
        name=str(row[1])    
        query= "\"Name\" = \'"+name+"\'"
        arcpy.SelectLayerByAttribute_management (fc, "NEW_SELECTION", query)
        arcpy.GenerateNearTable_analysis(fc, "observations", "near_"+name, \
                                         closest='ALL', closest_count=50)
        arcpy.AddField_management("near_"+name, "Name_"+name, "TEXT")
        arcpy.CalculateField_management("near_"+name, "Name_"+name, \
                                        repr(row[1]), "PYTHON")
        arcpy.AddField_management("near_"+name, "Rank_"+name, "SHORT")
        arcpy.CalculateField_management("near_"+name, "Rank_"+name, \
                                        "!Near_Rank!", "PYTHON")
        arcpy.JoinField_management("observations", "FID", "near_"+name, "Near_FID",\
                                   "Rank_"+name)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍