PostGISTrajectory

ST_DistanceCPA

What is ST_DistanceCPA?

ST_DistanceCPA is a PostGIS function that returns the minimum 3D distance between two trajectories at their closest point of approach (CPA). It is the "how close" complement to ST_ClosestPointOfApproach (which gives the "when").

SQL
ST_DistanceCPA(geometry trajectory_a, geometry trajectory_b)float

Inputs must be valid trajectories — measured linestrings whose M values are strictly increasing.

When would you use ST_DistanceCPA?

Use ST_DistanceCPA whenever you need to quantify near-miss severity — minimum vertical-plus-horizontal separation between aircraft, closest approach distance between vessels, or nearest-miss distance between drones in a shared airspace. Combine with ST_ClosestPointOfApproach to report both distance and time of the event.

SQL
1SELECT a.id, b.id,
2       ST_DistanceCPA(a.track, b.track) AS min_dist,
3       ST_ClosestPointOfApproach(a.track, b.track) AS at_time
4FROM flights a, flights b
5WHERE a.id < b.id
6  AND ST_DistanceCPA(a.track, b.track) < 1000;

FAQs

What units are returned?

Distance is in the units of the trajectory's SRS — metres for projected CRSs, degrees for EPSG:4326 (which is almost never useful for real-world analysis). Store trajectories in a projected CRS if you want meaningful distances.

Does ST_DistanceCPA use 3D distance?

Yes. If trajectories have Z, the returned distance is the 3D Euclidean minimum. For 2D trajectories Z is treated as 0. For aviation or underwater use cases, always store Z.

What if the trajectories do not overlap in time?

The function returns NULL. CPA and its distance are only defined on the intersection of the two M ranges. Check with ST_ClosestPointOfApproach(a, b) IS NOT NULL before relying on the distance.

How do I filter only dangerously close pairs?

Use ST_CPAWithin(a, b, threshold) — a boolean that short-circuits the computation as soon as the CPA is inside the threshold, often much faster than computing ST_DistanceCPA(a, b) < threshold directly.