Spatial Relationships

The topological relationships such as ST_Intersects and the distance relationships such as ST_DWithin can be generalized for temporal points. The arguments of these generalized functions are either a temporal point and a base type (that is, a geometry or a geography) or two temporal points. Furthermore, both arguments must be of the same base type, that is, these functions do not allow to mix a temporal geometry point (or a geometry) and a temporal geography point (or a geography).

There are two versions of the spatial relationships:

The semantics of the possible relationships varies depending on the relationship and the type of the arguments. For example, the following query

SELECT intersects(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))',
  tgeompoint '[Point(0 1)@2012-01-01, Point(1 1)@2012-01-03)');

tests whether the temporal point ever intersected the geometry, since the query is conceptually equivalent to the following one

SELECT ST_Intersects(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))',
  geometry 'Linestring(0 1,1 1)');

where the second geometry is obtained by applying the trajectory function to the temporal point. On the other hand, the query

SELECT contains(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))',
  tgeompoint '[Point(0 1)@2012-01-01, Point(1 1)@2012-01-03)');

tests whether the geometry always contains the temporal point. Finally, the following query

SELECT intersects(tgeompoint '[Point(0 1)@2012-01-01, Point(1 0)@2012-01-03)',
  tgeompoint '[Point(0 0)@2012-01-01, Point(1 1)@2012-01-03)');

tests whether the temporal points may intersect in space independently of time, since the query above is conceptually equivalent to the following one

SELECT ST_Intersects('Linestring(0 1,1 0)', 'Linestring(0 0,1 1)');

The possible relationships are typically used in combination with a spatiotemporal index when computing the temporal relationships. For example, the following query

SELECT T.TripId, R.RegionId, tintersects(T.Trip, R.Geom)
FROM Trips T, Regions R
WHERE intersects(T.Trip, R.Geom)

which verifies whether a trip T (which is a temporal point) intersects a region R (which is a geometry), will benefit from a spatiotemporal index on the column T.Trip since the intersects function will automatically perform the bounding box comparison T.Trip && R.Geom. This is further explained later in this document.

Not all spatial relationships available in PostGIS have a meaningful generalization for temporal points. A generalized version of the following relationships are defined for temporal geometric points: intersects, disjoint, dwithin, contains, and touches, while for temporal geographic points only the three first ones are defined. Furthermore, not all combinations of parameters are meaningful for a given generalized function. For example, while tcontains(geometry, tpoint) is meaningful, tcontains(tpoint, geometry) is meaningful only when the geometry is a single point, and tcontains(tpoint, tpoint) is equivalent to tintersects(tpoint, geometry). For this reason, only the first combination of parameters is defined for contains and tcontains.

Finally, it is worth noting that the temporal relationships allow to mix 2D/3D geometries but in that case, the computation is only performed on 2D.

Possible Relationships

  • May contain

    contains({geo,tgeompoint},{geo,tgeompoint}): boolean

    SELECT contains(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(1 1)@2012-01-03)');
    -- true
    
  • May be disjoint

    disjoint({geo,tgeompoint},{geo,tgeompoint}): boolean

    SELECT disjoint(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(1 1)@2012-01-03)');
    -- false
    
  • May be at distance within

    dwithin({geo,tpoint},{geo,tpoint},float): boolean

    SELECT dwithin(geometry 'Polygon((0 0 0,0 1 1,1 1 1,1 0 0,0 0 0))',
      tgeompoint 'Point(0 2 1)@2000-01-01,Point(2 2 1)@2000-01-02', 1)
    -- true
    SELECT dwithin(geometry 'Polygon((0 0 0,0 1 1,1 1 1,1 0 0,0 0 0))',
      tgeompoint 'Point(0 2 2)@2000-01-01,Point(2 2 2)@2000-01-02', 1)
    -- false
    
  • May intersect

    intersects({geo,tpoint},{geo,tpoint}): boolean

    SELECT intersects(geometry 'Polygon((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))',
      tgeompoint '[Point(0 0 1)@2012-01-01, Point(1 1 1)@2012-01-03)');
    -- false
    SELECT intersects(geometry 'Polygon((0 0 0,0 1 1,1 1 1,1 0 0,0 0 0))',
      tgeompoint '[Point(0 0 1)@2012-01-01, Point(1 1 1)@2012-01-03)');
    -- true
    
  • May touch

    touches({geo,tgeompoint},{geo,tgeompoint}): boolean

    SELECT touches(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(0 1)@2012-01-03)');
    -- true
    

Temporal Relationships

  • Temporal contains

    tcontains({geo,tgeompoint},{geo,tgeompoint}): tbool

    SELECT tcontains(geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 3)@2012-01-04)');
    -- "{[f@2012-01-01, f@2012-01-02], (t@2012-01-02, f@2012-01-03, f@2012-01-04)}"
    
  • Temporal disjoint

    tdisjoint({geo,tgeompoint},{geo,tgeompoint}): tbool

    SELECT tdisjoint(geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 3)@2012-01-04)');
    -- "{[t@2012-01-01, f@2012-01-02, f@2012-01-03], (t@2012-01-03, t@2012-01-04]}"
    SELECT tdisjoint(tgeompoint '[Point(0 3)@2012-01-01, Point(3 0)@2012-01-05)',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 3)@2012-01-05)');
    -- "{[t@2012-01-01, f@2012-01-03], (t@2012-01-03, t@2012-01-05)}"
    
  • Temporal distance within

    tdwithin({geo,tpoint},{geo,tpoint},float): tbool

    SELECT tdwithin(geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 0)@2012-01-04)', 1);
    -- "{[f@2012-01-01, t@2012-01-02, t@2012-01-03], (f@2012-01-03, f@2012-01-04)}"
    SELECT tdwithin(tgeompoint '[Point(1 0)@2000-01-01, Point(1 4)@2000-01-05]',
      tgeompoint 'Interp=Stepwise;[Point(1 2)@2000-01-01, Point(1 3)@2000-01-05]', 1);
    -- "{[f@2000-01-01, t@2000-01-02, t@2000-01-04], (f@2000-01-04, t@2000-01-05]}"
    
  • Temporal intersects

    tintersects({geo,tpoint},{geo,tpoint}): tbool

    SELECT tintersects(geometry 'MultiPoint(1 1,2 2)',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 3)@2012-01-04)');
    -- "{[f@2012-01-01, t@2012-01-02], (f@2012-01-02, t@2012-01-03],
      (f@2012-01-03, f@2012-01-04]}"
    SELECT tintersects(tgeompoint '[Point(0 3)@2012-01-01, Point(3 0)@2012-01-05)',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 3)@2012-01-05)');
    -- "{[f@2012-01-01, t@2012-01-03], (f@2012-01-03, f@2012-01-05)}"
    
  • Temporal touches

    ttouches({geo,tgeompoint},{geo,tgeompoint}): tbool

    SELECT ttouches(geometry 'Polygon((1 0,1 2,2 2,2 0,1 0))',
      tgeompoint '[Point(0 0)@2012-01-01, Point(3 0)@2012-01-04)');
    -- "{[f@2012-01-01, t@2012-01-02, t@2012-01-03], (f@2012-01-03, f@2012-01-04]}"