For any given polygon in a feature class I would like to create the largest possible circle that fits within this polygon (see examples below); in case of the original polygon being a circle, the new circle would be identical to the original.
Is there a function in ArcGIS Pro to achieve this?
PS: the minimum bounding geometry tool can draw a minimum circle on the outside of each polygon (https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/minimum-bounding-geometry.htm). I just need to achieve the circle within the polygon instead.
AFAIK, there is no out of the box tool for that.
This thread lists a few algorithms the get an incircle: algorithm - Largest circle inside a non-convex polygon - Stack Overflow
I took one of the approaches:
def create_incircle(polygon): add = arcpy.env.addOutputsToMap arcpy.env.addOutputsToMap = False # densify polygon to get rid of curves, which only have 2 vertices polygon = polygon.densify("DISTANCE", 10, 1) # extract vertices into a point fc vertices = arcpy.management.CreateFeatureclass("memory", "vertices", "POINT", spatial_reference=polygon.spatialReference) with arcpy.da.InsertCursor(vertices, ["SHAPE@"]) as cursor: for part in polygon: for v in part: cursor.insertRow([v]) # create Thiessen polygons thiessen = arcpy.analysis.CreateThiessenPolygons(vertices, "memory/thiessen") # intersect these with themselves to get candidate points test_points = arcpy.analysis.Intersect([thiessen], "memory/TestPoints", output_type="POINT") # get the point inside the polygon with the greatest distance to the polygon's boundary candidates = [] boundary = polygon.boundary() with arcpy.da.SearchCursor(test_points, ["SHAPE@"]) as cursor: for p, in cursor: if p.disjoint(polygon): continue candidates.append([p, p.distanceTo(boundary)]) center = sorted(candidates, key=lambda c: c[1])[-1] # buffer that point ith the distance to the boundary, return arcpy.env.addOutputsToMap = add return center[0].buffer(center[1]) # create the ouput fc incircles = arcpy.management.CreateFeatureclass("memory", "Incircles") arcpy.management.AddField(incircles, "FID", "LONG") # create the incircles with arcpy.da.InsertCursor(incircles, ["SHAPE@", "FID"]) as i_cursor: with arcpy.da.SearchCursor("TestPolygons", ["SHAPE@", "OID@"]) as s_cursor: for shp, oid in s_cursor: ic = create_incircle(shp) i_cursor.insertRow([ic, oid])
This is quite slow (1 - 2 seconds per feature), probably because the densification in line 5 adds lots of vertices. This can probably be optimized much, but it works as a quick-and-dirty approach. Sadly, it requires an Advanced license for the Thiessen polygons.
Aangemelde leden kunnen berichten plaatsen, updates volgen en meer. Nieuw hier? Registreer een gratis account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.