# Robin's Blog

## 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.

1. andres bacosa says:
2. Alexander Hidalgo says: