Temporal Point Cloud Points

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.

We give next the functions and operators for temporal point cloud points. Most functions and operators for temporal types described in the previous chapters can be applied for temporal point cloud points. Therefore, in the signatures of the functions, the notation base represents a pcpoint and the notations ttype and tpoint also represent a tpcpoint. To avoid redundancy, we only present next some examples of these functions and operators for temporal point cloud points.

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(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.

Input and Output

  • Return the text representation of a tpcpoint, or of an array of them, and cast a tpcpoint to text

    asText(tpcpoint) → text
    asText(tpcpoint[]) → text[]
    tpcpoint::text → text
    
    -- The pcpoint payload renders as hex-encoded WKB.
    SELECT asText(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz));
    -- 5C00000001000000640000006400000064000000000000@2001-01-01
    
  • Return the Moving Features JSON (MF-JSON) representation

    asMFJSON(tpcpoint,options int=0,flags int=0,maxdecimaldigits int=15) → text
    

    A tpcpoint is emitted as {"type":"MovingPCPoint", … "coordinates":[[X,Y,Z], …], "datetimes":[…]}, the X, Y and Z of each instant read from its pcpoint through the schema cache; a schema stating neither X nor Y leaves the coordinate array of that instant empty.

    SELECT asMFJSON(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz));
    /* {"type":"MovingPCPoint","coordinates":[[1,1,1]],
       "datetimes":["2001-01-01T00:00:00"],"interpolation":"None"} */
    

asText takes no maxdecimaldigits argument, a pcpoint printing as the hex-WKB of its serialized form, which has no decimal places to round, and there is no tpcpointFromText, pgPointCloud's pcpoint_in accepting hex-WKB only and the schema not being reconstructible from the text form. MF-JSON is output-only for the same reason, and carries a "bbox" key when options is 1, a TPCBox JSON object adding a "pcid" field next to the standard stbox-shaped "bbox" array. For a lossless round trip use asBinary / tpcpointFromBinary or asHexWKB / tpcpointFromHexWKB.

Constructors

  • Constructor for temporal point cloud points having a constant value

    tpcpoint(pcpoint,timestamptz) → tpcpointInst
    tpcpoint(pcpoint,tstzset) → tpcpointDiscSeq
    tpcpoint(pcpoint,tstzspan,interp text='step') → tpcpointContSeq
    tpcpoint(pcpoint,tstzspanset,interp text='step') → tpcpointSeqSet
    
    SELECT asText(tpcpoint(pcpoint(1, 1, 1, 1), timestamptz '2001-01-01'));
    -- 5C00000001000000640000006400000064000000000000@2001-01-01
    SELECT asText(tpcpoint(pcpoint(1, 1, 1, 1), tstzspan '[2001-01-01, 2001-01-02]'));
    -- [5C000000010000006400…000000@2001-01-01, 5C000000010000006400…000000@2001-01-02]
    
  • Constructor for temporal point cloud points of sequence subtype

    tpcpointSeq(tpcpointInst[],interp text='step',leftInc boolean=true,
      rightInc boolean=true) → tpcpointSeq
    

    The interpolation is 'discrete' or 'step'; the dimensions a pcpoint carries do not interpolate linearly, so 'linear' raises The temporal type cannot have linear interpolation.

    SELECT tpcpointSeq(ARRAY[tpcpoint(pcpoint(1, 1.0, 2.0, 3.0), '2024-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 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[]) → tpcpointSeqSet
    
    SELECT numSequences(tpcpointSeqSet(ARRAY[tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)])]));
    -- 1
    SELECT numInstants(tpcpointSeqSet(ARRAY[tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)])]));
    -- 2
    

Conversions

  • Convert a temporal point cloud point to a temporal geometry point

    tpcpoint::tgeompoint
    

    Every non-spatial dimension is projected away and the timestamps are preserved. The result carries the SRID the schema states, and is three-dimensional when the schema states a Z dimension. The reverse conversion is not provided, since rebuilding a pcpoint needs a target schema that the temporal value alone does not carry.

    SELECT ST_AsText(startValue(tpcpoint(pcpoint(1, 10.0, 20.0, 30.0),
      '2024-01-01'::timestamptz)::tgeompoint));
    -- POINT Z (10 20 30)
    

Accessors

  • Return the pgPointCloud schema id shared by all instants

    pcid(tpcpoint) → integer
    
    SELECT pcid(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz));
    -- 1
    
  • Return the SRID inherited from the schema

    SRID({tpcpoint,tpcpatch}) → integer
    
    -- The SRID is that of the schema registered for the pcid.
    SELECT SRID(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz));
    -- 0
    SELECT SRID(tpcpatch(pcpatch(pcpoint(1, 1, 1, 1)), '2001-01-01'::timestamptz));
    -- 0
    
  • Project a tpcpoint onto a spatial dimension, yielding a tfloat

    getX(tpcpoint) → tfloat
    getY(tpcpoint) → tfloat
    getZ(tpcpoint) → tfloat
    
    SELECT startValue(getX(tpcpoint(pcpoint(1, 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
    
    SELECT getDim(tpcpointSeq(ARRAY[tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)]), 'X');
    -- Interp=Step;[1@2001-01-01, 2@2001-01-02]
    

Transformations

  • Transform a tpcpoint to another subtype

    tpcpointInst(tpcpoint) → tpcpoint
    tpcpointSeq(tpcpoint,interp text='step') → tpcpoint
    tpcpointSeqSet(tpcpoint) → tpcpoint
    
    SELECT numInstants(tpcpointInst(tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz)));
    -- 1
    SELECT numInstants(tpcpointSeq(tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)])));
    -- 2
    
  • Transform a tpcpoint to another interpolation

    setInterp(tpcpoint,interp) → tpcpoint
    
    -- A tpcpoint carries step interpolation.
    SELECT interp(tpcpointSeq(ARRAY[tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)]));
    -- Step
    SELECT interp(setInterp(tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)], 'discrete'), 'step'));
    -- Step
    

Modifications

  • Insert a tpcpoint into another one, or update another one with it

    insert(tpcpoint,tpcpoint,connect boolean=true) → tpcpoint
    update(tpcpoint,tpcpoint,connect boolean=true) → tpcpoint
    
    SELECT numInstants(insert(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)]),
      tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)])));
    -- 3
    
  • Delete a time selector (timestamp, set, period, or spanset) from a tpcpoint

    deleteTime(tpcpoint,time,connect boolean=true) → tpcpoint
    
    -- Deleting the middle instant splits the sequence into {[2001-01-01, 2001-01-02),
    -- (2001-01-02, 2001-01-03]}; each half stores its bound at the deleted timestamp, giving
    -- four instants.
    SELECT numInstants(deleteTime(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), timestamptz '2001-01-02'));
    -- 4
    
  • Append an instant or a sequence to a tpcpoint

    appendInstant(tpcpoint,tpcpoint) → tpcpoint
    appendSequence(tpcpoint,tpcpoint) → tpcpoint
    
    SELECT numInstants(appendInstant(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz)]),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)));
    -- 3
    

Restrictions

  • Restrict a tpcpoint to (the complement of) a pcpoint value or a set of pcpoint values

    atValue(tpcpoint,pcpoint) → tpcpoint
    minusValue(tpcpoint,pcpoint) → tpcpoint
    atValues(tpcpoint,pcpointset) → tpcpoint
    minusValues(tpcpoint,pcpointset) → tpcpoint
    
    -- With step interpolation the matching value is held on [2001-01-01, 2001-01-02); its
    -- closing bound is stored as a second instant.
    SELECT numInstants(atValue(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), pcpoint(1, 1, 1, 1)));
    -- 2
    SELECT numInstants(minusValue(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), pcpoint(1, 1, 1, 1)));
    -- 2
    
  • Restrict a tpcpoint to a time selector (timestamp, period, set, or spanset), or remove it

    atTime(tpcpoint,time) → tpcpoint
    minusTime(tpcpoint,time) → tpcpoint
    
    SELECT numInstants(atTime(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), timestamptz '2001-01-02'));
    -- 1
    SELECT numInstants(atTime(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]),
      tstzspan '[2001-01-01, 2001-01-02]'));
    -- 2
    
  • Restrict a tpcpoint to the spatial / temporal extent of a tpcbox, or remove it

    atTpcbox(tpcpoint,tpcbox,border_inc boolean=true) → tpcpoint
    minusTpcbox(tpcpoint,tpcbox,border_inc boolean=true) → tpcpoint
    

    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

    SELECT numInstants(atTpcbox(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]),
      tpcboxZT(0, 0, 0, 2, 2, 2, tstzspan '[2001-01-01, 2001-01-03]', 1)));
    -- 2
    -- The box does not intersect the tpcpoint, so nothing is removed.
    SELECT numInstants(minusTpcbox(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]),
      tpcboxZT(10, 10, 10, 12, 12, 12, tstzspan '[2001-01-01, 2001-01-03]', 1)));
    -- 3
    
  • Restrict a tpcpoint to the instants before or after a timestamp

    beforeTimestamp(tpcpoint,timestamptz,strict boolean=true) → tpcpoint
    afterTimestamp(tpcpoint,timestamptz,strict boolean=true) → tpcpoint
    

    The strict flag excludes the instant at the timestamp itself

    SELECT timeSpan(beforeTimestamp(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), timestamptz '2001-01-02'));
    -- [2001-01-01, 2001-01-02)
    SELECT timeSpan(afterTimestamp(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), timestamptz '2001-01-02'));
    -- (2001-01-02, 2001-01-03]
    

Splitting Operations

  • Return the distinct values of a tpcpoint with the span set on which each of them is taken

    unnest(tpcpoint) → {(value,time)}
    
    SELECT (un).time FROM (SELECT unnest(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2024-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2024-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 1, 1, 1), '2024-01-03'::timestamptz)])) AS un) t;
    -- {[2024-01-01, 2024-01-02), [2024-01-03, 2024-01-03]}
    -- {[2024-01-02, 2024-01-03)}
    
  • Split a tpcpoint into fragments, one per time bin

    timeSplit(tpcpoint,duration interval,
      origin timestamptz='2000-01-03') → {(time,tpcpoint)}
    
    SELECT (ts).time, numInstants((ts).temp) FROM (SELECT timeSplit(tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2024-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2024-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2024-01-03'::timestamptz)]),
      interval '1 day', '2024-01-01'::timestamptz) AS ts) t;
    -- 2024-01-01 | 2
    -- 2024-01-02 | 2
    -- 2024-01-03 | 1
    
  • Return the array of time spans of a tpcpoint's segments

    spans(tpcpoint) → tstzspan[]
    
    SELECT spans(tpcpointSeq(ARRAY[tpcpoint(pcpoint(1, 1, 1, 1), '2024-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2024-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2024-01-03'::timestamptz)]));
    -- {"[2024-01-01, 2024-01-02]","[2024-01-02, 2024-01-03]"}
    
  • Return the time spans of a tpcpoint split into a given number of bins, or with a given number of segments per bin

    splitNSpans(tpcpoint,integer) → tstzspan[]
    splitEachNSpans(tpcpoint,integer) → tstzspan[]
    
    SELECT splitNSpans(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2024-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2024-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2024-01-03'::timestamptz)]), 2);
    -- {"[2024-01-01, 2024-01-02]","[2024-01-02, 2024-01-03]"}
    

Bounding Box Operations

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

  • Topological operators

    {tstzspan,tpcbox,tpcpoint} {&&, @>, <@, ~=, -|-} {tstzspan,tpcbox,tpcpoint} → boolean
    
    SELECT tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]) &&
      tstzspan '[2001-01-02, 2001-01-04]';
    -- true
    SELECT tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]) @>
      tpcboxZ(1, 1, 1, 2, 2, 2, 1);
    -- true
    
  • Position operators

    {tpcbox,tpcpoint} {<<, >>, <<|, |>>, <</, />>} {tpcbox,tpcpoint} → boolean
    {tstzspan,tpcbox,tpcpoint} {<<#, #>>} {tstzspan,tpcbox,tpcpoint} → boolean
    
    SELECT tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]) <<
      tpcboxZ(10, 10, 10, 12, 12, 12, 1);
    -- true
    SELECT tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]) <<#
      tstzspan '[2001-01-05, 2001-01-06]';
    -- true
    

Distance Operations

  • Return the smallest distance ever

    nearestApproachDistance(tpcpoint,{tpcbox,tpcpoint}) → float
    

    Two values whose schemas differ are not comparable, so a pcid mismatch raises Operation on pcpoint values with different schemas, naming both, rather than answering.

    SELECT round(nearestApproachDistance( tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 10, 10, 10), '2001-01-01'::timestamptz))::numeric, 4);
    -- 15.5885
    -- A tpcbox without a time span measures the spatial approach only.
    SELECT round(nearestApproachDistance(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]),
      tpcboxZ(10, 10, 10, 12, 12, 12, 1))::numeric, 4);
    -- 12.1244
    SELECT round((tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz) |=|
      tpcpoint(pcpoint(1, 10, 10, 10), '2001-01-01'::timestamptz))::numeric, 4);
    -- 15.5885
    
  • Return the instant of the tpcpoint at which the two arguments are at the nearest distance

    nearestApproachInstant({geometry,tpcpoint},{geometry,tpcpoint}) → tpcpoint
    
    SELECT asText(nearestApproachInstant(tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 4, 4, 4), '2001-01-02'::timestamptz)]), geometry 'Point Z(5 5 5)'));
    -- 5C00000001000000900100009001000090010000000000@2001-01-02
    
  • Return the line connecting the nearest approach point between the two arguments

    shortestLine({geometry,tpcpoint},{geometry,tpcpoint}) → geometry
    
    SELECT ST_AsText(shortestLine(tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 4, 4, 4), '2001-01-02'::timestamptz)]), geometry 'Point Z(5 5 5)'));
    -- LINESTRING Z (4 4 4,5 5 5)
    
  • Return the temporal distance

    {geometry,tpcpoint} <-> {geometry,tpcpoint} → tfloat
    
    SELECT round(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 4, 4, 4), '2001-01-02'::timestamptz)]) <->
      geometry 'Point Z(5 5 5)', 4);
    -- [6.9282@2001-01-01, 1.7321@2001-01-02]
    

Ever and Always Relationships

A tpcpoint is projected to a tgeompoint through the schema cache and the relationship is answered there, so a tpcpoint declares the relationships its cast target declares.

  • Ever and always relationships

    eContains(geometry,tpcpoint) → boolean
    aContains(geometry,tpcpoint) → boolean
    eCovers(geometry,tpcpoint) → boolean
    aCovers(geometry,tpcpoint) → boolean
    eDisjoint({geometry,tpcpoint},{geometry,tpcpoint}) → boolean
    aDisjoint({geometry,tpcpoint},{geometry,tpcpoint}) → boolean
    eDwithin({geometry,tpcpoint},{geometry,tpcpoint},dist float) → boolean
    aDwithin({geometry,tpcpoint},{geometry,tpcpoint},dist float) → boolean
    eIntersects({geometry,tpcpoint},{geometry,tpcpoint}) → boolean
    aIntersects({geometry,tpcpoint},{geometry,tpcpoint}) → boolean
    eTouches(geometry,tpcpoint) → boolean
    aTouches(geometry,tpcpoint) → boolean
    eTouches(tpcpoint,geometry) → boolean
    aTouches(tpcpoint,geometry) → boolean
    

    A moving point neither contains nor covers a geometry and two moving points do not touch, so eContains, eCovers and their always twins take the geometry first only, and eTouches and aTouches read either order but not two points. They are planar relationships, so a point whose schema states a Z dimension meets the refusal The tgeompoint cannot have Z dimension.

    SELECT eContains(geometry 'Polygon((0 0,0 4,4 4,4 0,0 0))',
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz));
    -- ERROR:  The tgeompoint cannot have Z dimension
    SELECT eIntersects(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), geometry 'POINT Z (1 1 1)');
    -- t
    SELECT aIntersects(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), geometry 'POINT Z (1 1 1)');
    -- f
    SELECT eIntersects(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]),
      tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]));
    -- t
    SELECT eDisjoint(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), geometry 'POINT Z (1 1 1)');
    -- t
    SELECT aDisjoint(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), geometry 'POINT Z (1 1 1)');
    -- f
    SELECT eDwithin(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), geometry 'POINT Z (5 5 5)',
      4);
    -- t
    SELECT aDwithin(tpcpointSeq(ARRAY[ tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz), tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]), geometry 'POINT Z (5 5 5)',
      4);
    -- f
    

Spatiotemporal Relationships

The spatiotemporal relationships compute the topological or distance relationship at each instant and result in a tbool. They read the same tgeompoint projection the ever/always relationships read, and are wired in the same three argument orders. A tpcpoint carries the Z its schema declares, if any: tContains, tCovers and tTouches are planar relationships, so a schema whose dimensions do not include Z answers them and one carrying Z is refused. That projection carries the interpolation of its source, so a tpcpoint sequence is answered along its trajectory rather than at its instants alone.

  • Temporal spatial relationships

    tDisjoint({geometry,tpcpoint},{geometry,tpcpoint}) → tbool
    tDwithin({geometry,tpcpoint},{geometry,tpcpoint},float) → tbool
    tIntersects({geometry,tpcpoint},{geometry,tpcpoint}) → tbool
    tContains(geometry,tpcpoint) → tbool
    tCovers(geometry,tpcpoint) → tbool
    tTouches(geometry,tpcpoint) → tbool
    tTouches(tpcpoint,geometry) → tbool
    

    A temporal point cloud point declares the relationships its cast target declares, so tContains and tCovers take the geometry first only and tTouches has no direction between two point cloud points. The three are planar relationships: a schema whose dimensions do not include Z answers them, and one carrying Z meets the refusal The tgeompoint cannot have Z dimension.

    SELECT tIntersects(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      geometry 'Polygon((0 0,0 2,2 2,2 0,0 0))');
    -- t@2001-01-01
    SELECT tDisjoint(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      geometry 'Polygon((0 0,0 2,2 2,2 0,0 0))');
    -- f@2001-01-01
    SELECT tDisjoint(tpcpoint(pcpoint(1, 9, 9, 9), '2001-01-02'::timestamptz),
      geometry 'Polygon((0 0,0 2,2 2,2 0,0 0))');
    -- t@2001-01-02
    SELECT tDisjoint(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 9, 9, 9), '2001-01-01'::timestamptz));
    -- t@2001-01-01
    SELECT tDwithin(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      geometry 'Point(1 2)', 2.0);
    -- t@2001-01-01
    SELECT tDwithin(tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      geometry 'Point(1 5)', 2.0);
    -- f@2001-01-01
    

Comparisons

  • Traditional comparisons

    tpcpoint {=, <>, <, <=, >, >=} tpcpoint → boolean
    

    The order is lexicographic over the canonical encodings of the two values, not geometric.

    SELECT tpcpoint(pcpoint(1, 1, 1, 1),
      '2001-01-01'::timestamptz) = tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz);
    -- t
    SELECT tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz) <> tpcpoint(pcpoint(1, 2,
      2, 2), '2001-01-02'::timestamptz);
    -- t
    SELECT tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz) < tpcpoint(pcpoint(1, 2,
      2, 2), '2001-01-02'::timestamptz);
    -- t
    
  • Ever and always comparisons

    {pcpoint,tpcpoint} {?=, %=, ?<>, %<>} {pcpoint,tpcpoint} → boolean
    
    SELECT pcpoint(1, 1, 1, 1) ?= tpcpointSeq(ARRAY[
      tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]);
    -- t
    SELECT tpcpointSeq(ARRAY[tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]) %= pcpoint(1, 1, 1, 1);
    -- f
    
  • Temporal comparisons

    {pcpoint,tpcpoint} {#=, #<>} {pcpoint,tpcpoint} → tbool
    
    SELECT tpcpointSeq(ARRAY[tpcpoint(pcpoint(1, 1, 1, 1), '2001-01-01'::timestamptz),
      tpcpoint(pcpoint(1, 2, 2, 2), '2001-01-02'::timestamptz),
      tpcpoint(pcpoint(1, 3, 3, 3), '2001-01-03'::timestamptz)]) #= pcpoint(1, 1, 1, 1);
    -- [t@2001-01-01, f@2001-01-02, f@2001-01-03]