Tests whether the distance between two spatial objects is less than or equal to a specified threshold, across 2D, 3D, or spatiotemporal dimensions.
Syntax
bool ST_{2D|3D}DWithin(geometry geom, trajectory traj, float8 dist);
bool ST_{2D|3D}DWithin(trajectory traj, geometry geom, float8 dist);
bool ST_{2D|3D}DWithin(geometry geom, trajectory traj, timestamp ts, timestamp te, float8 dist);
bool ST_{2D|3D}DWithin(trajectory traj, geometry geom, timestamp ts, timestamp te, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin(boxndf box, trajectory traj, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin(trajectory traj, boxndf box, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin(boxndf box, trajectory traj, timestamp ts, timestamp te, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin(trajectory traj, boxndf box, timestamp ts, timestamp te, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin(trajectory traj1, trajectory traj2, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin(trajectory traj1, trajectory traj2, timestamp ts, timestamp te, float8 dist);Choose the variant based on what you want to measure:
2D / 3D: distance between the spatial projections of the two objects (ignores time)
2DT / 3DT: distance between the two objects at each point in time over a shared timeline (spatiotemporal) To limit the comparison to a specific time window, providetsandte. Withouttsandte, the function compares the complete trajectories.
ST_DistanceWithinis an alias for this function family. When one argument is a geometry, it behaves likeST_2DDWithin. When both arguments are trajectories, it behaves likeST_3DTDWithin.
Parameters
| Parameter | Description |
|---|---|
geom | The geometry to compare. |
traj | The trajectory to compare, or the source trajectory from which a sub-trajectory is extracted. |
traj1 | The first trajectory to compare, or the source trajectory from which a sub-trajectory is extracted. |
traj2 | The second trajectory to compare, or the source trajectory from which a sub-trajectory is extracted. |
box | The bounding box to compare. |
ts | The start of the time range for sub-trajectory extraction. Optional. |
te | The end of the time range for sub-trajectory extraction. Optional. |
dist | The distance threshold. |
Description
For 2D and 3D variants, the function checks whether the distance between the two- or three-dimensional projections of the two objects is less than or equal to dist.
For 2DT and 3DT variants, the function checks whether the distance between the two objects in a specified dimension at a specified point in time is less than or equal to dist.
When ts and te are provided, the function extracts sub-trajectories over that time range before computing the distance. When omitted, the function uses the complete trajectories.
Examples
2D vs 3D comparison
The following example shows how 2D and 3D distance checks can produce different results for the same trajectory pair. Trajectory a travels along z=10, while trajectory b travels along z=0 (no z-coordinate). The 3D check accounts for the z-axis gap; the 2D check projects both objects onto the XY plane.
WITH traj AS (
SELECT
ST_makeTrajectory('STPOINT', 'LINESTRING(0 0 10, 50 0 10, 100 0 10)'::geometry,
('[' || ST_PGEpochToTS(0) || ',' || ST_PGEpochToTS(100) || ')')::tsrange,
'{"leafcount":3,"attributes":{"velocity":{"type":"integer","length":2,"nullable":true,"value":[120,130,140]},"accuracy":{"type":"float","length":4,"nullable":false,"value":[120,130,140]},"bearing":{"type":"float","length":8,"nullable":false,"value":[120,130,140]},"acceleration":{"type":"string","length":20,"nullable":true,"value":["120","130","140"]},"active":{"type":"timestamp","nullable":false,"value":["Fri Jan 01 11:35:00 2010","Fri Jan 01 12:35:00 2010","Fri Jan 01 13:30:00 2010"]}},"events":[{"2":"Fri Jan 02 15:00:00 2010"},{"3":"Fri Jan 02 15:30:00 2010"}]}') a,
ST_makeTrajectory('STPOINT', 'LINESTRING(0 20, 50 20, 100 20)'::geometry,
('[' || ST_PGEpochToTS(0) || ',' || ST_PGEpochToTS(100) || ')')::tsrange,
'{"leafcount":3,"attributes":{"velocity":{"type":"integer","length":2,"nullable":true,"value":[120,130,140]},"accuracy":{"type":"float","length":4,"nullable":false,"value":[120,130,140]},"bearing":{"type":"float","length":8,"nullable":false,"value":[120,130,140]},"acceleration":{"type":"string","length":20,"nullable":true,"value":["120","130","140"]},"active":{"type":"timestamp","nullable":false,"value":["Fri Jan 01 11:35:00 2010","Fri Jan 01 12:35:00 2010","Fri Jan 01 13:30:00 2010"]}},"events":[{"2":"Fri Jan 02 15:00:00 2010"},{"3":"Fri Jan 02 15:30:00 2010"}]}') b
)
SELECT
ST_2dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) AS "2D dist=19 [0,49)",
ST_3dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) AS "3D dist=19 [0,49)",
ST_2dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(50), 20) AS "2D dist=20 [0,50)",
ST_3dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(50), 20) AS "3D dist=20 [0,50)",
ST_2dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(70), 21) AS "2D dist=21 [0,70)",
ST_3dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(70), 21) AS "3D dist=21 [0,70)"
FROM traj;Result:
NOTICE: One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value"
NOTICE: One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value"
2D dist=19 [0,49) | 3D dist=19 [0,49) | 2D dist=20 [0,50) | 3D dist=20 [0,50) | 2D dist=21 [0,70) | 3D dist=21 [0,70)
--------------------+--------------------+--------------------+--------------------+--------------------+--------------------
f | f | t | t | t | tBoth functions return f at dist=19 over the [0, 49) window because neither projection falls within 19 units. Raising the threshold to 20 over [0, 50) brings both to t.
2DT and 3DT (spatiotemporal)
The spatiotemporal variants evaluate distance at each point in time rather than on a static spatial projection. Using the same trajectory pair, ST_2dtDWithin and ST_3dtDWithin produce the same results as their 2D/3D counterparts because both objects share the same timeline and XY separation is the dominant factor.
WITH traj AS (
SELECT
ST_makeTrajectory('STPOINT', 'LINESTRING(0 0 10, 50 0 10, 100 0 10)'::geometry,
('[' || ST_PGEpochToTS(0) || ',' || ST_PGEpochToTS(100) || ')')::tsrange,
'{"leafcount":3,"attributes":{"velocity":{"type":"integer","length":2,"nullable":true,"value":[120,130,140]},"accuracy":{"type":"float","length":4,"nullable":false,"value":[120,130,140]},"bearing":{"type":"float","length":8,"nullable":false,"value":[120,130,140]},"acceleration":{"type":"string","length":20,"nullable":true,"value":["120","130","140"]},"active":{"type":"timestamp","nullable":false,"value":["Fri Jan 01 11:35:00 2010","Fri Jan 01 12:35:00 2010","Fri Jan 01 13:30:00 2010"]}},"events":[{"2":"Fri Jan 02 15:00:00 2010"},{"3":"Fri Jan 02 15:30:00 2010"}]}') a,
ST_makeTrajectory('STPOINT', 'LINESTRING(0 20, 50 20, 100 20)'::geometry,
('[' || ST_PGEpochToTS(0) || ',' || ST_PGEpochToTS(100) || ')')::tsrange,
'{"leafcount":3,"attributes":{"velocity":{"type":"integer","length":2,"nullable":true,"value":[120,130,140]},"accuracy":{"type":"float","length":4,"nullable":false,"value":[120,130,140]},"bearing":{"type":"float","length":8,"nullable":false,"value":[120,130,140]},"acceleration":{"type":"string","length":20,"nullable":true,"value":["120","130","140"]},"active":{"type":"timestamp","nullable":false,"value":["Fri Jan 01 11:35:00 2010","Fri Jan 01 12:35:00 2010","Fri Jan 01 13:30:00 2010"]}},"events":[{"2":"Fri Jan 02 15:00:00 2010"},{"3":"Fri Jan 02 15:30:00 2010"}]}') b
)
SELECT
ST_2dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) AS "2DT dist=19 [0,49)",
ST_3dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) AS "3DT dist=19 [0,49)",
ST_2dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(50), 20) AS "2DT dist=20 [0,50)",
ST_3dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(50), 20) AS "3DT dist=20 [0,50)",
ST_2dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(70), 21) AS "2DT dist=21 [0,70)",
ST_3dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(70), 21) AS "3DT dist=21 [0,70)"
FROM traj;Result:
NOTICE: One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value"
NOTICE: One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value"
2DT dist=19 [0,49) | 3DT dist=19 [0,49) | 2DT dist=20 [0,50) | 3DT dist=20 [0,50) | 2DT dist=21 [0,70) | 3DT dist=21 [0,70)
---------------------+---------------------+---------------------+---------------------+---------------------+---------------------
f | f | t | t | t | t