Split into equal length features

Request came in last week for a way to split a line feature into 10 equal length line features.

The input looked like this
stream1

The accepted solution came from Dave on the team who sent this elegant and efficient solution.

in_fc = r'c:\projects\waterway.gdb\stream'
out_fc = r'c:\projects\waterway.gdb\stream10'
out_count = 10 # how many features desired

line = arcpy.da.SearchCursor(in_fc, ("SHAPE@",)).next()[0]
arcpy.CopyFeatures_management([line.segmentAlongLine(i/float(out_count), ((i+1)/float(out_count)), True) for i in range(0, out_count)], out_fc)

Which outpus a new feature class containing 10 line features like so
stream10

How does it work? The first 3 lines are self explanatory. So we will skip.

The following line is also fairly simple, what it does is get the geometry (shape@) of the first record (we only ask for next() once). The [0] is needed to get just the first value in the record (remember cursors return lists of values).


polyline = arcpy.da.SearchCursor(in_fc, ("SHAPE@",)).next()[0]

Next is where the magic happens, python list comprehension is used to turn the polyline object into a list of 10 (as per the out_count variable) equal length segments generated by the segmentAlongLine function. This list of polyline is then used as input to CopyFeatures (as per Using geometry objects with geoprocessing tools) which writes out the 10 polyline as individual features into the output feature class (out_fc).


arcpy.CopyFeatures_management([polyline.segmentAlongLine(i/float(out_count), ((i+1)/float(out_count)), True) for i in range(0, out_count)], out_fc)

EDIT: As was pointed out in the comments, the segmentAlongLine is new at 10.3.

Cheers

merge polyline paths

Somebody on the team was having trouble tracing streams due to breaks in the streams introduced when converting raster to feature.

So here is slick little solution which takes n paths in a line features and makes a 1 path (aka 1 part) out of it.
None of the vertices are moved. Where there were two paths separated by a gap you will have one path with no gap.

To work property the paths have to be pointed in the same direction and not be converging. To deal with that would require quite a bit more logic.

As is script modified data in place, so back up your data before using.

Splitting a line with a point

Recently I got an email where a colleague was trying to determine the distance a point on a line was from the beginning.  They were spinning their wheels looking at geometry operators and not seeing a solution.

First and foremost arcpy offers a broad broad collection of geoprocessing tools. What is perhaps less obvious is how those tools can be used directly with geometry objects. In the above scenario, using geometry as both input and output offers the solution to the problem. At a functional level, the Split Line at Points tool offers the solution. Being able to use it directly with geometry saves the hassle (and mess) of creating temporary datasets to work with.

import arcpy

def split_line_with_point(in_line, in_point, search_radius=0):
    """Splits a Polyline object with a PointGeometry object. Returns
    a list of two Polyline geometries. First line will include the
    starting point of the in_line. Curves are supported.

    Parameters:
    in_line: arcpy.Polyline
    in_point: arcpy.PointGeometry
    search_radius: string | float | int
        Use to split the lines based on its proximity to the point.
        Line will be split at the nearest location to the point.
        If search_radius is 0, the point must be on the line.
        Can be expressed as a number or linear unit.
    """

    split_lines = arcpy.management.SplitLineAtPoint(
        in_line,
        in_point,
        arcpy.Geometry(),
        search_radius)

    if len(split_lines) == 1:
        raise Exception('Line could not be split')
    else:
        return split_lines

So to answer the original question, to get the distance a point on a line is from the beginning, you could use the above function and then ask for the length property of the first Polyline returned in the list.

distance = split_line_with_point(line, point)[0].length