3

In ArcMap, I am using the Polygon Neighbors tool to generate a list of each polygon's adjacent polygons, or 'neighbors.' Currently, ArcMap orders the polygons using each polygon's numeric ID. What I would like to do is order each polygon's neighbor list in clockwise order relative to the center of the "source" polygon.

For example, in the picture below, if Polygon 1 is my source precinct, the neighbors currently appear ordered 2,3,4,5,6,7. I would like the ordering to be clockwise - say, 6,3,7,5,4,2. (The start of the list does not matter, only that they are clockwise relative to the starting neighbor in the list.)

Is there a way to do this in ArcMap?

Example of Polygon Neighbors

10
  • That looks like a random ordering to me. You can of course construct whatever attribute allocation scheme you want, but first you need to choose a programming environment, and then start programming.
    – Vince
    Commented May 26, 2019 at 21:15
  • Hi, @Vince. For clarification, which ordering are you saying looks random? Commented May 26, 2019 at 21:27
  • To do this I would try ArcPy and look at the angles between the centroid of the centre polygon and each of its neighbours.
    – PolyGeo
    Commented May 26, 2019 at 21:33
  • @PolyGeo, that's what I originally did. However, due to the irregular shapes of some of the polygons and the placement of their centroids, the order sorted by angles does not correspond to the clockwise order in many cases. Too many to fix manually, at least. Commented May 26, 2019 at 21:35
  • What about the angles between the centroid of the centre polygon and the points where it intersects each pair of neighbours? If that does not work then assembling a list of the coordinates where the centre polygon intersects each pair of its neighbours, and then examining them against each coordinate in the string of coordinates that make up the polygon should let you write a new list in the clock-wise order.
    – PolyGeo
    Commented May 26, 2019 at 21:54

1 Answer 1

3

This workflow will create mid points of edges between polygons and delete outer ones called "LINKS":

arcpy.FeatureToLine_management(in_features="PGONS", out_feature_class="C:/SCRATCH/OUTLINES.shp", cluster_tolerance="", attributes="NO_ATTRIBUTES")
arcpy.Dissolve_management(in_features="OUTLINES", out_feature_class="C:/SCRATCH/edges.shp", dissolve_field="", statistics_fields="", multi_part="SINGLE_PART", unsplit_lines="DISSOLVE_LINES")
arcpy.FeatureVerticesToPoints_management(in_features="edges", out_feature_class="C:/SCRATCH/midpoints.shp", point_location="MID")
arcpy.SpatialJoin_analysis(target_features="midpoints", join_features="PGONS", out_feature_class="C:/SCRATCH/SJ.shp", join_operation="JOIN_ONE_TO_MANY")
arcpy.Dissolve_management(in_features="SJ", out_feature_class="C:/SCRATCH/links.shp", dissolve_field="TARGET_FID", statistics_fields="JOIN_FID FIRST;JOIN_FID LAST", multi_part="SINGLE_PART", unsplit_lines="DISSOLVE_LINES")
arcpy.SelectLayerByAttribute_management(in_layer_or_view="links", selection_type="NEW_SELECTION", where_clause='"FIRST_JOIN" = "LAST_JOIN_"')
arcpy.DeleteFeatures_management(in_features="links")

I thought to continue that way, but realised, that I don't know how to compute chainage on a closed line using linear referencing and I don't know model builder good enough to loop through polygons. So here you go:

import arcpy, os
import networkx as nx

nodes="PGONS"
edges="LINKS"
G=nx.Graph()

with arcpy.da.SearchCursor(edges, ("Shape@","FIRST_JOIN","LAST_JOIN_")) as cursor:
    for pG,f,t in cursor:
        G.add_edge(f,t)
        G[f][t]["Shape"] = pG
g = arcpy.Geometry()
geometryList = [pgon.boundary() for pgon in arcpy.CopyFeatures_management(nodes,g)]
curT = arcpy.da.InsertCursor("out_points",("F","T","SHAPE@"))
for f in G.nodes():
    outline = geometryList[f]
    aList = []
    for t in nx.neighbors(G,f):
        p = G[f][t]["Shape"].firstPoint
        chainage = outline.measureOnLine(p)
        aList.append((chainage,f,t,p))
    aList.sort()
    for chainage,f,t,p in aList:
        curT.insertRow((f,t,p))
del curT

Output:

enter image description here

I connected some of the output points:

enter image description here

Note: tested on shapefiles.

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.