0

For each group I want to find the maximum point-to-point distance (and which of the id1 features participate in the max).

For example, if I have the following attribute table:

enter image description here

FID Long    Lat id1 group
0   120.65627   23.649932   15  1
1   120.65677   23.650132   2   1
2   120.65887   23.652732   111 2
3   120.66057   23.654632   17  3
4   120.66167   23.655832   120 3
5   120.67133   23.65794    55  3

I would like to get an output table that looks like this:

enter image description here

Here the group=2 is omitted because there is only one point in the group, so no pt2pt distance to calculate (or it's fine if it is there and is zero). This is maximum distance for group=3 point combinations (others, 55.57 meters and 1,011 meters are less).

The Point Distance tool doesn't have any group-id capability nor any statistics (min, max, etc.) capablities.

I will be doing this in ArcPy, but I am not sure which tools or sequences of tools to use to get started.

2
  • What if you perform a Spatial Join (one to many) and then build a query expression using WHERE, MAX and GROUP BY.
    – Taras
    Commented Aug 13, 2020 at 7:22
  • 1. Anaylsis Tools > Extract > Split By Attributes 2. Analysis Tools > Proximity > Point Distance 3. Data Management Tools > General > Append Extract each group of points first, then calculate the point distance and got the maximum point pairs. Finally, append the results of each group if needed.
    – Leo
    Commented Aug 13, 2020 at 7:42

1 Answer 1

0

I worked out a solution:

  1. Project into UTM EPSG so that distances are in meters: arcpy.Project_management()
  2. Use summary statistics to get the FREQUENCY of each id1: arcpy.Statistics_analysis()
  3. Use Pandas to extract a list of id1 values that are repeated
  4. Use Pandas to create my table (dataframe) of id1 and max_dist and populate in a loop through all the duplicate id1 values:
  5. (in loop) Create a temporary copy of my SHP: arcpy.CopyFeatures_management()
  6. (in loop) Delete all rows in the copy that are not equal to the id1
  7. (in loop) Calculate distances between all the remaining points: arcpy.PointDistance_analysis()
  8. (in loop) Get maximum distance using arcpy.da.SearchCursor()
  9. (in loop) Populate my table (dataframe) with the id1 and max_dist
  10. Exit loop, save table

It doesn't save the id1 values like I initially wanted, but that could be achieved by going back and adding a join operation on the OID (FID) after Step 6 and then populating the table accordingly in Step 9.

import arcpy, pandas as pd
epsg = 26911
arcpy.Project_management(inshp, projshp, arcpy.SpatialReference(epsg))

temptable1 = 'in_memory\\{}_Table'.format('mytemp1')
arcpy.Statistics_analysis(projshp, temptable1, statistics_fields=[['id1', 'COUNT']], 
                    case_field='id1')
mydf = pd.DataFrame(data=[row for row in arcpy.da.SearchCursor(temptable1, 
                    ['id1', 'FREQUENCY'])], columns=['id1', 'FREQUENCY'])
mydf = mydf[mydf.FREQUENCY != 1]
keeps = mydf.id1.values.tolist()

# clean-up
arcpy.Delete_management(tempmerge)
arcpy.Delete_management(temptable1)
del mydf

df = pd.DataFrame(columns=['id1', 'max_dist'])
for n in keeps:
    arcpy.CopyFeatures_management(projshp, tempshp)
    with arcpy.da.UpdateCursor(tempshp, ['id1']) as rows:
        for val, in rows:
            if val not in [n]:
                rows.deleteRow()
    
    temptable2 = 'in_memory\\{}_Table'.format('mytemp2')
    arcpy.PointDistance_analysis(tempshp, tempshp, temptable2)
    maxdist = max([row[0] for row in arcpy.da.SearchCursor(temptable2, ['DISTANCE'])])
    df = df.append({'id1': int(n), 'max_dist': maxdist}, ignore_index=True)
    
    # clean-up
    arcpy.Delete_management(temptable2)
    arcpy.Delete_management(tempshp)
    del maxdist

df.to_csv('myfilename.csv', index=False)
 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.