There is a lot of nested loops and wondering of ways I could speed up this code? Any ideas?
Note: This requires ArcMap 10.2
def cut_geometry(to_cut, cutter):
"""
Cut a feature by a line, splitting it into two geometries.
:param to_cut: The feature to cut.
:param cutter: The polyline to cut the feature by.
:return: The feature with the split geometry added to it.
"""
arcpy.AddField_management(to_cut, "SOURCE_OID", "LONG")
geometries = None
with arcpy.da.SearchCursor(cutter, "SHAPE@") as lines:
for line in lines:
with arcpy.da.UpdateCursor(to_cut, ["SHAPE@", "OID@"]) as polygons:
for polygon in polygons:
if line[0].disjoint(polygon[0]) == False:
geometries = polygon[0].cut(line[0])
polygons.deleteRow()
with arcpy.da.InsertCursor(to_cut, ["SHAPE@", "SOURCE_OID"]) as insert_cursor:
for geometry in geometries:
if geometry.area > 0:
insert_cursor.insertRow([geometry, polygon[1]])
I was able to move out the insert_cursor, by adding in code for an edit session. However can't figure out how to pull out the UpdateCursor without losing the functionality, since it's deleting and inserting rows back into the original feature it needs to get a new UpdateCursor each time.
def cut_geometry(to_cut, cutter):
"""
Cut a feature by a line, splitting it into its separate geometries.
:param to_cut: The feature to cut.
:param cutter: The polylines to cut the feature by.
:return: The feature with the split geometry added to it.
"""
arcpy.AddField_management(to_cut, "SOURCE_OID", "LONG")
geometries = None
polygon = None
edit = arcpy.da.Editor(os.path.dirname(to_cut))
edit.startEditing(False, False)
insert_cursor = arcpy.da.InsertCursor(to_cut, ["SHAPE@", "SOURCE_OID"])
with arcpy.da.SearchCursor(cutter, "SHAPE@") as lines:
for line in lines:
with arcpy.da.UpdateCursor(to_cut, ["SHAPE@", "OID@"]) as polygons:
for polygon in polygons:
if line[0].disjoint(polygon[0]) == False:
geometries = polygon[0].cut(line[0])
polygons.deleteRow()
for geometry in geometries:
if geometry.area > 0:
insert_cursor.insertRow([geometry, polygon[1]])
edit.stopEditing(True)
Answer
[UPDATED TO HANDLE INTERSECTING LINES]
Can also be download as a toolbox here: https://github.com/tforward/CutPolygonByLines
import os
def cut_geometry(to_cut, cutter):
"""
Cut a feature by a line, splitting it into its separate geometries.
:param to_cut: The feature to cut.
:param cutter: The polylines to cut the feature by.
:return: The feature with the split geometry added to it.
"""
arcpy.AddField_management(to_cut, "SOURCE_OID", "LONG")
geometries = []
polygon = None
edit = arcpy.da.Editor(os.path.dirname(to_cut))
edit.startEditing(False, False)
insert_cursor = arcpy.da.InsertCursor(to_cut, ["SHAPE@", "SOURCE_OID"])
with arcpy.da.SearchCursor(cutter, "SHAPE@") as lines:
for line in lines:
with arcpy.da.UpdateCursor(to_cut, ["SHAPE@", "OID@", "SOURCE_OID"]) as polygons:
for polygon in polygons:
if line[0].disjoint(polygon[0]) == False:
if polygon[2] == None:
id = polygon[1]
# Remove previous geom if additional cuts are needed for intersecting lines
if len(geometries) > 1:
del geometries[0]
geometries.append([polygon[0].cut(line[0]), id])
polygons.deleteRow()
for geometryList in geometries:
for geometry in geometryList[0]:
if geometry.area > 0:
insert_cursor.insertRow([geometry, geometryList[1]])
edit.stopEditing(True)
cut_geometry(r"PATH_TO_POLY", r"PATH_TO_LINES")
No comments:
Post a Comment