Split Lines at Intersection of Other Lines
Note that as of QGIS 2.8, there's a new tool in Processing Toolbox called "Split lines with lines" that does exactly this task and works beautifully.
You can use Python with shapely , with PyQGIS or directly with OpenJump GIS or PostGIS as mnt.biker says.
With Python:
1) the first solution is to find the intersections of the lines and then break the input coords into parts (look at cut.py or Get the vertices on a LineString either side of a Point with shapely) -> not very easy...
2) a more direct solution is to use the union
operations (combine
with PyQGIS) : the method will split all self-intersection geometries ([geos-devel] split self-intersecting LineString into non-intersecting lines)
Example with shapely and Fiona (similar with PyQGIS)
import fiona
# open the line shapefile and transform to shapely geometry
file = fiona.open('line.shp')
from shapely.geometry import shape
line = shape(file.next()['geometry'])
# open the contours shapefile and transform to MultLineString shapely geometry
Multi = MultiLineString([shape(lin['geometry']) for lin in fiona.open('contours.shp')])
# now you can use the `union`, `cascaded_union`or `unary_union`of shapely
result = unary_union([line, Multi])
and save the resulting shapefile with Fiona.
If you want to save only the line that needs to be cut, look at Code for splitting a line with another line
And you can use a spatial index with the module Rtree to speed things up.
3) but the most comprehensive solution is to compute the Topological Planar Graph of the combined layers.
it can be drawn on the plane in such a way that its edges intersect only at their endpoints. In other words, it can be drawn in such a way that no edges cross each other
I have a Python class to do it but I will use here OpenJump:
Whith OpenJump GIS and Planar Graph command
1) you load the shapefiles and compute the union (combined layer):
2) you compute the Planar Graph
3) and you have the nodes, the faces and the arcs (edges) of the Graph as as the result , all with the corresponding attribute values preserved.
Whith PostGIS (version 2.00 and up) (mnt.biker answer)
The result are the same
New
In OpenJUMP use Combine Layers
("Rassemblez les couches" in French) and not Union
I would do the job with OpenJUMP and the Noder tool.
Open your line layers into OpenJUMP
Combine the layers for further processing
This tool will transform all the attributes from the source layers and add a new attribute "LAYER". That will be useful later.
Next use the Noder tool from the menu "Tools - Edit Geometry - Noder.."
Lines will be noded and split. A few split roads selected as a proof.
Finally you can extract the contours and roads back to their own layers by utilizing the LAYER attribute. OpenJUMP has an "Extract Layer by Attribute" tool in the Edit menu for this purpose.