How to: Find closest objects in ArcGIS with Python
As part of my DunesGIS project I had a need to calculate ‘closeness statistics’ for objects in ArcGIS. By ‘closeness statistics’ I mean statistics giving information about how close the objects are to each other. I needed to do this to calculate how dune patterns change over time.
The code below takes a shapefile as input, and then calculates the closest other object to each object. It then returns the mean closeness and standard deviation of all objects.
def CalculateCloseness(Filename): # Calculate the distance from each shape (point, line, polygon) # to all of the others gp.GenerateNearTable(Filename, Filename, "NearTable", \ "", "LOCATION", "ANGLE", "ALL") # Create a view of the table so that we can run queries on it below gp.MakeTableView("NearTable", "tbl", "NEAR_DIST > 0") # Search for all of the distances which are > 175 and < 185 degrees # that is, basically horizontally rows = gp.SearchCursor("tbl", "NEAR_ANGLE >= 175 AND NEAR_ANGLE <= 185", "", "") # Get the first row row = rows.Next() # Create a NumPy array to hold the results shortest = numpy.zeros(500) # For each row while row: # Get the previous shortest distance from the array prev_value = shortest[row.IN_FID] # If the previous value is 0 then this is the first distance # we've found so set it to that if (prev_value == 0): shortest[row.IN_FID] = row.NEAR_DIST continue # Otherwise if this is a shorter one then use it elif (row.NEAR_DIST < prev_value): shortest[row.IN_FID] = row.NEAR_DIST # Move to the next row row = rows.Next() # Select all non-zero elements so the zero's don't skew the mean non_z_indices = numpy.where(shortest) # Calculate mean and stdev mean_closeness = numpy.mean(shortest[non_z_indices]) std_closeness = numpy.std(shortest[non_z_indices]) # Return results return [mean_closeness, std_closeness]
This script is (well, will shortly) be included in RTWTools for ArcGIS, where it is integrated into an ArcGIS Toolbox.