I've put together some code below which seems to create single segment lines from polyline (which can be multipart) feature classes while retaining their attributes.
I recommend that you run it against a small test dataset or two first, and if it seems to do what you want, then comment out or remove the print statements to gain some performance.
If you add this to a Python script tool then you should be able to use it in a model at either ArcGIS 10.1 or 10.2. Earlier versions will not be able to use it because I have included arcpy.da for performance.
import arcpy
inFC = r"C:\temp\testLines.shp"
outFC = r"C:\temp\testLinesSplit.shp"
if arcpy.Exists(outFC):
arcpy.Delete_management(outFC)
arcpy.CreateFeatureclass_management("C:/temp","testLinesSplit.shp","POLYLINE","#","DISABLED","DISABLED",inFC)
arcpy.AddField_management(outFC,"inFID","LONG","#","#","#","#","NULLABLE","NON_REQUIRED","#")
iCursor = arcpy.da.InsertCursor(outFC, ["inFID","SHAPE@"])
with arcpy.da.SearchCursor(inFC,["OID@", "SHAPE@"]) as sCursor:
for row in sCursor:
inFID = row[0]
# Print the current multipoint's ID
#
print("Feature {0}:".format(row[0]))
partnum = 0
# Step through each part of the feature
#
for part in row[1]:
# Print the part number
#
print("Part {0}:".format(partnum))
# Step through each vertex in the feature
#
prevX = None
prevY = None
for pnt in part:
if pnt:
# Print x,y coordinates of current point
#
print("{0}, {1}".format(pnt.X, pnt.Y))
if prevX:
array = arcpy.Array([arcpy.Point(prevX, prevY),
arcpy.Point(pnt.X, pnt.Y)])
polyline = arcpy.Polyline(array)
iCursor.insertRow([inFID,polyline])
prevX = pnt.X
prevY = pnt.Y
else:
# If pnt is None, this represents an interior ring
#
print("Interior Ring:")
partnum += 1
del iCursor
arcpy.JoinField_management(outFC,"inFID",inFC,"FID","#")
When importing a line vector into GRASS, the topology cleaning automatically splits lines at every intersection. If you need to split lines at additional points, you can use
v.edit
The tool=break is what you need, and the "coords" parameter is for the X-Y of the point to split. If you have the coordinates of all your "junctions" then feed those in a loop into the v.edit command. You might do this by dumping the X-Y coordinates of the junctions into a text file with v.out.ascii. Then read the text file, line by line, in a bash loop, something like:
v.out.ascii junctions separator=" " out=junction_coords.txt
while read x y cat; do \
v.edit map=hydro_network tool=break coords=$x,$y; \
done < junction_coords.txt
BTW, if the junction points are not exactly on the line, you will want to look into the combination of:
v.distance
v.patch
v.clean
This procedure creates small connector lines from the jucntion points to the hydro_network, then by patching these connectors to the network, and running v.clean, you get an "error" output point vector which is the intersection points of each connector and the original hydro_network. THis way you can get a new set of "snapped" junction points which fall exactly on the hydro_network.
Best Answer
Try the "Explode lines" from the Processing Toolbox (Ctrl+Alt+T) will split all lines at their vertices to separate lines.
Menu Processing -> Toolbox. Type "explode" into the search field to find the function. Select your line layer from the dropdown and start. This will produce a new layer.
Selecting one or more lines from the line layer will produce a splitted layer with only these features, discarding the rest.
Note: As QGIS is moving fast, all infos below are outdated already.