ST_{2D|2DT|3D|3DT}DWithin_IndexLeft

Updated at:

Checks whether the distance between two trajectory objects on a specified axis is within a threshold, and directs the query planner to use the GiST index on the column that stores the first trajectory (traj1).

Syntax

bool ST_{2D|2DT|3D|3DT}DWithin_IndexLeft(trajectory traj1, trajectory traj2, float8 dist);
bool ST_{2D|2DT|3D|3DT}DWithin_IndexLeft(trajectory traj1, trajectory traj2, timestamp ts, timestamp te, float8 dist);

The second overload accepts an optional time range (ts, te) to extract sub-trajectories before comparing.

Parameters

ParameterTypeDescription
traj1trajectoryThe first trajectory to compare. Can also be the original trajectory from which a sub-trajectory is extracted using ts and te. The GiST index on this column is used for the index scan.
traj2trajectoryThe second trajectory to compare. Can also be the original trajectory from which a sub-trajectory is extracted using ts and te.
tstimestampStart of the time range for extracting a sub-trajectory. Optional.
tetimestampEnd of the time range for extracting a sub-trajectory. Optional.
distfloat8Distance threshold. Returns true if the distance between the two trajectories is less than or equal to this value.

How it works

When a query compares two trajectory columns using ST_{2D|2DT|3D|3DT}DWithin, the query planner cannot determine which column's index to use. This causes additional computing overheads.

ST_{2D|2DT|3D|3DT}DWithin_IndexLeft resolves this by binding the index lookup to the traj1 column. The query executes in two stages:

  1. Coarse filter: Uses the GiST index on traj1's column to identify candidate rows via bounding box comparison.

  2. Exact check: Applies the precise distance calculation only to the rows that passed the coarse filter.

To check distance without controlling which index is used, see ST_{2D|2DT|3D|3DT}DWithin.

Example

The following example uses EXPLAIN to confirm that the GiST index on the traj column is active when calling ST_3DTDWithin_IndexLeft.

EXPLAIN SELECT count(*) FROM sqltr_test_trajs WHERE ST_3DTDWithin_IndexLeft(traj, ST_makeTrajectory('STPOINT', 'LINESTRING(-70 -30, -72 -34, -73 -35)'::geometry, '[2000-01-01 00:01:30, 2000-01-01 00:15:00)'::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"}]}'), 2);

The query plan shows a Bitmap Index Scan on sqltr_test_traj_gist_2dt, confirming the GiST index is active:

QUERY PLAN
--------------
Aggregate  (cost=4341.89..4341.90 rows=1 width=8)
   ->  Bitmap Heap Scan on sqltr_test_trajs  (cost=103.31..4340.56 rows=529 width=0)
         Recheck Cond: ('BOX2DT(-75 -37 2000-01-01 00:01:29.999994,-68 -28 2000-01-01 00:15:00)'::boxndf &/#& traj)
         Filter: _st_3dtdwithin(traj, '{"trajectory":{"version":1,"type":"STPOINT","leafcount":3,"start_time":"2000-01-01 00:01:30","end_time":"2000-01-01 00:15:00","spatial":"LINESTRING(-70 -30,-72 -34,-73 -35)","timeline":["2000-01-01 00:01:30","2000-01-01 00:08:15","2000-01-01 00:15:00"],"attributes":{"leafcount":3,"velocity":{"type":"integer","length":2,"nullable":true,"value":[120,130,140]},"accuracy":{"type":"float","length":4,"nullable":false,"value":[120.0,130.0,140.0]},"bearing":{"type":"float","length":8,"nullable":false,"value":[120.0,130.0,140.0]},"acceleration":{"type":"string","length":20,"nullable":true,"value":["120","130","140"]},"active":{"type":"timestamp","length":8,"nullable":false,"value":["2010-01-01 11:35:00","2010-01-01 12:35:00","2010-01-01 13:30:00"]}},"events":[{"2":"2010-01-02 15:00:00"},{"3":"2010-01-02 15:30:00"}]}}'::trajectory, '2'::double precision)
         ->  Bitmap Index Scan on sqltr_test_traj_gist_2dt  (cost=0.00..103.18 rows=1586 width=0)
               Index Cond: (traj &/#& 'BOX2DT(-75 -37 2000-01-01 00:01:29.999994,-68 -28 2000-01-01 00:15:00)'::boxndf)