More

Method to split line segments in a road network that are greater than X length into n smaller line segments using ArcGIS?

Method to split line segments in a road network that are greater than X length into n smaller line segments using ArcGIS?


I'm using ArcGIS Desktop 10.2 and I'd like to take roads in a network greater than a certain length and split them into equal smaller pieces. I've noticed that splitting by percent can be achieved via the Editor Menu; however, it appears this must be done on a line-by-line basis.

Could you suggest ways of automating the process to split all roads over a certain length into smaller parts based on the percent of the original?


A little Python automation gets this job done. The basic steps:

  • Determine max distance in feature class's units with help from a spatial reference object (requires projected feature class I do believe)
  • Create a new, empty feature class with the input line feature class as its template
  • Iterate input feature class and check its line lengths
  • If the length is too long, continually split the line with the use of awhileloop,position along line, andsplit line at point.
  • Once lines are shorter than the max length, add row object to a list
  • Insert all row objects into new feature class with an insert cursor

Inputs:

inFc: input line feature class

outFc: output feature class

dist: max distance in meters

Code:

#Full path to input line feature class inFc = r"C:Userse1b8DesktopE1B8WorkspaceWorkspace5.gdb	estLines_split" #Full path to output line feature class outFc = r"C:Userse1b8DesktopE1B8WorkspaceWorkspace5.gdb	estLines_split2" #Distance (meters) dist = 15 #----------- import arcpy import os #overwrite outputs (optional) arcpy.env.overwriteOutput = True print "determining spatial reference info" #Get spatial reference object sr = arcpy.Describe (inFc).spatialReference #meters conversion metersPerUnit = sr.metersPerUnit #Distance in feature class units checkDistance = dist / metersPerUnit print "max distance:", checkDistance print "creating output feature class" #Create out feature class outPath = os.path.dirname (outFc) outName = os.path.basename (outFc) arcpy.CreateFeatureclass_management (outPath, outName, "POLYLINE", inFc, spatial_reference = sr) #set workspace arcpy.env.workspace = outPath #list with geometry field fields = ["[email protected]"] #Add feature class fields to list fields += [f.name for f in arcpy.ListFields (inFc)] #Get objectid field name oidFld = arcpy.Describe (inFc).OIDFieldName #Remove oid field from fields list fields.remove (oidFld) #empty list to have rows appended to rows = [] print print "iterating", arcpy.GetCount_management (inFc).getOutput (0), "rows" i = 0 #cursor to iterate feature class with arcpy.da.SearchCursor (inFc, fields) as cursor: #iterate rows for row in cursor: i += 1 #get geometry object geometry = row [0] #get length length = geometry.length #check if length longer than limit if length > checkDistance: print "row", i print "line length:", length #empty list for intermediate date to be deleted garbage = [] #create empty line fc for single feature split = arcpy.CreateUniqueName ("split") outPath = os.path.dirname (split) outName = os.path.basename (split) arcpy.CreateFeatureclass_management (outPath, outName, "POLYLINE", inFc, spatial_reference = sr) #insert feature in new fc with arcpy.da.InsertCursor (split, fields) as cur: cur.insertRow (row) del cur #add new fc to garbage garbage += [split] #create empty point fc for single feature midPnt = arcpy.CreateUniqueName ("point") outPath = os.path.dirname (midPnt) outName = os.path.basename (midPnt) arcpy.CreateFeatureclass_management (outPath, outName, "POINT", spatial_reference = sr) #Get midpoint pnt = geometry.positionAlongLine (.5, True) #insert point into new feature class with arcpy.da.InsertCursor (midPnt, "[email protected]") as cur: cur.insertRow ((pnt,)) del cur #add new fc to garbage garbage += [midPnt] #loop while length is greater than limit while length > checkDistance: #Split line at (mid)point newSplit = arcpy.CreateUniqueName("split") garbage += [newSplit] arcpy.SplitLineAtPoint_management (split, midPnt, newSplit) #Create new mid points midPnt = arcpy.CreateUniqueName ("point") garbage += [midPnt] outPath = os.path.dirname (midPnt) outName = os.path.basename (midPnt) arcpy.CreateFeatureclass_management (outPath, outName, "POINT", spatial_reference = sr) #empty list for new points pnts = [] #iterate split line and get midpoints with arcpy.da.SearchCursor (newSplit, "[email protected]") as cur: for geom, in cur: pnt = geom.positionAlongLine (.5, True) pnts += [pnt] del cur #add midpoints to midpoint feature class with arcpy.da.InsertCursor (midPnt, "[email protected]") as cur: for pnt in pnts: cur.insertRow ((pnt,)) del cur #divide length variable by two length = length / 2 print "line length:", length split = newSplit rows += [row for row in arcpy.da.SearchCursor (split, fields)] #clean up intermediate data for trash in garbage: arcpy.Delete_management (trash) else: rows += [row] #del cursor variable del cursor print print "inserting rows into new feature class" #insert cursor new feature class with rows with arcpy.da.InsertCursor (outFc, fields) as cursor: for row in rows: cursor.insertRow (row) del cursor print print "created:", outFc print print "done"

Output looks something like this:

determining spatial reference info max distance: 65.6166666667 creating output feature class iterating 11 rows row 4 line length: 90.6641581736 line length: 45.3320790868 row 6 line length: 81.7030489448 line length: 40.8515244724 row 7 line length: 82.7060163161 line length: 41.3530081581 row 9 line length: 97.005780961 line length: 48.5028904805 row 10 line length: 90.6565601113 line length: 45.3282800557 inserting rows into new feature class created: C:Userse1b8DesktopE1B8WorkspaceWorkspace5.gdb	estLines_split2 done

In feature class:

Out feature class:


It is not exactly equivalent to the process you describe, but ArcGIS has the Dice tool to automatically split long lines into parts of X vertices. It doesn't use a percentage limit though, but merely a vertex limit. Still, if your only intention is to split the lines up in about equal sizes, it may be useful:

http://resources.arcgis.com/EN/HELP/MAIN/10.2/index.html#//001700000037000000


Watch the video: split line at vertices in ArcGIS