[GIS] Segment road network line shapefile into new equal length segments line shapefile

arcgis-10.1arcpylinear-referencingNetworkroad

I would like to subdivide a road network for an entire state into segments of equal length. So, Highway X would be divided into 0.5 mile segments, with a record for each segment, and Highway Y would similarly be divided into 0.5 mile segments. Currently, segments vary in length based on intersections and curviness.

I must restrict the segments to trace the road network, so I cannot just connect vertices/nodes, or trace existing arcs/edges. In most cases, the script must insert a new vertex for the 0.5 mile point, to serve as the end point of the segment and the start point for the next segment.

I am familiar with Python/ArcPy and think I may need to use OGR to grab a list of vertices. My GIS software is ArcInfo 10.1 SP2.

Has anyone successfully implemented a solution to this problem, or have an idea on how to solve it?

I've been further exploring the standard tools in ArcGIS 10.1. I'm currently trying the idea of converting all of the vertices to a separate points layer using the Feature Vertices to Points tool. My next step will be playing with this new shapefile in Python:

The tool preserve the topology of the original line road network with the new points, and there is a sequential order to the FIDs, so I believe I can connect the points {for each road, i.e. Interstate 80} from {n} to {n+1}. I can keep track of the accumulated distance between the vertices-now-points. When the accumulated distance adding another point is greater than the threshold {d}, then I need to create a new point between the most recent point and the point-too-far at a distance that will equal the threshold. This becomes the end point for the new segment. Accumulate these points together, draw a line connecting them, and voila, a segment of length {d}. My goal of course is to have these lines be segments in a shapefile, rather than 1000s of new line shapefiles.

If anyone has any experience with those sort of geometric solution, by all means, please chime in.

Best Answer

As with everythin in GIS there's more than one way to do it:

ArcGIS has a feature to do just this, See Divide line function. Of course, remember that you rarely have an exact division unless you use the percentage option (i.e. you will get a bit left over). And, to be honest, I found it would not always work perfectly but it doesn't do too bad a job. Don't confuse the Divide function with Split.

Depending on your requirements, adding M values to the data can either provide a means for splitting it or may be the solution to your problem. I know you say you want to split the lines, but do you NEED to (you don't say what the end goal is). I'm not being funny, I'm just suggesting that lateral thinking in geoprocessing can often provide the answer you need more easily rather than the most obvious route.

If neither of the easy options will do and you want to do this as a script and have ArcGIS, you don't need OGR to grab a list of vertices. You can do it all in ArcPy. Have a look in the manual for examples on reading geometries and then read the section on writing geometries. These sections have ArcPy examples. I'd follow a recipe along the following lines:

  • Create an empty shapefile (destination)
  • For each feature, read the vertices, calculating the distance and bearing between each one and summing the distances until you need to split. As you go, add the vertices to a new line array object.
  • When you need to split use the bearing between your last two points and the remaining distance before 0.5mi to calculate the coordinates of your new point. Add this to your line array object.
  • Insert your line array object into your destination shapefile
  • Loop your code to make another line-array object using the last point as the first point of the new line and then continue reading as before.
  • Rinse and reapeat until done.
  • List item

Finally, Alternatively in any GEOS enabled software (PostGIS, SpatiaLite etc) you should frin an ST_Line_Interpolate_Point. This interpolates points along lines at set distances. You can then use the points as a means to split the lines.

I'm sure there are other ways to do it too :)