PostGISGeometry Constructors

ST_MakeLine

What is ST_MakeLine?

ST_MakeLine is a PostGIS function that constructs a LINESTRING from an ordered collection of point (or linestring) geometries. It is the canonical constructor for building lines out of individual vertices in SQL.

SQL
1ST_MakeLine(geometry pt1, geometry pt2)geometry
2ST_MakeLine(geometry[] pts_array)geometry
3ST_MakeLine(geometry set points)geometry   -- aggregate form

All inputs must share the same SRID. Z and M values from input points are preserved in the resulting line. Inputs can also be LINESTRINGs, in which case they are concatenated in order.

When would you use ST_MakeLine?

Use ST_MakeLine to assemble a polyline from an ordered set of points — the classic example is reconstructing a GPS track from individual fixes, ordered by timestamp:

SQL
1SELECT trip_id,
2       ST_MakeLine(geom ORDER BY recorded_at) AS track
3FROM gps_fix
4GROUP BY trip_id;

Other common uses include drawing a straight line between an origin and destination for flight routes or spider-map visualizations (ST_MakeLine(origin_pt, dest_pt)), stitching pre-computed polyline segments together, and constructing synthetic test geometries.

For best results with the aggregate form, always include an explicit ORDER BY — without it the vertex order depends on whatever order the planner happens to deliver rows.

FAQs

How do I control vertex order in the aggregate form?

Use ORDER BY inside the aggregate: ST_MakeLine(geom ORDER BY seq). Without it the order is not deterministic. This is the most common source of "my line zigzags" bugs.

What is the difference between ST_MakeLine and ST_LineFromMultiPoint?

ST_MakeLine builds a line directly from points or an array; ST_LineFromMultiPoint requires a MULTIPOINT input. ST_MakeLine is more flexible and more common — reserve ST_LineFromMultiPoint for when you already have a MULTIPOINT value.

Does ST_MakeLine preserve Z and M values?

Yes. If input points carry Z or M, those dimensions are preserved in the output line. Mixing dimensioned and non-dimensioned points produces implementation-dependent behaviour — normalize inputs with ST_Force3D or ST_Force2D first.

What happens if I pass only one point?

The aggregate form returns NULL if fewer than two input points are provided. The two-argument form requires both arguments to be non-null points. Filter with HAVING COUNT(*) >= 2 when grouping.