All Products
Search
Document Center

PolarDB:ST_{2D|2DT|3D|3DT}DWithin

Last Updated:Mar 28, 2026

Returns true if the distance between two objects on a specified axis is no larger than dist.

Variants

VariantWhat it checks
ST_2DDWithin2D distance between the planar projections of two objects
ST_3DDWithin3D distance between the spatial projections of two objects
ST_2DTDWithin2D distance between two objects at a specified point in time
ST_3DTDWithin3D distance between two objects at a specified point in time

Syntax

-- geometry vs. trajectory
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);

-- bounding box vs. trajectory
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);

-- trajectory vs. trajectory
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);

Parameters

ParameterDescription
geomThe geometry to compare.
trajThe trajectory to compare, or the original trajectory containing the sub-trajectory to compare.
traj1The first trajectory to compare, or the original trajectory containing the first sub-trajectory to compare.
traj2The second trajectory to compare, or the original trajectory containing the second sub-trajectory to compare.
boxThe bounding box (boxndf) to compare.
ts(Optional) Start of the time range for sub-trajectory extraction.
te(Optional) End of the time range for sub-trajectory extraction.
distThe distance threshold.

How it works

When ts and te are provided, the function extracts sub-trajectories over that time range and compares them. Without ts and te, the function compares the complete trajectories.

ST_DistanceWithin is an alias for this function family. It behaves like ST_2DDWithin when one of the objects is a geometry, and like ST_3DTDWithin when both objects are trajectories.

Examples

The examples below use two parallel trajectories that move along the x-axis at y=0 and y=20, covering x from 0 to 100 over a 100-second interval. The 2D distance between them is always 20.

Set up the trajectories:

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
)

Check whether the 2D distance is within 19 over t=0 to t=49:

SELECT ST_2dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) FROM traj;
-- f  (distance is 20, which exceeds 19)

Check whether the 2D distance is within 20 over t=0 to t=50:

SELECT ST_2dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(50), 20) FROM traj;
-- t  (distance is exactly 20)

Check whether the 3D distance is within 20 over t=0 to t=50:

SELECT ST_3dDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(50), 20) FROM traj;
-- t
When one or both trajectories lack a z-value, the 3D variants treat the missing z as any value: One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value".

Check the 2DT and 3DT variants over t=0 to t=49 with threshold 19:

SELECT ST_2dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) FROM traj;
-- f

SELECT ST_3dtDWithin(a, b, ST_PGEpochToTS(0), ST_PGEpochToTS(49), 19) FROM traj;
-- f

Full result across all variants and thresholds:

SELECT
  ST_2dDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(49), 19),   -- f
  ST_3dDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(49), 19),   -- f
  ST_2dDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(50), 20),   -- t
  ST_3dDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(50), 20),   -- t
  ST_2dDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(70), 21),   -- t
  ST_3dDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(70), 21),   -- t
  ST_2dtDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(49), 19),  -- f
  ST_3dtDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(49), 19),  -- f
  ST_2dtDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(50), 20),  -- t
  ST_3dtDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(50), 20),  -- t
  ST_2dtDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(70), 21),  -- t
  ST_3dtDWithin(a,b, ST_PGEpochToTS(0),ST_PGEpochToTS(70), 21)   -- t
FROM traj;