ArcPy – Deleting Line Vertices Inside a Polygon using ArcGIS Desktop

arcgis-10.1arcgis-desktoparcpypoint-in-polygonvertices

Is there a way to automatically delete vertices in line features using a polygon file in ArcGIS so that it wouldn't cut up the line but just straightens the line inside the polygon?

The lines are lines and the box represents a polygon that covers them. I want to delete line vertices that are inside the polygon so the line would be straight inside the polygon boundary like on the illustration.

I use ArcGIS 10.1 but have access to other software also if something offers the solution.

Lines are lines, box is polygon.

Best Answer

The key is the difference method on geometry objects. The following code is far from efficient, since a new update cursor is opened for each polygon. But it has the added benefit of supporting multiple polygons on the same line:

import itertools, arcpy
arcpy.env.overwriteOutput = True
line_FC = r'<path to lines>'
poly_FC = r'<path to polygons>'
output = r'<path to result>'

#clone input lines to memory for fast processing
temp = arcpy.CopyFeatures_management(line_FC, "in_memory/temp")

polygons = arcpy.CopyFeatures_management(poly_FC, arcpy.Geometry())

for poly in polygons:
    with arcpy.da.UpdateCursor(temp, ["SHAPE@"]) as uCursor:
        for line in uCursor:
            line = line[0]
            diff = line.difference(poly)
            #if the two lines are not equal, that means it intersected the polygon
            if not line.equals(diff):
                #the result of geometry.difference() is a multipart line of only those
                #parts that lie outside the polyon
                parts = diff.getPart()

                #if parts is empty that means the line is completely within the polygon
                #i.e., no difference
                if parts:
                    #We'll need to "join" the end of part1 to the beginning of part2
                    #so we'll just flatten the list of lists
                    joined = list(itertools.chain.from_iterable(parts))

                    #and create a new polyline object to update the shape
                    poly_trimmed = arcpy.Polyline(arcpy.Array(joined))
                    uCursor.updateRow([poly_trimmed])

arcpy.CopyFeatures_management(temp, output)

I haven't tested it with edge cases, but this should get you started. enter image description here

Related Question