Split line interactively using ArcPy FeatureSets

Back when I was doing a lot of GIS work for civil and electrical asset management, a common task I had was to ensure that all civil structures represented as a polyline (reticulation and bulk pipelines, eletrical feeder cables, road surfaces etc) were split at the physical road intersections as seen on the latest available aerial imagery, as well as where they crossed each other.

This task wasn’t too much trouble if the lines were already drawn across each other, as more often than not, the lines crossed at the road intersections. The result was usually achieved by using the Planarize option on the Advanced Editing toolbar. However, it became a problem for new areas which had to be digitised by hand (no CAD drawings or shapefiles received), or lines which had to be corrected.

I would have to visually check on the imagery where the road intersections were, and then manually split each polyline. I ran through some ideas, including digitising all road intersections as points (which would be good data to have anyway), and then splitting all the lines at the closest intersection by using the Split Line at Point tool.

I did however want to create a method of splitting the line multiple times on the fly, instead of just splitting it once (which is the option provided by the Split button on the Editor toolbar). I wanted to be able to select a line, click as many points along the line as I wanted, and then split the line into those points.

'''
@date 06/10/2015
@author Cindy Williams
@version 1.0
Uses an arcpy FeatureSet to allow the user to interactively create
points on a line which will be used to split that line into parts,
while retaining all attributes.
Requirements:
– Works as a script tool. Add to a toolbox.
– Can only work on a single line for now. Select the line, right
click the layer and "Create layer from selected features". Use
this selection layer as input to the tool.
– Digitise points snapped to the selected line. Tool will fail if not
snapped
– Digitise points left to right along the line.
Future versions will include:
– split multiple lines at same time
– snap points automatically/error that points should be snapped
– points will be sorted after digitising to ensure correct order
Built on an idea here http://gis.stackexchange.com/questions/154708/standalone-python-script-to-split-a-polyline-with-a-point-layer
'''
import arcpy
inset = arcpy.GetParameter(0) # FeatureSet of interactive points from ArcMap
inline = arcpy.GetParameterAsText(1) # Input polyline feature layer
# Get all field names excluding dynamic fields
fields = ["SHAPE@"]
fields.extend([field.name for field in arcpy.ListFields(inline) if field.name not in ["OBJECTID", "Shape_Length", "Shape"]])
# Open an insert cursor for inserting the cut lines
cursor_ins = arcpy.da.InsertCursor(inline, fields)
# Get the spatial reference from the polyline
sr = arcpy.Describe(inline).spatialReference
# Get the polyline and delete the original record
with arcpy.da.UpdateCursor(inline, fields) as cursor:
for row in cursor:
polyline = row
cursor.deleteRow()
# Iterate over the points
with arcpy.da.SearchCursor(inset, "SHAPE@") as cursor:
for row in cursor:
point = row[0].firstPoint
# Build a temporary diagonal line from the point
diag = arcpy.Polyline(arcpy.Array([arcpy.Point(point.X + 10.0, point.Y + 10.0), arcpy.Point(point.X10.0, point.Y10.0)]), sr)
# Cut the original polyline
geom = polyline[0].cut(diag)
# Create a new line with the right side of the geom i.e. finished with this side
newline = [geom[1]]
newline.extend(polyline[1:])
# Insert the line into the feature layer
cursor_ins.insertRow(newline)
# Set the left side of the cut line as the new line for cutting
polyline = [geom[0]]
polyline.extend(newline[1:])
# Insert the last portion of the line
cursor_ins.insertRow(polyline)
del cursor_ins
del polyline

The tool iterates over all the points created by the user in the FeatureSet. For each point, a temporary diagonal is created to cut the original polyline. This new part is saved in a list and the tool runs again on the original polyline (minus the new part). Once all the points have been processed, the original polyline is removed from the feature class, and the new parts are inserted. All feature attributes are maintained.

My intention with this tool was to expand it with more features, fix the bugs (it would randomly not work) and upload it as a toolbox. However, the need to do that fell away. I also realised I was starting to get into a space where I was forcing as much code as I could into my work in order to get through the day.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.