# Tipos temporales geométricos (Parte 2)

## Restricciones

- Restringir a (al complemento de) una geometría, un lapso Z y/o un período &Z_support;

  `atGeometry(tgeom,geometry[,zspan]) → tgeom`

  `minusGeometry(tgeom,geometry[,zspan]) → tgeom`

  La geometría debe ser 2D y el cálculo con respecto a ella se realiza en 2D. El resultado conserva la dimensión Z del punto temporal, si existe.

      SELECT asText(atGeometry(tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-04)',
        geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))'));
      -- {"[POINT(1 1)@2001-01-02, POINT(2 2)@2001-01-03]"}
      SELECT astext(atGeometry(tgeompoint '[Point(0 0 0)@2001-01-01, Point(4 4 4)@2001-01-05]',
        geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))'));
      -- {[POINT Z (1 1 1)@2001-01-02, POINT Z (2 2 2)@2001-01-03]}
      SELECT asText(atGeometry(tgeompoint '[Point(1 1 1)@2001-01-01, Point(3 1 1)@2001-01-03,
        Point(3 1 3)@2001-01-05]', 'Polygon((2 0,2 2,2 4,4 0,2 0))', '[0,2]'));
      -- {[POINT Z (2 1 1)@2001-01-02, POINT Z (3 1 1)@2001-01-03, POINT Z (3 1 2)@2001-01-04]}
      SELECT asText(atGeometry(tgeometry 'Linestring(1 1,10 1)@2001-01-01',
        'Polygon((0 0,0 5,5 5,5 0,0 0))'));
      -- LINESTRING(1 1,5 1)@2001-01-01

      SELECT asText(minusGeometry(tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-04)',
        geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))'));
      /* {[POINT(0 0)@2001-01-01, POINT(1 1)@2001-01-02), (POINT(2 2)@2001-01-03,
         POINT(3 3)@2001-01-04)} */
      SELECT astext(minusGeometry(tgeompoint '[Point(0 0 0)@2001-01-01,
        Point(4 4 4)@2001-01-05]', geometry 'Polygon((1 1,1 2,2 2,2 1,1 1))'));
      /* {[POINT Z (0 0 0)@2001-01-01, POINT Z (1 1 1)@2001-01-02),
         (POINT Z (2 2 2)@2001-01-03, POINT Z (4 4 4)@2001-01-05]} */
      SELECT asText(minusGeometry(tgeompoint '[Point(1 1 1)@2001-01-01, Point(3 1 1)@2001-01-03,
        Point(3 1 3)@2001-01-05]', 'Polygon((2 0,2 2,2 4,4 0,2 0))', '[0,2]'));
      /* {[POINT Z (1 1 1)@2001-01-01, POINT Z (2 1 1)@2001-01-02),
          (POINT Z (3 1 2)@2001-01-04, POINT Z (3 1 3)@2001-01-05]} */
      SELECT asText(minusGeometry(tgeometry 'Linestring(1 1,10 1)@2001-01-01',
        'Polygon((0 0,0 5,5 5,5 0,0 0))'));
      -- LINESTRING(5 1,10 1)@2001-01-01

- Restringir a (al complemento de) un `stbox` &Z_support;

  `atStbox(tgeom,stbox,borderInc bool=true) → tgeompoint`

  `minusStbox(tgeom,stbox,borderInc bool=true) → tgeompoint`

  El tercer argumento opcional se utiliza para mosaicos multidimensionales (ver ttype_tiling) para excluir el borde superior de los mosaicos cuando un valor temporal se divide en varios mosaicos, de modo que todos los fragmentos de la geometría temporal sean exclusivos.

      SELECT asText(atStbox(tgeompoint '[Point(0 0)@2001-01-01, Point(3 3)@2001-01-04)',
        stbox 'STBOX XT(((0,0),(2,2)),[2001-01-02, 2001-01-04])'));
      -- {[POINT(1 1)@2001-01-02, POINT(2 2)@2001-01-03]}
      SELECT asText(atStbox(tgeompoint '[Point(1 1 1)@2001-01-01, Point(3 3 3)@2001-01-03,
        Point(3 3 2)@2001-01-04, Point(3 3 7)@2001-01-09]', stbox 'STBOX Z((2,2,2),(3,3,3))'));
      /* {[POINT Z (2 2 2)@2001-01-02, POINT Z (3 3 3)@2001-01-03, POINT Z (3 3 2)@2001-01-04,
        POINT Z (3 3 3)@2001-01-05]} */
      SELECT asText(atStbox(tgeometry '[Point(1 1)@2001-01-01, Linestring(1 1,3 3)@2001-01-03,
        Point(2 2)@2001-01-04, Linestring(3 3,4 4)@2001-01-09]', stbox 'STBOX X((2,2),(3,3))'));
      -- {[LINESTRING(2 2,3 3)@2001-01-03, POINT(2 2)@2001-01-04, POINT(3 3)@2001-01-09]}

      SELECT asText(minusStbox(tgeompoint '[Point(1 1)@2001-01-01, Point(4 4)@2001-01-04)',
        stbox 'STBOX XT(((1,1),(2,2)),[2001-01-03,2001-01-04])'));
      -- {(POINT(2 2)@2001-01-02, POINT(3 3)@2001-01-03)}
      SELECT asText(minusStbox(tgeompoint '[Point(1 1 1)@2001-01-01, Point(3 3 3)@2001-01-03,
        Point(3 3 2)@2001-01-04, Point(3 3 7)@2001-01-09]', stbox 'STBOX Z((2,2,2),(3,3,3))'));
      /* {[POINT Z (1 1 1)@2001-01-01, POINT Z (2 2 2)@2001-01-02),
          (POINT Z (3 3 3)@2001-01-05, POINT Z (3 3 7)@2001-01-09]} */
      SELECT asText(minusStbox(tgeometry '[Point(1 1)@2001-01-01,
        Linestring(1 1,3 3)@2001-01-03, Point(2 2)@2001-01-04,
        Linestring(1 1,4 4)@2001-01-09]', stbox 'STBOX X((2,2),(3,3))'));
      /* {[POINT(1 1)@2001-01-01, LINESTRING(1 1,2 2)@2001-01-03,
         LINESTRING(1 1,2 2)@2001-01-04),[MULTILINESTRING((1 1,2 2),(3 3,4 4))@2001-01-09]} */

## Sistema de referencia espacial

- Devuelve o establece el identificador de referencia espacial &Z_support; &geography_support;

  `SRID(tgeo) → integer`

  `setSRID(tgeo) → tgeo`

      SELECT SRID(tgeompoint 'Point(0 0)@2001-01-01');
      -- 0
      SELECT asEWKT(setSRID(tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02)', 4326));
      -- SRID=4326;[POINT(0 0)@2001-01-01 00:00:00+00, POINT(1 1)@2001-01-02 00:00:00+00)

- Transformar a una referencia espacial diferente &Z_support; &geography_support;

  `transform(tgeo,to_srid integer) → tgeo`

  `transformPipeline(tgeo,pipeline text,to_srid integer,is_forward bool=true) → tgeo`

  La función `transform` especifica la transformación con un SRID de destino. Se genera un error cuando el punto temporal tiene un SRID desconocido (representado por 0).

  La función `transformPipeline` especifica la transformación con una canalización de transformación de coordenadas definida representada con el siguiente formato:

  `urn:ogc:def:coordinateOperation:AUTHORITY::CODE`

  El SRID del punto temporal de entrada se ignora y el SRID del punto temporal de salida se establecerá en cero a menos que se proporcione un valor a través del parámetro opcional `to_srid`. Como se indica en el último parámetro, la canalización se ejecuta de forma predeterminada en dirección hacia adelante; al establecer el parámetro en falso, la canalización se ejecuta en la dirección inversa.

      SELECT asEWKT(transform(tgeompoint 'SRID=4326;Point(4.35 50.85)@2001-01-01', 3812));
      -- SRID=3812;POINT(648679.018035303 671067.055638114)@2001-01-01 00:00:00+00

      WITH test(tgeo, pipeline) AS (
        SELECT tgeogpoint 'SRID=4326;{Point(4.3525 50.846667 100.0)@2001-01-01,
          Point(-0.1275 51.507222 100.0)@2001-01-02}',
          text 'urn:ogc:def:coordinateOperation:EPSG::16031' )
      SELECT asEWKT(transformPipeline(transformPipeline(tgeo, pipeline, 4326),
        pipeline, 4326, false), 6)
      FROM test;
      /* SRID=4326;{POINT Z (4.3525 50.846667 100)@2001-01-01,
         POINT Z (-0.1275 51.507222 100)@2001-01-02} */

## Operaciones de cuadro delimitador

- Devuelve el cuadro delimitador espaciotemporal expandido en la dimensión espacial por un valor flotante &Z_support; &geography_support;

  `expandSpace({geo,tgeo},float) → stbox`

      SELECT expandSpace(geography 'Linestring(0 0,1 1)', 2);
      -- SRID=4326;GEODSTBOX X((-2,-2),(3,3))
      SELECT expandSpace(tgeompoint 'Point(0 0)@2001-01-01', 2);
      -- STBOX XT(((-2,-2),(2,2)),[2001-01-01,2001-01-01])

## Operaciones de distancia

- Devuelve la distancia más pequeña que haya existido &Z_support; &geography_support;

  `{geo,tgeo} |=| {geo,tgeo} → float`

      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

  El operador `|=|` se puede utilizar para realizar una búsqueda de vecino más cercano utilizando un índice GiST o SP-GIST (ver la ttype_indexing). Esta función corresponde a la función `ST_DistanceCPA` proporcionada por PostGIS, aunque este última requiere que ambos argumentos sean una trayectoria.

      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

- Devuelve el instante del primer punto temporal en el que los dos argumentos están a la distancia más cercana &Z_support; &geography_support;

  `nearestApproachInstant({geo,tgeo},{geo,tgeo}) → tgeo`

  La función sólo devuelve el primer instante que encuentre si hay más de uno. El instante resultante puede tener un límite exclusivo.

      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

  La función `nearestApproachInstant` generaliza the la función PostGIS `ST_ClosestPointOfApproach`. Primero, la última función requiere que ambos argumentos sean trayectorias. Segundo, la función `nearestApproachInstant` devuelve tanto el punto como la marca de tiempo del punto de aproximación más cercano, mientras que la función PostGIS sólo proporciona la marca de tiempo como se muestra a continuación.

      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+00

- Devuelve la línea que conecta el punto de aproximación más cercano &Z_support; &geography_support;

  `shortestLine({geo,tgeo},{geo,tgeo}) → geo`

  La función sólo devolverá la primera línea que encuentre si hay más de una.

      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)

  La función `shortestLine` se puede utilizar para obtener el resultado proporcionado por la función PostGIS `ST_CPAWithin` cuando ambos argumentos son trayectorias como se muestra a continuación.

      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

El operador de distancia temporal, denotado `<->`, calcula la distancia en cada instante de la intersección de las extensiones temporales de sus argumentos y da como resultado un número flotante temporal. Calcular la distancia temporal es útil en muchas aplicaciones de movilidad. Por ejemplo, un grupo en movimiento (también conocido como convoy o bandada) se define como un conjunto de objetos que se mueven cerca unos de otros durante un intervalo de tiempo prolongado. Esto requiere calcular la distancia temporal entre dos objetos en movimiento.

El operador de distancia temporal acepta una geometría/geografía restringida a un punto o un punto temporal como argumentos. Observe que los tipos temporales sólo consideran la interpolación lineal entre valores, mientras que la distancia es una raíz de una función cuadrática. Por lo tanto, el operador de distancia temporal proporciona una aproximación lineal del valor de distancia real para los puntos de secuencia temporal. En este caso, los argumentos se sincronizan en la dimensión de tiempo y para cada uno de los segmentos de línea que componen los argumentos, se calcula la distancia espacial entre el punto inicial, el punto final y el punto de aproximación más cercano, como se muestra en los ejemplos a continuación.

- Devuelve la distancia temporal &Z_support; &geography_support;

  `{geo,tgeo} <-> {geo,tgeo} → tfloat`

      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]

## Relaciones espaciales

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:

- Las relaciones alguna vez determinan determinan si la relación topológica o de distancia se satisface alguna vez (ver ever_always_comparison) 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 ever_always_comparison) 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 se han generalizado para geometrías temporales, solo las derivadas de las siguientes funciones: `ST_Contains`, `ST_Covers`, `ST_Disjoint`, `ST_Intersects`, `ST_Touches` y `ST_DWithin`. Estas funciones solo admiten geometrías 2D, y solo las funciones `ST_Covers`, `ST_Intersects` y `ST_DWithin` admiten geografías. Por lo tanto, esto mismo aplica a las funciones de MobilityDB derivadas de ellas, excepto que admiten 3D para puntos temporales, es decir, `tgeompoint` y `tgeogpoint`. Como se mencionó anteriormente, cada una de las funciones PostGIS mencionadas, como `ST_Contains`, tiene tres versiones generalizadas en MobilityDB: `eContains`, `aContains` y `tContains`. Además, no todas las combinaciones de parámetros son relevantes para las funciones generalizadas. Por ejemplo, `tContains(tpoint, geometría)` solo es relevante cuando la geometría es un solo punto, y `tContains(tpoint, tpoint)` es equivalente a `tintersects(tpoint, geometría)`.

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.

### Relaciones alguna vez o siempre

Presentamos a continuación las relaciones 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(geometry,tgeom) → boolean`

  `aContains(geometry,tgeom) → 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))',
        tgeometry '[Linestring(1 1,4 4)@2001-01-01, Point(3 3)@2001-01-04]');
      -- true

- Ever or always covers

  `eCovers({geometry,tgeom},{geometry,tgeom}) → boolean`

  `aCovers({geometry,tgeom},{geometry,tgeom}) → boolean`

  Please refer to the documentation of the ST_Contains and the ST_Covers function in PostGIS for detailed explanations about the difference between the two functions.

      SELECT eCovers(geometry 'Linestring(1 1,3 3)',
        tgeompoint '[Point(4 2)@2001-01-01, Point(2 4)@2001-01-02]');
      -- false
      SELECT eCovers(geometry 'Linestring(1 1,3 3,1 1)',
        tgeompoint '[Point(4 2)@2001-01-01, Point(2 4)@2001-01-03]');
      -- true
      SELECT eCovers(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 eCovers(geometry 'Polygon((1 1,1 3,3 3,3 1,1 1))',
        tgeometry '[Linestring(1 1,4 4)@2001-01-01, Point(3 3)@2001-01-04]');
      -- true

- Está disjunto alguna vez &Z_support; &geography_support;

  `eDisjoint({geometry,tgeom},{geometry,tgeom}) → boolean`

  `aDisjoint({geo,tgeo},{geo,tgeo}) → 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))',
        tgeometry '[Linestring(1 1 1,2 2 2)@2001-01-01, Point(2 2 2)@2001-01-03]');
      -- true

- Está alguna vez a distancia de &Z_support; &geography_support;

  `eDwithin({geo,tgeo},{geo,tgeo},float) → boolean`

  `aDwithin({geometry,tgeom},{geometry,tgeom},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 &Z_support; &geography_support;

  `eIntersects({geo,tgeo},{geo,tgeo}) → boolean`

  `aIntersects({geometry,tgeom},{geometry,tgeom}) → 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({geometry,tgeom},{geometry,tgeom}) → boolean`

  `aTouches({geometry,tgeom},{geometry,tgeom}) → 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

### Relaciones espaciotemporales

Presentamos a continuación las relaciones espaciotemporales. 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(atValues(tIntersects(T.trip, M.geom), True))
    FROM Trips T, Municipality M
    WHERE M.Name = "Brussels" AND atValues(tIntersects(T.trip, M.geom), True) IS NOT NULL;

Para simplificar la escritura de consultas, las relaciones espaciotemporales tienen un último parámetro opcional, que si se proporciona aplica la función `atValue` (ver ttype_restrictions) 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,tgeom,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 &Z_support; &geography_support;

  `tDisjoint({geo,tgeo},{geo,tgeo},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 &Z_support;

  `tDwithin({geo,tgeo},{geo,tgeo},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 &Z_support; &geography_support;

  `tIntersects({geo,tgeo},{geo,tgeo},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({geometry,tgeom},{geometry,tgeom},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]}