Return the smallest distance ever
{geo,tgeo,stbox} |=| {geo,tgeo,stbox} → float
nearestApproachDistance({geography,tgeog,stbox},{geography,tgeog,stbox},
spheroid boolean=true) → float
For geographies, the operator computes on the WGS 84 spheroid, and the function nearestApproachDistance computes on the sphere, faster, if its last argument is false.
SELECT tgeompoint '[Point(0 0)@2001-01-02, Point(1 1)@2001-01-04, Point(0 0)@2001-01-06)' |=| geometry 'Linestring(2 2,2 1,3 1)'; -- 1 SELECT tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-03, Point(0 0)@2001-01-05)' |=| tgeompoint '[Point(2 0)@2001-01-02, Point(1 1)@2001-01-04, Point(2 2)@2001-01-06)'; -- 0.5 SELECT tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-05)' |=| tgeompoint '[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06)'; -- 0.5 SELECT tgeometry '(Point(1 1)@2001-01-01, Linestring(3 1,1 1)@2001-01-03]' |=| geometry 'Linestring(1 3,2 2,3 3)'; -- 1 SELECT round((tgeogpoint '[Point(0 1)@2001-01-01, Point(0 2)@2001-01-02]' |=| geography 'Point(0 0)')::numeric, 3); -- 110574.389 SELECT round(nearestApproachDistance( tgeogpoint '[Point(0 1)@2001-01-01, Point(0 2)@2001-01-02]', geography 'Point(0 0)', false)::numeric, 3); -- 111195.080
The operator |=| can be used for doing nearest neighbor searches using a GiST or an SP-GiST index (see the section called “Indexing”). This operator corresponds to the PostGIS function ST_DistanceCPA, altough the latter requires both arguments to be a trajectory.
When one argument is a spatiotemporal box carrying a period, the distance is measured from the part of the temporal value inside that period, and the result is NULL when no part of it is. A box carrying no period measures the whole temporal value.
SELECT ST_DistanceCPA(tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-05)'::geometry, tgeompoint '[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06)'::geometry); -- 0.5
Return the instant of the first temporal point at which the two arguments are at the nearest distance
nearestApproachInstant({geo,tgeo},{geo,tgeo}) → tgeo
nearestApproachInstant({geography,tgeog},{geography,tgeog},spheroid boolean=true) → tgeog
The function will only return the first instant that it finds if there are more than one. The resulting instant may be at an exclusive bound. For geographies, the closest points of each segment are located on the sphere and their distances are compared on the WGS 84 spheroid by default, as the PostGIS function ST_Distance measures a geography distance. If the last argument is false, they are compared on the sphere.
SELECT asText(nearestApproachInstant(tgeompoint '(Point(1 1)@2001-01-01,
Point(3 1)@2001-01-03]', geometry 'Linestring(1 3,2 2,3 3)'));
-- POINT(2 1)@2001-01-02
SELECT asText(nearestApproachInstant(tgeompoint 'Interp=Step;
(Point(1 1)@2001-01-01, Point(3 1)@2001-01-03]', geometry 'Linestring(1 3,2 2,3 3)'));
-- POINT(1 1)@2001-01-01
SELECT asText(nearestApproachInstant(tgeompoint '(Point(1 1)@2001-01-01,
Point(2 2)@2001-01-03]', tgeompoint '(Point(1 1)@2001-01-01, Point(4 1)@2001-01-03]'));
-- POINT(1 1)@2001-01-01
SELECT asText(nearestApproachInstant(tgeometry
'[Linestring(0 0 0,1 1 1)@2001-01-01, Point(0 0 0)@2001-01-03]', tgeometry
'[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06]'));
-- LINESTRING Z (0 0 0,1 1 1)@2001-01-02
SELECT asText(nearestApproachInstant(tgeogpoint '{Point(0 1)@2001-01-01,
Point(0.998 0)@2001-01-02}', geography 'Linestring(0 0,0 -0.5)'));
-- POINT(0 1)@2001-01-01
SELECT asText(nearestApproachInstant(tgeogpoint '{Point(0 1)@2001-01-01,
Point(0.998 0)@2001-01-02}', geography 'Linestring(0 0,0 -0.5)', false));
-- POINT(0.998 0)@2001-01-02
Function nearestApproachInstant generalizes the PostGIS function ST_ClosestPointOfApproach. First, the latter function requires both arguments to be trajectories. Second, function nearestApproachInstant returns both the point and the timestamp of the nearest point of approach while the PostGIS function only provides the timestamp as shown next.
SELECT to_timestamp(ST_ClosestPointOfApproach( tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-05)'::geometry, tgeompoint '[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06)'::geometry)); -- 2001-01-03 12:00:00
Return the minimum spatial distance between two sets of temporal geometries, ignoring time
minDistance(tgeo[],tgeo[]) → float minDistance(tgeog[],tgeog[],spheroid boolean=true) → float
The distance is measured between the trajectories with time discarded, equal to ST_Distance of the trajectory of each argument, and the result is the minimum over every pair drawn from the two sets. Two values that follow the same path at different times are therefore at distance zero. The time-synchronous quantity, which compares two arguments only at the instants they share, is nearestApproachDistance. A single pair is the one-element case. For geographies, the computation is done on the WGS 84 spheroid by default. If the last argument is false, a faster spherical calculation is used.
SELECT minDistance(ARRAY[tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-03)', tgeompoint '[Point(5 5)@2001-01-01, Point(6 6)@2001-01-03)'], ARRAY[tgeompoint '[Point(0 1)@2001-01-01, Point(1 0)@2001-01-03)']); -- 0 SELECT round(minDistance( ARRAY[tgeogpoint '[Point(0 1)@2001-01-01, Point(0 2)@2001-01-02]'], ARRAY[tgeogpoint 'Point(0 0)@2001-01-01'], false)::numeric, 3); -- 111195.080
Return the qualifying index pairs of two arrays of temporal geometries, generalising the scalar spatial relationships to a set-set spatial join
eDwithinPairs(tgeo[],tgeo[],float) → setof(i integer,j integer) aDwithinPairs(tgeo[],tgeo[],float) → setof(i integer,j integer) eIntersectsPairs(tgeo[],tgeo[]) → setof(i integer,j integer) aIntersectsPairs(tgeo[],tgeo[]) → setof(i integer,j integer) eDisjointPairs(tgeo[],tgeo[]) → setof(i integer,j integer) aDisjointPairs(tgeo[],tgeo[]) → setof(i integer,j integer) eTouchesPairs(tgeometry[],tgeometry[]) → setof(i integer,j integer) aTouchesPairs(tgeometry[],tgeometry[]) → setof(i integer,j integer) tDwithinPairs(tgeo[],tgeo[],float) → setof(i integer,j integer,periods tstzspanset) tIntersectsPairs(tgeo[],tgeo[]) → setof(i integer,j integer,periods tstzspanset) tDisjointPairs(tgeo[],tgeo[]) → setof(i integer,j integer,periods tstzspanset) tTouchesPairs(tgeometry[],tgeometry[]) → setof(i integer,j integer,periods tstzspanset) eDwithinPairs(tgeog[],tgeog[],float,spheroid boolean=true) → setof(i integer,j integer) aDwithinPairs(tgeog[],tgeog[],float,spheroid boolean=true) → setof(i integer,j integer)
Each function resolves the pruned cross product of the two input arrays inside a single call and returns the one-based indexes i and j of the qualifying pairs. The e-prefixed functions return the pairs for which the relationship ever holds, the a-prefixed functions the pairs for which it always holds, and the t-prefixed functions additionally return the periods during which it holds. Each input's spatiotemporal box is used as a bounding-box prefilter so that the exact relationship is computed only on the surviving candidate pairs, and pairs whose temporal extents do not overlap are excluded, matching the scalar relationships. The functions are defined for temporal points and temporal geometries in both the planar and geodetic cases, except the touches relationship, which is defined for planar geometries only. The indexes map back to the original identities through a parallel array_agg(identity ORDER BY ...). For geographies, the computation is done on the WGS 84 spheroid by default. If the last argument is false, a faster spherical calculation is used.
SELECT i, j FROM eDwithinPairs(
ARRAY[tgeompoint '[Point(0 0)@2001-01-01, Point(0 10)@2001-01-02]',
tgeompoint '[Point(50 50)@2001-01-01, Point(50 60)@2001-01-02]'],
ARRAY[tgeompoint '[Point(1 0)@2001-01-01, Point(1 10)@2001-01-02]'], 2.0);
-- 1 | 1
SELECT i, j, periods FROM tDwithinPairs(
ARRAY[tgeompoint '[Point(0 0)@2001-01-01, Point(0 10)@2001-01-02]'],
ARRAY[tgeompoint '[Point(1 0)@2001-01-01, Point(1 10)@2001-01-02]'], 2.0);
-- one pair, with the period during which it is within the distance
SELECT i, j FROM aDisjointPairs(
ARRAY[tgeompoint '[Point(0 0)@2001-01-01, Point(0 10)@2001-01-02]'],
ARRAY[tgeompoint '[Point(5 0)@2001-01-01, Point(5 10)@2001-01-02]']);
-- 1 | 1
Return the line connecting the nearest approach point
shortestLine({geo,tgeo},{geo,tgeo}) → geo
shortestLine({geography,tgeog},{geography,tgeog},spheroid boolean=true) → geography
The function will only return the first line that it finds if there are more than one. For geographies, the line joins the points at the nearest approach instant, which the WGS 84 spheroid decides by default and the sphere if the last argument is false.
SELECT ST_AsText(shortestLine(tgeompoint '(Point(1 1)@2001-01-01, Point(3 1)@2001-01-03]',
geometry 'Linestring(1 3,2 2,3 3)'));
-- LINESTRING(2 1,2 2)
SELECT ST_AsText(shortestLine(tgeompoint 'Interp=Step;
(Point(1 1)@2001-01-01, Point(3 1)@2001-01-03]', geometry 'Linestring(1 3,2 2,3 3)'));
-- LINESTRING(1 1,2 2)
SELECT ST_AsText(shortestLine(tgeometry
'[Linestring(0 0 0,1 1 1)@2001-01-01, Point(0 0 0)@2001-01-03]', tgeometry
'[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06]'));
-- LINESTRING Z (0 0 0,2 0 0)
SELECT ST_AsText(shortestLine(tgeogpoint '{Point(0 1)@2001-01-01,
Point(0.998 0)@2001-01-02}', geography 'Linestring(0 0,0 -0.5)'));
-- LINESTRING(0 1,0 0)
SELECT ST_AsText(shortestLine(tgeogpoint '{Point(0 1)@2001-01-01,
Point(0.998 0)@2001-01-02}', geography 'Linestring(0 0,0 -0.5)', false));
-- LINESTRING(0.998 0,0 0)
Function shortestLine can be used to obtain the result provided by the PostGIS function ST_CPAWithin when both arguments are trajectories as shown next.
SELECT ST_Length(shortestLine( tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-05)', tgeompoint '[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06)')) <= 0.5; -- true SELECT ST_CPAWithin(tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-05)'::geometry, tgeompoint '[Point(2 0 0)@2001-01-02, Point(1 1 1)@2001-01-04, Point(2 2 2)@2001-01-06)'::geometry, 0.5); -- true
The temporal distance operator, denoted <->, computes the distance at each instant of the intersection of the temporal extents of their arguments and results in a temporal float. Computing temporal distance is useful in many mobility applications. For example, a moving cluster (also known as convoy or flock) is defined as a set of objects that move close to each other for a long time interval. This requires to compute temporal distance between two moving objects.
The temporal distance operator accepts a geometry/geography restricted to a point or a temporal point as arguments. Notice that the temporal types only consider linear interpolation between values, while the distance is a root of a quadratic function. Therefore, the temporal distance operator gives a linear approximation of the actual distance value for temporal sequence points. In this case, the arguments are synchronized in the time dimension, and for each of the composing line segments of the arguments, the spatial distance between the start point, the end point, and the nearest point of approach is computed, as shown in the examples below.
Return the temporal distance
{geo,tgeo} <-> {geo,tgeo} → tfloat
tDistance({geography,tgeog},{geography,tgeog},spheroid boolean=true) → tfloat
For geographies, the operator computes on the WGS 84 spheroid, and the function tDistance computes on the sphere, faster, if its last argument is false.
SELECT tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-03)' <-> geometry 'Point(0 1)'; -- [1@2001-01-01, 0.707106781186548@2001-01-02, 1@2001-01-03) SELECT tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-03)' <-> tgeompoint '[Point(0 1)@2001-01-01, Point(1 0)@2001-01-03)'; -- [1@2001-01-01, 0@2001-01-02, 1@2001-01-03) SELECT tgeompoint '[Point(0 1)@2001-01-01, Point(0 0)@2001-01-03)' <-> tgeompoint '[Point(0 0)@2001-01-01, Point(1 0)@2001-01-03)'; -- [1@2001-01-01, 0.707106781186548@2001-01-02, 1@2001-01-03) SELECT tgeometry '[Point(0 0)@2001-01-01, Linestring(0 0,1 1)@2001-01-02]' <-> tgeometry '[Point(0 1)@2001-01-01, Point(1 0)@2001-01-02)'; -- Interp=Step;[1@2001-01-01, 1@2001-01-02] SELECT round(tgeogpoint '[Point(0 1)@2001-01-01, Point(0 2)@2001-01-02]' <-> geography 'Point(0 0)', 3); -- [110574.389@2001-01-01, 221149.453@2001-01-02] SELECT round(tDistance(tgeogpoint '[Point(0 1)@2001-01-01, Point(0 2)@2001-01-02]', geography 'Point(0 0)', false), 3); -- [111195.08@2001-01-01, 222390.159@2001-01-02]