What I'd like to do, using ArcPy: use a line to split a bunch of polygons into separate parts. Here is what the inputs could look like:
In this case the line should split each polygon into two separate polygons, creating 6 separate polygons in the end.
This question has been asked many times, and there have been a lot of answers provided, but none of them seem to mention the polygon's cut method, perhaps because it seems to only have been introduced in 10.2.
Here is what the ArcGIS Help shows (scroll to cut (cutter)):
This seems to be exactly what I need, but I cannot entirely figure out how to implement it.
From the few examples I was able to find, it seems like I cannot use the method directly on a shapefile that I am referencing, but I need to access the underlying geometry/vertices, so here is what I did (please correct me if there is an entirely different way of doing it):
- read shapefile's vertices using a cursor
- push each vertex into an array
- use that array to create a polygon/line
The next step would be to to use the cut() method, as shown in the screenshot above, to actually split the polygons, but I cannot get it to work.
What follows is my code (only the polygon-part uses comments as the polyline is just repetition):
import arcpy
polygon = r"D:\Data\poly.shp"
line = r"D:\Data\line.shp"
# ------------------- POLYGON -------------------
# first read the geometry
# i.e.: read all of the vertex coordinates, and push them into an array
dataset_vertices = []
# loop through each feature
for row in arcpy.da.SearchCursor(polygon, ["OID@", "SHAPE@"]):
print("Here comes feature {0}:".format(row[0]))
partnum = 0
# Step through each part of the feature
for part in row[1]:
# Print the part number
print("Part {0}:".format(partnum))
tempPart = [] # push each vertex into an array
# Step through each vertex in the feature
for pnt in part:
if pnt:
# Print x,y coordinates of current point
print("{0}, {1}".format(pnt.X, pnt.Y))
tempPart.append([pnt.X,pnt.Y])
else:
# If pnt is None, this represents an interior ring
print("Interior Ring:")
# push part-array into entire array
dataset_vertices.append(tempPart)
partnum += 1
# A list that will hold each the Polygon objects
polygon_features = []
for feature in dataset_vertices:
# Create a Polygon object based on the array of points
# Append to the list of Polygon objects
polygon_features.append(
arcpy.Polygon(
arcpy.Array([arcpy.Point(*coords) for coords in feature])))
# ------------------- POLYLINE -------------------
line_vertices = []
for row in arcpy.da.SearchCursor(line, ["OID@", "SHAPE@"]):
print("Here comes feature {0}:".format(row[0]))
partnum = 0
for part in row[1]:
print("Part {0}:".format(partnum))
tempPart = []
for pnt in part:
if pnt:
print("{0}, {1}".format(pnt.X, pnt.Y))
tempPart.append([pnt.X,pnt.Y])
else:
print("Interior Ring:")
line_vertices.append(tempPart)
partnum += 1
line_features = []
for feature in dataset_vertices:
line_features.append(
arcpy.Polygon(
arcpy.Array([arcpy.Point(*coords) for coords in feature])))
After running this code I can use methods, such as polygon_features[0].boundary(), but I am not sure how to use cut().