Las relaciones topológicas como ST_Intersects
y las relaciones de distancia como ST_DWithin
pueden ser generalizadas a los puntos temporales. Los argumentos de estas funciones generalizadas son un punto temporal y un tipo base (es decir, un geometry
o un geography
) o dos puntos temporales. Además, ambos argumentos deben ser del mismo tipo base, es decir, estas funciones no permiten merzclar un punto de geometría temporal (o una geometría) y un punto de geografía temporal (o una geografía).
Hay tres versiones de las relaciones espaciales:
Las relaciones alguna vez determinan determinan si la relación topológica o de distancia se satisface alguna vez (ver “Comparaciones alguna vez y siempre”) y resultan en un boolean
. Ejemplos son las funciones eIntersects
y eDwithin
.
Las relaciones siempre determinan determinan si la relación topológica o de distancia se satisface siempre (ver “Comparaciones alguna vez y siempre”) y resultan en un boolean
. Ejemplos son las funciones aIntersects
y aDwithin
.
Las relaciones temporales calculan la función topológica o de distancia en cada instante y dan como resultado un tbool
. Ejemplos son las funciones tIntersects
y tDwithin
.
Por ejemplo, la siguiente consulta
SELECT eIntersects(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', tgeompoint '[Point(0 2)@2001-01-01, Point(4 2)@2001-01-05)'); -- t
determina si el punto temporal se cruza alguna vez con la geometría. En este caso, la consulta es equivalente a la siguiente
SELECT ST_Intersects(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', geometry 'Linestring(0 2,4 2)');
donde la segunda geometría se obtiene aplicando la función trajectory
al punto temporal. Por otro lado, la consulta
SELECT tIntersects(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', tgeompoint '[Point(0 2)@2001-01-01, Point(4 2)@2001-01-05)'); -- {[f@2001-01-01, t@2001-01-02, t@2001-01-04], (f@2001-01-04, f@2001-01-05)}
calcula en cada instante si el punto temporal se cruza con la geometría. Del mismo modo, la siguiente consulta
SELECT eDwithin(tgeompoint '[Point(3 1)@2001-01-01, Point(5 1)@2001-01-03)', tgeompoint '[Point(3 1)@2001-01-01, Point(1 1)@2001-01-03)', 2); -- t
determina si la distancia entre los puntos temporales es alguna vez menor o igual a 2, mientras que la siguiente consulta
SELECT tDwithin(tgeompoint '[Point(3 1)@2001-01-01, Point(5 1)@2001-01-03)', tgeompoint '[Point(3 1)@2001-01-01, Point(1 1)@2001-01-03)', 2); -- {[t@2001-01-01, t@2001-01-02], (f@2001-01-02, f@2001-01-03)}
calcula en cada instante si la distancia entre los puntos temporales es menor o igual a 2.
Las relaciones alguna vez o siempre se utilizan normalmente en combinación con un índice espacio-temporal al calcular las relaciones temporales. Por ejemplo, la siguiente consulta
SELECT T.TripId, R.RegionId, tIntersects(T.Trip, R.Geom) FROM Trips T, Regions R WHERE eIntersects(T.Trip, R.Geom)
que verifica si un viaje T
(que es un punto temporal) se cruza con una región R
(que es una geometría) beneficiará de un índice espacio-temporal en la columna T.Trip
dado que la función intersects
realiza automáticamente la comparación del cuadro delimitador T.Trip && R.Geom
. Esto se explica más adelante en este documento.
No todas las relaciones espaciales disponibles en PostGIS tienen una generalización significativa para los puntos temporales. Se define una versión generalizada de las siguientes relaciones para los puntos geométricos temporales: eIntersects
, eDisjoint
, eDwithin
, eContains
, y eTouches
, mientras que para los puntos geográficos temporales solo se definen las tres primeras. Además, no todas las combinaciones de parámetros son significativas para una función generalizada dada. Por ejemplo, mientras que tContains(geometry,tpoint)
es significativo, tContains(tpoint,geometry)
es significativo solo cuando la geometría es un solo punto, y tContains(tpoint,tpoint)
es equivalente a tIntersects(tpoint, geometry)
. Por esta razón, solo se define la primera combinación de parámetros para eContains
, aContains
y tContains
.
Finalmente, cabe destacar que las relaciónes temporales permiten mezclar geometrías 2D/3D pero en ese caso, el cálculo sólo se realiza en 2D.
Presentamos a continuación las relaciones espaciales alguna vez o siempre. Estas relaciones incluyen automáticamente una comparación de cuadro delimitador que hace uso de cualquier índice espacial que esté disponible en los argumentos.
Contiene alguna vez
eContains(geo,tgeompoint) → boolean
aContains(geo,tgeompoint) → boolean
Esta función devuelve verdadero si el punto temporal está alguna vez en el interior de la geometría. Recuerde que una geometría no contiene cosas en su borde y, por lo tanto, los polígonos y las líneas no contienen líneas y puntos que se encuentran en su borde. Consulte la documentación de la función ST_Contains en PostGIS.
SELECT eContains(geometry 'Linestring(1 1,3 3)', tgeompoint '[Point(4 2)@2001-01-01, Point(2 4)@2001-01-02]'); -- false SELECT eContains(geometry 'Linestring(1 1,3 3,1 1)', tgeompoint '[Point(4 2)@2001-01-01, Point(2 4)@2001-01-03]'); -- true SELECT eContains(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', tgeompoint '[Point(0 1)@2001-01-01, Point(4 1)@2001-01-02]'); -- false SELECT eContains(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', tgeompoint '[Point(1 4)@2001-01-01, Point(4 1)@2001-01-04]'); -- true
Está disjunto alguna vez
eDisjoint({geo,tgeompoint},{geo,tgeompoint}) → boolean
aDisjoint({geo,tpoint},{geo,tpoint}) → boolean
SELECT eDisjoint(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))', tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-03)'); -- false SELECT eDisjoint(geometry 'Polygon((0 0 0,0 1 1,1 1 1,1 0 0,0 0 0))', tgeompoint '[Point(0 0 1)@2001-01-01, Point(1 1 0)@2001-01-03)'); -- true
Está alguna vez a distancia de
eDwithin({geo,tpoint},{geo,tpoint},float) → boolean
aDwithin({geo,tgeompoint},{geo,tgeompoint},float) → boolean
SELECT eDwithin(geometry 'Point(1 1 1)', tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 0)@2001-01-02]', 1); -- true SELECT eDwithin(geometry 'Polygon((0 0 0,0 1 1,1 1 1,1 0 0,0 0 0))', tgeompoint '[Point(0 2 2)@2001-01-01,Point(2 2 2)@2001-01-02]', 1); -- false
Intersecta alguna vez
eIntersects({geo,tpoint},{geo,tpoint}) → boolean
aIntersects({geo,tgeompoint},{geo,tgeompoint}) → boolean
SELECT eIntersects(geometry 'Polygon((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))', tgeompoint '[Point(0 0 1)@2001-01-01, Point(1 1 1)@2001-01-03)'); -- false SELECT eIntersects(geometry 'Polygon((0 0 0,0 1 1,1 1 1,1 0 0,0 0 0))', tgeompoint '[Point(0 0 1)@2001-01-01, Point(1 1 1)@2001-01-03)'); -- true
Toca alguna vez
eTouches({geo,tgeompoint},{geo,tgeompoint}) → boolean
aTouches({geo,tgeompoint},{geo,tgeompoint}) → boolean
SELECT eTouches(geometry 'Polygon((0 0,0 1,1 1,1 0,0 0))', tgeompoint '[Point(0 0)@2001-01-01, Point(0 1)@2001-01-03)'); -- true
Presentamos a continuación las relaciones espaciales temporales. Un requisito común con respecto ellas es restringir el resultado de la relación a los instantes en que el valor del resultado es verdadero o falso. Por ejemplo, la siguiente consulta calcula para cada viaje el tiempo dedicado viajando en el municipio de Bruselas.
SELECT TripId, duration(atValue(tIntersects(T.trip, M.geom), True)) FROM Trips T, Municipality M WHERE M.Name = "Brussels" AND atValue(tIntersects(T.trip, M.geom), True) IS NOT NULL;
Para simplificar la escritura de consultas, las relaciones espaciales temporales tienen un último parámetro opcional, que si se proporciona aplica la función atValue
(ver “Restricciones”) al resultado de la relación. De esta forma, la consulta anterior se puede escribir de la siguiente manera.
SELECT TripId, duration(tIntersects(T.trip, M.geom, True)) FROM Trips T, Municipality M WHERE M.Name = "Brussels" AND tIntersects(T.trip, M.geom, True) IS NOT NULL;
Contiene temporal
tContains(geometry,tgeompoint,atValue boolean=NULL) → tbool
SELECT tContains(geometry 'Linestring(1 1,3 3)', tgeompoint '[Point(4 2)@2001-01-01, Point(2 4)@2001-01-02]'); -- {[f@2001-01-01, f@2001-01-02]} SELECT tContains(geometry 'Linestring(1 1,3 3,1 1)', tgeompoint '[Point(4 2)@2001-01-01, Point(2 4)@2001-01-03]'); -- {[f@2001-01-01, t@2001-01-02], (f@2001-01-02, f@2001-01-03]} SELECT tContains(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', tgeompoint '[Point(0 1)@2001-01-01, Point(4 1)@2001-01-02]'); -- {[f@2001-01-01, f@2001-01-02]} SELECT tContains(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))', tgeompoint '[Point(1 4)@2001-01-01, Point(4 1)@2001-01-04]'); -- {[f@2001-01-01, f@2001-01-02], (t@2001-01-02, f@2001-01-03, f@2001-01-04]}
Disjunto temporal
tDisjoint({geo,tpoint},{geo,tpoint},atValue boolean=NULL) → tbool
La función solo admite 3D o geografías para dos puntos temporales
SELECT tDisjoint(geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))', tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-04)'); -- {[t@2001-01-01, f@2001-01-02, f@2001-01-03], (t@2001-01-03, t@2001-01-04]} SELECT tDisjoint(tgeompoint '[Point(0 3)@2001-01-01, Point(3 0)@2001-01-05)', tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-05)'); -- {[t@2001-01-01, f@2001-01-03], (t@2001-01-03, t@2001-01-05)}
Está a distancia de temporal
tDwithin({geompoint,tgeompoint},{geompoint,tgeompoint},float,atValue boolean=NULL)
→ tbool
SELECT tDwithin(geometry 'Point(1 1)', tgeompoint '[Point(0 0)@2001-01-01, Point(2 2)@2001-01-03)', sqrt(2)); -- {[t@2001-01-01, t@2001-01-03)} SELECT tDwithin(tgeompoint '[Point(1 0)@2001-01-01, Point(1 4)@2001-01-05]', tgeompoint 'Interp=Step;[Point(1 2)@2001-01-01, Point(1 3)@2001-01-05]', 1); -- {[f@2001-01-01, t@2001-01-02, t@2001-01-04], (f@2001-01-04, t@2001-01-05]}
Intersección temporal
tIntersects({geo,tpoint},{geo,tpoint},atValue boolean=NULL) → tbool
La función solo admite 3D o geografías para dos puntos temporales
SELECT tIntersects(geometry 'MultiPoint(1 1,2 2)', tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-04)'); /* {[f@2001-01-01, t@2001-01-02], (f@2001-01-02, t@2001-01-03], (f@2001-01-03, f@2001-01-04]} */ SELECT tIntersects(tgeompoint '[Point(0 3)@2001-01-01, Point(3 0)@2001-01-05)', tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-05)'); -- {[f@2001-01-01, t@2001-01-03], (f@2001-01-03, f@2001-01-05)}
Toca temporal
tTouches({geo,tgeompoint},{geo,tgeompoint},atValue boolean=NULL) → tbool
SELECT tTouches(geometry 'Polygon((1 0,1 2,2 2,2 0,1 0))', tgeompoint '[Point(0 0)@2001-01-01, Point(3 0)@2001-01-04)'); -- {[f@2001-01-01, t@2001-01-02, t@2001-01-03], (f@2001-01-03, f@2001-01-04]}