Given a table with line geometry, and one or more points that are snapped to this line in a separate table, I would like to split each line with one or more intersecting points at each of the locations where the line intersects a point.
For example, there is a line, L, with three intersecting points, A, B, and C in order along the line geometry. I would like to return L as four distinct geometries: from the beginning of L to A, from A to B along L, from B to C along L, and from C to the end of L.
In the past I have used shapely for this task, which is a linear referencing problem (http://sgillies.net/blog/1040/shapely-recipes/). However, this would not be practicable in this case, which has many millions of lines and points. Instead, I'm looking for a solution using PostgreSQL/PostGIS.
Note that points are constrained to be on a line. Further, a point can validly be on the start or end of a line, in which case the line need not be split (unless there are other points which are not coincident with the same line's start or end points). The subset lines need to retain their direction and their attributes, but the attributes of the point features do not matter.
Best Answer
The ST_Split PostGIS function is probably what you want.
PostGIS 2.2+ now supports Multi* geometries in ST_Split.
For older versions of PostGIS, read on:
To get a single line split by multiple points, you could use something like this multipoint wrapper plpgsql function. I've simplified it just to the "split (multi)lines with (multi)points" case below:
Then to create a multipoint geometry to cut by, use ST_Collect and either create it manually from inputs:
Or aggregate it from a subquery: