Temporal Type tpcpoint

A tpcpoint is the lifting of pcpoint through MobilityDB's temporal machinery. It supports the same three subtypes as the other temporal types — instant, sequence (with discrete or step interpolation), and sequence set. All instants in a single tpcpoint value must share the same pcid; the constructor enforces this.

The bounding box of a tpcpoint is a tpcbox, computed at construction time from the X/Y/Z dimensions of the underlying pcpoint values together with the timestamps of the instants.

A column or domain may pin the schema by adding the pcid as a single-integer typmod, exactly like PostGIS' geometry(Point, SRID). Mixing schemas in such a column is rejected at INSERT or cast time. The same construct applies to tpcpatch.

CREATE TABLE scans (id int, traj tpcpoint(1), full_scan tpcpatch(1));
-- accepts pcid 1
INSERT INTO scans VALUES (1,
  tpcpoint(pcpoint(1, 1.0, 2.0, 3.0), '2024-01-01'::timestamptz),
  tpcpatch(pcpatch(1, pcpoint(1, 1, 1, 1), pcpoint(1, 2, 2, 2)),
           '2024-01-01'::timestamptz));
-- rejects any other pcid:
-- ERROR: Pcid of tpcpoint value (2) does not match column typmod pcid (1)

Omitting the typmod (tpcpoint with no parenthesised pcid) leaves the column schema-agnostic. The runtime check in the extent aggregate still rejects mid-query mixed-pcid input even on unconstrained columns.

Constructors

  • Construct a temporal pcpoint of instant subtype

    tpcpoint(pcpoint,timestamptz) → tpcpoint

    SELECT tpcpoint(PC_MakePoint(1, ARRAY[10.0, 20.0, 30.0]), '2024-01-01 12:00+00');
    
  • Construct a temporal pcpoint of sequence subtype from an array of instants. The interpolation is one of 'discrete', 'step'; 'step' is the default for tpcpoint since pcpoints carry heterogeneous dimensions that do not interpolate linearly

    tpcpointSeq(tpcpoint[]) → tpcpoint

    tpcpointSeq(tpcpoint[],text) → tpcpoint

    SELECT tpcpointSeq(ARRAY[tpcpoint(PC_MakePoint(1, ARRAY[1.0, 2.0, 3.0]), '2024-01-01'::timestamptz),
      tpcpoint(PC_MakePoint(1, ARRAY[4.0, 5.0, 6.0]), '2024-01-02'::timestamptz)], 'step');
    
  • Construct a temporal pcpoint of sequence-set subtype from an array of sequences

    tpcpointSeqSet(tpcpoint[]) → tpcpoint

Accessors

All generic temporal accessors apply (see Chapter 4, Temporal Types (Part 1)): numInstants, startInstant, endInstant, instantN, instants, startValue, endValue, getValues, numTimestamps, startTimestamp, endTimestamp, getTime, duration, memSize, interp. In addition:

  • Return the pgPointCloud schema id shared by all instants

    pcid(tpcpoint) → integer

  • Return the SRID inherited from the schema

    SRID(tpcpoint) → integer

Per-Dimension Projections

  • Project a tpcpoint onto a spatial dimension, yielding a tfloat

    getX(tpcpoint) → tfloat

    getY(tpcpoint) → tfloat

    getZ(tpcpoint) → tfloat

    SELECT startValue(getX(tpcpoint(PC_MakePoint(1, ARRAY[10.0, 20.0, 30.0]),
      '2024-01-01'::timestamptz)));
    -- 10
    
  • Project a tpcpoint onto any named schema dimension, yielding a tfloat

    getDim(tpcpoint,text) → tfloat

Conversions

  • Cast a tpcpoint to a temporal geometry point, projecting away every non-spatial dimension while preserving timestamps. The result has the same SRID as the schema; its dimensionality (2D vs. 3D) follows the presence of Z in the schema. A reverse cast is not provided: reconstructing a pcpoint requires a target schema that the temporal value alone cannot supply

    tgeompoint::tpcpoint is not defined

    tpcpoint::tgeompoint

    SELECT ST_AsText(startValue(tpcpoint(PC_MakePoint(1, ARRAY[10.0, 20.0, 30.0]),
      '2024-01-01'::timestamptz)::tgeompoint));
    -- POINT Z (10 20 30)
    
  • Convert a temporal point cloud point to the Arrow C Data Interface and back, returning the reconstructed value

    arrowRoundtrip(tpcpoint) → tpcpoint

    SELECT arrowRoundtrip(tpcpoint(PC_MakePoint(1, ARRAY[1.0, 1.0, 1.0]),
      '2024-01-01'::timestamptz)) = tpcpoint(PC_MakePoint(1, ARRAY[1.0, 1.0, 1.0]),
      '2024-01-01'::timestamptz);
    -- t
    

Comparisons

  • Compare two tpcpoints lexicographically over their canonical encodings

    tpcpoint = tpcpoint → boolean

    tpcpoint <> tpcpoint → boolean

    tpcpoint < tpcpoint → boolean

    tpcpoint <= tpcpoint → boolean

    tpcpoint > tpcpoint → boolean

    tpcpoint >= tpcpoint → boolean

  • Test whether the value at any (ever) or every (always) instant equals a given pcpoint

    tpcpoint ?= pcpoint → boolean

    tpcpoint %= pcpoint → boolean

Restrictions

  • Restrict a tpcpoint to a time selector (timestamp, period, set, or spanset), or remove it

    atTime(tpcpoint,timestamptz) → tpcpoint

    atTime(tpcpoint,tstzspan) → tpcpoint

    atTime(tpcpoint,tstzset) → tpcpoint

    atTime(tpcpoint,tstzspanset) → tpcpoint

    minusTime(tpcpoint,timestamptz) → tpcpoint

    minusTime(tpcpoint,tstzspan) → tpcpoint

    minusTime(tpcpoint,tstzset) → tpcpoint

    minusTime(tpcpoint,tstzspanset) → tpcpoint

  • Restrict a tpcpoint to the spatial / temporal extent of a tpcbox, or remove it. Returns NULL when the tpcbox's pcid does not match the tpcpoint's. Internally projects to a tgeompoint via the schema cache, restricts the projection by the equivalent stbox, and lifts the result's time span back onto the original tpcpoint to preserve the full pcpoint values

    atTpcbox(tpcpoint,tpcbox,border_inc bool=TRUE) → tpcpoint

    minusTpcbox(tpcpoint,tpcbox,border_inc bool=TRUE) → tpcpoint

Bounding-box operators

The bbox operators evaluate against the value's tpcbox; see the section called “Topological Operators” and the section called “Position Operators” for the per-operator geometry. Each operator below is wired against tpcbox, tstzspan, and tpcpoint itself.

  • Topological predicates: && overlaps, @> contains, <@ contained by, ~= same, -|- adjacent.

  • Strict directional predicates on the X axis (<<, >>), Y axis (<<|, |>>), Z axis (<</, />>), and time axis (<<#, #>>), plus their "overlaps-or-X" variants &<, &>, &<|, |&>, &</, /&>, &<#, #&>.

  • Nearest-approach distance, KNN-orderable through the GiST opclass: SELECT … ORDER BY temp |=| query LIMIT N is index-accelerated. Pcid mismatch yields infinity.

    nearestApproachDistance(tpcpoint,tpcbox) → float

    nearestApproachDistance(tpcpoint,tpcpoint) → float

B-tree ordering — what ORDER BY tpcpoint means

The tpcpoint_btree_ops opclass produces a total order over tpcpoint values, but the order is byte-wise on the underlying pcpoint serialisation, not geometric. The same caveats that apply to tpcpatch's B-tree apply here:

  • pcid is the primary discriminator. Points with smaller pcid sort before points with larger pcid, regardless of coordinates. Mixing pcids in a single column groups rows by schema first when ordering.

  • Within a single pcid, ordering follows the schema's on-disk dimension layout — typically X, Y, Z encoded as int32 (after applying the schema's per-dimension scale). Two points whose Euclidean distance is small can sort far apart if their X dimensions differ, since X is compared first.

  • Equality is exact-bytes equality. Two pcpoints with the same dimension values in the same schema are equal; the same coordinate set encoded in a schema with different scale or dimension order is not.

For spatial-meaningful ordering, project to a tgeompoint via the schema-aware cast and use PostGIS' KNN <-> on the resulting geometry, or use the GiST KNN operator |=| directly on the tpcpoint. For time-meaningful ordering, project to startTimestamp or timespan and order on that.

Spatial relationships

Evaluated by projecting the tpcpoint to a tgeompoint via the schema cache and delegating to the corresponding tgeompoint relation. Each function is wired in three argument orders: (geometry, tpcpoint), (tpcpoint, geometry), and (tpcpoint, tpcpoint). tpcpatch is intentionally out of scope — patch-level intersection would require per-point decompression and a different design.

  • Ever / always intersects.

    eIntersects(tpcpoint,geometry) → bool, aIntersects(tpcpoint,geometry) → bool

    eIntersects(tpcpoint,tpcpoint) → bool, aIntersects(tpcpoint,tpcpoint) → bool

  • Ever / always disjoint.

    eDisjoint(tpcpoint,geometry) → bool, aDisjoint(tpcpoint,geometry) → bool

    eDisjoint(tpcpoint,tpcpoint) → bool, aDisjoint(tpcpoint,tpcpoint) → bool

  • Ever / always within distance.

    eDwithin(tpcpoint,geometry,float) → bool, aDwithin(tpcpoint,geometry,float) → bool

    eDwithin(tpcpoint,tpcpoint,float) → bool, aDwithin(tpcpoint,tpcpoint,float) → bool