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.
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.
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
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)
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]
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
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
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]
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]"}
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
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]
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
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
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]