# Tipos temporales: Operaciones espaciales

A continuación, especificamos con el símbolo &Z_support; que la función admite puntos 3D y con el símbolo &geography_support; que la función está disponible para geografías.

## Entrada y salida

- Devuelve la representación de texto conocido (Well-Known Text o WKT) &Z_support; &geography_support;

  `asText({tpoint,tpoint[],geo[]}) → {text,text[]}`

      SELECT asText(tgeompoint 'SRID=4326;[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02)');
      -- [POINT Z (0 0 0)@2001-01-01, POINT Z (1 1 1)@2001-01-02)
      SELECT asText(ARRAY[geometry 'Point(0 0)', 'Point(1 1)']);
      -- {"POINT(0 0)","POINT(1 1)"}

- Devuelve la representación extendida de texto conocido (Extended Well-Known Text o EWKT)

  `asEWKT({tpoint,tpoint[],geo[]}) → {text,text[]}`

      SELECT asEWKT(tgeompoint 'SRID=4326;[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02)');
      -- SRID=4326;[POINT Z (0 0 0)@2001-01-01, POINT Z (1 1 1)@2001-01-02)
      SELECT asEWKT(ARRAY[geometry 'SRID=5676;Point(0 0)', 'SRID=5676;Point(1 1)']);
      -- {"SRID=5676;POINT(0 0)","SRID=5676;POINT(1 1)"}

- Devuelve la representación JSON de características móviles (Moving Features JSON o MF-JSON) &Z_support; &geography_support;

  `asMFJSON(tpoint,options=0,flags=0,maxdecdigits=15) → text`

  El argumento `options` puede usarse para agregar BBOX y/o CRS en la salida MFJSON:

  - 0: significa que no hay opción (valor por defecto)

  - 1: MFJSON BBOX

  - 2: MFJSON Short CRS (e.g., EPSG:4326)

  - 4: MFJSON Long CRS (e.g., urn:ogc:def:crs:EPSG::4326)

  El argumento `flags` puede usarse para personalizar la salida JSON, por ejemplo, para producir una salida JSON fácil de leer (para lectores humanos). Consulte la documentación de la biblioteca `json-c` para conocer los valores posibles. Los valores típicos son los siguientes:

  - 0: means no option (default value)

  - 1: JSON_C_TO_STRING_SPACED

  - 2: JSON_C_TO_STRING_PRETTY

  El argumento `maxdecdigits` puede usarse para establecer el número máximo de decimales en la salida de los valores en punto flotante (por defecto 15).

      SELECT asMFJSON(tgeompoint 'Point(1 2)@2001-01-01 18:00:00.15+02');
      /* {"type":"MovingPoint","coordinates":[[1,2]],"datetimes":["2001-01-01T17:00:00.15+01"],
         "interpolation":"None"} */
      SELECT asMFJSON(tgeompoint 'SRID=4326;
        Point(50.813810 4.384260)@2001-01-01 18:00:00.15+02', 3, 2);
      /* {"type":"MovingPoint","crs":{"type":"name","properties":{"name":"EPSG:4326"}},
         "stBoundedBy":{"bbox":[50.81,4.38,50.81,4.38],
         "period":{"begin":"2001-01-01 17:00:00.15+01","end":"2001-01-01 17:00:00.15+01"}},
         "coordinates":[[50.81,4.38]],"datetimes":["2001-01-01T17:00:00.15+01"],
         "interpolation":"None"} */

- Devuelve la representación binaria conocida (Well-Known Binary o WKB) &Z_support; &geography_support;

  `asBinary(tpoint,endian text='') → bytea`

  El resultado se codifica utilizando la codificación little-endian (NDR) o big-endian (XDR). Si no se especifica ninguna codificación, se utiliza la codificación de la máquina.

      SELECT asBinary(tgeompoint 'Point(1 2 3)@2001-01-01');
      -- \x012e0011000000000000f03f00000000000000400000000000000840009c57d3c11c0000

- Devuelve la representación extendida binaria conocida (Extended Well-Known Binary o EWKB) &Z_support; &geography_support;

  `asEWKB(tpoint,endian text='') → bytea`

  El resultado se codifica utilizando la codificación little-endian (NDR) o big-endian (XDR). Si no se especifica ninguna codificación, se utiliza la codificación de la máquina.

      SELECT asEWKB(tgeogpoint 'SRID=7844;Point(1 2 3)@2001-01-01');
      -- \x012f0071a41e0000000000000000f03f00000000000000400000000000000840009c57d3c11c0000

- Devuelve la representación hexadecimal extendida binaria conocida (Extended Well-Known Binary o EWKB) en formato texto &Z_support; &geography_support;

  `asHexEWKB(tpoint,endian text='') → text`

  El resultado se codifica utilizando la codificación little-endian (NDR) o big-endian (XDR). Si no se especifica ninguna codificación, se utiliza la codificación de la máquina.

      SELECT asHexEWKB(tgeompoint 'SRID=3812;Point(1 2 3)@2001-01-01');
      -- 012E0051E40E0000000000000000F03F00000000000000400000000000000840009C57D3C11C0000

- Entrar un punto temporal en una representación de texto conocido (Well-Known Text o WKT) &Z_support; &geography_support;

  `tgeompointFromText(text) → tgeompoint`

  `tgeogpointFromText(text) → tgeogpoint`

      SELECT asEWKT(tgeompointFromText(text '[POINT(1 2)@2001-01-01, POINT(3 4)@2001-01-02]'));
      -- [POINT(1 2)@2001-01-01, POINT(3 4)@2001-01-02]
      SELECT asEWKT(tgeogpointFromText(text '[POINT(1 2)@2001-01-01, POINT(3 4)@2001-01-02]'));
      -- SRID=4326;[POINT(1 2)@2001-01-01, POINT(3 4)@2001-01-02]

- Entrar un punto temporal en una representación extendida de texto conocido (Extended Well-Known Text o EWKT) &Z_support; &geography_support;

  `tgeompointFromEWKT(text) → tgeompoint`

  `tgeogpointFromEWKT(text) → tgeogpoint`

      SELECT asEWKT(tgeompointFromEWKT(text 'SRID=3812;[POINT(1 2)@2001-01-01,
        POINT(3 4)@2001-01-02]'));
      -- SRID=3812;[POINT(1 2)@2001-01-01 00:00:00+01, POINT(3 4)@2001-01-02 00:00:00+01]
      SELECT asEWKT(tgeogpointFromEWKT(text 'SRID=7844;[POINT(1 2)@2001-01-01,
      	POINT(3 4)@2001-01-02]'));
      -- SRID=7844;[POINT(1 2)@2001-01-01, POINT(3 4)@2001-01-02]

- Entrar un punto temporal en una representación JSON de características móviles (Moving Features) &Z_support; &geography_support;

  `tgeompointFromMFJSON(text) → tgeompoint`

  `tgeogpointFromMFJSON(text) → tgeogpoint`

      SELECT asEWKT(tgeompointFromMFJSON(text '{"type":"MovingGeomPoint","crs":{"type":"name",
        "properties":{"name":"EPSG:4326"}},"coordinates":[[50.81,4.38]],
        "datetimes":["2001-01-01T17:00:00.15+01"],"interpolation":"None"}'));
      -- SRID=4326;POINT(50.81 4.38)@2001-01-01 17:00:00.15+01
      SELECT asEWKT(tgeogpointFromMFJSON(text '{"type":"MovingGeogPoint","crs":{"type":"name",
        "properties":{"name":"EPSG:4326"}},"coordinates":[[50.81,4.38]],
        "datetimes":["2001-01-01T17:00:00.15+01"],"interpolation":"None"}'));
      -- SRID=4326;POINT(50.81 4.38)@2001-01-01 17:00:00.15+01

- Entrar un punto temporal en una representación binaria conocida (WKB) &Z_support; &geography_support;

  `tgeompointFromBinary(bytea) → tgeompoint`

  `tgeogpointFromBinary(bytea) → tgeogpoint`

      SELECT asEWKT(tgeompointFromBinary(
        '\x012e0011000000000000f03f00000000000000400000000000000840009c57d3c11c0000'));
      -- POINT Z (1 2 3)@2001-01-01

- Entrar un punto temporal en una representación extendida binaria conocida (EWKB) &Z_support; &geography_support;

  `tgeompointFromEWKB(bytea) → tgeompoint`

  `tgeogpointFromEWKB(bytea) → tgeogpoint`

      SELECT asEWKT(tgeogpointFromEWKB(
        '\x012f0071a41e0000000000000000f03f00000000000000400000000000000840009c57d3c11c0000'));
      -- SRID=7844;POINT Z (1 1 1)@2001-01-01

- Entrar un punto temporal geométrico en una representación hexadecimal extendida binaria conocida (HexEWKB) &Z_support; &geography_support;

  `tgeompointFromHexEWKB(text) → tgeompoint`

  `tgeogpointFromHexEWKB(text) → tgeogpoint`

      SELECT asEWKT(tgeompointFromHexEWKB(
        '012E0051E40E0000000000000000F03F00000000000000400000000000000840009C57D3C11C0000'));
      -- SRID=3812;POINT(1 2 3)@2001-01-01

## Sistema de referencia espacial

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

  `SRID(tpoint) → integer`

      SELECT SRID(tgeompoint 'Point(0 0)@2001-01-01');
      -- 0

- Establecer el identificador de referencia espacial &Z_support; &geography_support;

  `setSRID(tpoint) → tpoint`

      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(tpoint,to_srid integer) → tpoint`

  `transform(tpoint,pipeline text,to_srid integer,is_forward bool=true) → tpoint`

  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 de cadena: `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(tpoint, 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(tpoint, 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,tpoint},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])

## Accessores

- Obtenir la trayectoria &Z_support; &geography_support;

  `trajectory(tpoint) → geo`

  Esta función es equivalente a `getValues` para los valores temporales alphanuméricos

      SELECT ST_AsText(trajectory(tgeompoint '{[Point(0 0)@2001-01-01, Point(0 1)@2001-01-02),
        [Point(0 1)@2001-01-03, Point(1 1)@2001-01-04)}'));
      -- MULTILINESTRING((0 0,0 1),(0 1,1 1))
      SELECT ST_AsText(trajectory(tgeompoint 'Interp=Step;{[Point(0 0)@2001-01-01,
        Point(0 1)@2001-01-02], [Point(0 1)@2001-01-03, Point(1 1)@2001-01-04]}'));
      -- MULTIPOINT((0 0),(0 1),(0 1),(1 1))
      SELECT ST_AsText(trajectory(tgeompoint '{Point(0 0)@2001-01-01, Point(0 1)@2001-01-02}'));
      -- MULTIPOINT((0 0),(0 1))
      SELECT ST_AsText(trajectory(tgeompoint '{[Point(0 0)@2001-01-01, Point(0 1)@2001-01-02),
        [Point(1 1)@2001-01-03, Point(1 1)@2001-01-04),
        [Point(2 1)@2001-01-05, Point(2 2)@2001-01-06)}'));
      -- GEOMETRYCOLLECTION(POINT(1 1),MULTILINESTRING((0 0,0 1),(2 1,2 2)))

- Devuelve los valores de las coordenadas X/Y/Z como un número flotante temporal &Z_support; &geography_support;

  `getX(tpoint) → tfloat`

  `getY(tpoint) → tfloat`

  `getZ(tpoint) → tfloat`

      SELECT getX(tgeompoint '{Point(1 2)@2001-01-01, Point(3 4)@2001-01-02,
        Point(5 6)@2001-01-03}');
      -- {1@2001-01-01, 3@2001-01-02, 5@2001-01-03}
      SELECT getX(tgeogpoint 'Interp=Step;[Point(1 2 3)@2001-01-01, Point(4 5 6)@2001-01-02,
        Point(7 8 9)@2001-01-03]');
      -- Interp=Step;[1@2001-01-01, 4@2001-01-02, 7@2001-01-03]
      SELECT getY(tgeompoint '{Point(1 2)@2001-01-01, Point(3 4)@2001-01-02,
        Point(5 6)@2001-01-03}');
      -- {2@2001-01-01, 4@2001-01-02, 6@2001-01-03}
      SELECT getY(tgeogpoint 'Interp=Step;[Point(1 2 3)@2001-01-01, Point(4 5 6)@2001-01-02,
        Point(7 8 9)@2001-01-03]');
      -- Interp=Step;[2@2001-01-01, 5@2001-01-02, 8@2001-01-03]
      SELECT getZ(tgeompoint '{Point(1 2)@2001-01-01, Point(3 4)@2001-01-02,
        Point(5 6)@2001-01-03}');
      -- The temporal point must have Z dimension
      SELECT getZ(tgeogpoint 'Interp=Step;[Point(1 2 3)@2001-01-01, Point(4 5 6)@2001-01-02,
        Point(7 8 9)@2001-01-03]');
      -- Interp=Step;[3@2001-01-01, 6@2001-01-02, 9@2001-01-03]

- Devuelve verdadero si el punto temporal no se auto-intersecta espacialmente &Z_support;

  `isSimple(tpoint) → boolean`

  Nótese que un punto temporal de conjunto de secuencias es simple si cada una de las secuencias que lo componen es simple.

      SELECT isSimple(tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(0 0)@2001-01-03]');
      -- false
      SELECT isSimple(tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02,
        Point(2 0 2)@2001-01-03, Point(0 0 0)@2001-01-04]');
      -- false
      SELECT isSimple(tgeompoint '{[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02],
        [Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-04]}');
      -- true

- Devuelve la longitud atravesada por el punto temporal &Z_support; &geography_support;

  `length(tpoint) → float`

      SELECT length(tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02]');
      -- 1.73205080756888
      SELECT length(tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02,
        Point(0 0 0)@2001-01-03]');
      -- 3.46410161513775
      SELECT length(tgeompoint 'Interp=Step;[Point(0 0 0)@2001-01-01,
        Point(1 1 1)@2001-01-02, Point(0 0 0)@2001-01-03]');
      -- 0

- Devuelve la longitud acumulada atravesada por el punto temporal &Z_support; &geography_support;

  `cumulativeLength(tpoint) → tfloatSeq`

      SELECT round(cumulativeLength(tgeompoint '{[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(1 0)@2001-01-03], [Point(1 0)@2001-01-04, Point(0 0)@2001-01-05]}'), 6);
      -- {[0@2001-01-01, 1.414214@2001-01-02, 2.414214@2001-01-03],
        [2.414214@2001-01-04, 3.414214@2001-01-05]}
      SELECT cumulativeLength(tgeompoint 'Interp=Step;[Point(0 0 0)@2001-01-01,
        Point(1 1 1)@2001-01-02, Point(0 0 0)@2001-01-03]');
      -- Interp=Step;[0@2001-01-01, 0@2001-01-03]

- Devuelve la velocidad del punto temporal en unidades por segundo &Z_support; &geography_support;

  `speed(tpoint) → tfloatSeqSet`

  El punto temporal debe tener interpolación linear

      SELECT speed(tgeompoint '{[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(1 0)@2001-01-03], [Point(1 0)@2001-01-04, Point(0 0)@2001-01-05]}') * 3600 * 24;
      /* Interp=Step;{[1.4142135623731@2001-01-01, 1@2001-01-02, 1@2001-01-03],
         [1@2001-01-04, 1@2001-01-05]} */
      SELECT speed(tgeompoint 'Interp=Step;[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(1 0)@2001-01-03]');
      -- ERROR:  The temporal value must have linear interpolation

- Devuelve el centroide ponderado en el tiempo &Z_support;

  `twCentroid(tgeompoint) → point`

      SELECT ST_AsText(twCentroid(tgeompoint '{[Point(0 0 0)@2001-01-01,
        Point(0 1 1)@2001-01-02, Point(0 1 1)@2001-01-03, Point(0 0 0)@2001-01-04)}'));
      -- POINT Z (0 0.666666666666667 0.666666666666667)

- Devuelve la dirección, es decir, el acimut entre las ubicaciones inicial y final &Z_support; &geography_support;

  `direction(tpoint) → float`

  El resultado se expresa en radianes. Es NULL si solo hay una ubicación o si las ubicaciones inicial y final son iguales.

      SELECT round(degrees(direction(tgeompoint '[Point(0 0)@2001-01-01,
        Point(-1 -1)@2001-01-02, Point(1 1)@2001-01-03]'))::numeric, 6);
      -- 45.000000
      SELECT direction(tgeompoint '{[Point(0 0 0)@2001-01-01,
        Point(0 1 1)@2001-01-02, Point(0 1 1)@2001-01-03, Point(0 0 0)@2001-01-04)}');
      -- NULL

- Devuelve el acimut temporal &Z_support; &geography_support;

  `azimuth(tpoint) → tfloat`

  El resultado se expresa en radianes. El azimut es indefinido cuando dos localizaciones sucesivas son iguales y en este caso se añade una brecha de tempo.

      SELECT round(degrees(azimuth(tgeompoint '[Point(0 0 0)@2001-01-01,
        Point(1 1 1)@2001-01-02, Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-04)')));
      -- Interp=Step;{[45@2001-01-01, 45@2001-01-02], [225@2001-01-03, 225@2001-01-04)}

- Devuelve la diferencia angular temporal &geography_support;

  `angularDifference(tpoint) → tfloat`

  El resultado se expresa en grados.

      SELECT round(angularDifference(tgeompoint '[Point(1 1)@2001-01-01, Point(2 2)@2001-01-02,
        Point(1 1)@2001-01-03]'), 3);
      -- {0@2001-01-01, 180@2001-01-02, 0@2001-01-03}
      SELECT round(degrees(angularDifference(tgeompoint '{[Point(1 1)@2001-01-01,
        Point(2 2)@2001-01-02], [Point(2 2)@2001-01-03, Point(1 1)@2001-01-04]}')), 3);
      -- {0@2001-01-01, 0@2001-01-02, 0@2001-01-03, 0@2001-01-04}

- Devuelve el rumbo temporal &Z_support; &geography_support;

  `bearing({tpoint, point}, {tpoint, point}) → tfloat`

  Nótese que esta función no acepta dos puntos geográficos temporales.

      SELECT degrees(bearing(tgeompoint '[Point(1 1)@2001-01-01, Point(3 3)@2001-01-03]',
        geometry 'Point(2 2)'));
      -- [45@2001-01-01, 0@2001-01-02, 225@2001-01-03]
      SELECT round(degrees(bearing(tgeompoint '[Point(0 0)@2001-01-01, Point(2 0)@2001-01-03]',
        tgeompoint '[Point(2 1)@2001-01-01, Point(0 1)@2001-01-03]')), 3);
      --  [63.435@2001-01-01, 0@2001-01-02, 296.565@2001-01-03]
      SELECT round(degrees(bearing(tgeompoint '[Point(2 1)@2001-01-01, Point(0 1)@2001-01-03]',
        tgeompoint '[Point(0 0)@2001-01-01, Point(2 0)@2001-01-03]')), 3);
      -- [243.435@2001-01-01, 116.565@2001-01-03]

## Transformaciones

- Redondear los valores de las coordenadas a un número de decimales &Z_support; &geography_support;

  `round(tpoint,integer=0) → tpoint`

      SELECT asText(round(tgeompoint '{Point(1.12345 1.12345 1.12345)@2001-01-01,
        Point(2 2 2)@2001-01-02, Point(1.12345 1.12345 1.12345)@2001-01-03}', 2));
      /* {POINT Z (1.12 1.12 1.12)@2001-01-01, POINT Z (2 2 2)@2001-01-02,
         POINT Z (1.12 1.12 1.12)@2001-01-03} */
      SELECT asText(round(tgeogpoint 'Point(1.12345 1.12345)@2001-01-01', 2));
      -- POINT(1.12 1.12)@2001-01-01

- Devuelve una matriz de fragmentos del punto temporal que son simples &Z_support;

  `makeSimple(tpoint) → tgeompoint[]`

      SELECT asText(makeSimple(tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(0 0)@2001-01-03]'));
      /* {"[POINT(0 0)@2001-01-01, POINT(1 1)@2001-01-02)",
         "[POINT(1 1)@2001-01-02, POINT(0 0)@2001-01-03]"} */
      SELECT asText(makeSimple(tgeompoint '[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02,
        Point(2 0 2)@2001-01-03, Point(0 0 0)@2001-01-04]'));
      /* {"[POINT Z (0 0 0)@2001-01-01, POINT Z (1 1 1)@2001-01-02, POINT Z (2 0 2)@2001-01-03,
         POINT Z (0 0 0)@2001-01-04]"} */
      SELECT asText(makeSimple(tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(0 1)@2001-01-03, Point(1 0)@2001-01-04]'));
      /* {"[POINT(0 0)@2001-01-01, POINT(1 1)@2001-01-02, POINT(0 1)@2001-01-03)",
         "[POINT(0 1)@2001-01-03, POINT(1 0)@2001-01-04]"} */
      SELECT asText(makeSimple(tgeompoint '{[Point(0 0 0)@2001-01-01, Point(1 1 1)@2001-01-02],
        [Point(1 1 1)@2001-01-03, Point(0 0 0)@2001-01-04]}'));
      /* {"{[POINT Z (0 0 0)@2001-01-01, POINT Z (1 1 1)@2001-01-02],
         [POINT Z (1 1 1)@2001-01-03, POINT Z (0 0 0)@2001-01-04]}"} */

- Construir una geometría/geografía con medida M a partir de un punto temporal y un número flotante temporal &Z_support; &geography_support;

  `geoMeasure(tpoint,tfloat,segmentize=false) → geo`

  El último argumento `segmentize` establece si el valor resultado ya sea es un `Linestring M` o un `MultiLinestring M` donde cada componente es un segmento de dos puntos.

      SELECT st_astext(geoMeasure(tgeompoint '{Point(1 1 1)@2001-01-01,
        Point(2 2 2)@2001-01-02}', '{5@2001-01-01, 5@2001-01-02}'));
      -- MULTIPOINT ZM (1 1 1 5,2 2 2 5)
      SELECT st_astext(geoMeasure(tgeogpoint '{[Point(1 1)@2001-01-01, Point(2 2)@2001-01-02],
        [Point(1 1)@2001-01-03, Point(1 1)@2001-01-04]}',
        '{[5@2001-01-01, 5@2001-01-02],[7@2001-01-03, 7@2001-01-04]}'));
      -- GEOMETRYCOLLECTION M (POINT M (1 1 7),LINESTRING M (1 1 5,2 2 5))
      SELECT st_astext(geoMeasure(tgeompoint '[Point(1 1)@2001-01-01,
        Point(2 2)@2001-01-02, Point(1 1)@2001-01-03]',
        '[5@2001-01-01, 7@2001-01-02, 5@2001-01-03]', true));
      -- MULTILINESTRING M ((1 1 5,2 2 5),(2 2 7,1 1 7))

  Una visualización típica de los datos de movilidad es mostrar en un mapa la trayectoria del objeto móvil utilizando diferentes colores según la velocidad. La figspeed muestra el resultado de la consulta a continuación usando una rampa de color en QGIS.

      WITH Temp(t) AS (
        SELECT tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-05,
          Point(2 0)@2001-01-08, Point(3 1)@2001-01-10, Point(4 0)@2001-01-11]'
      )
      SELECT ST_AsText(geoMeasure(t, round(speed(t) * 3600 * 24, 2), true))
      FROM Temp;
      /* MULTILINESTRING M ((0 0 0.35,1 1 0.35),(1 1 0.47,2 0 0.47),(2 0 0.71,3 1 0.71),
        (3 1 1.41,4 0 1.41)) */

  La siguiente expresión se usa en QGIS para lograr esto. La función `scale_linear` transforma el valor M de cada segmento componente al rango [0, 1]. Este valor luego se pasa a la función `ramp_color`.

      ramp_color(
        'RdYlBu',
        scale_linear(
          m(start_point(geometry_n($geometry,@geometry_part_num))),
            0, 2, 0, 1)
      	)

  ### Visualización de la velocidad de un objeto móvil usando una rampa de color en QGIS.

- Transformar un punto geométrico temporal en el espacio de coordenadas de un Mapbox Vector Tile &Z_support;

  `asMVTGeom(tpoint,bounds,extent=4096,buffer=256,clip=true) → (geom,times)`

  El resultado es un par compuesto de un valor `geometry` y una matriz de valores de marca de tiempo asociados codificados como época de Unix. Los parámetros son los siguientes:

  - `tpoint` es el punto temporal para transformar

  - `bounds` es un `stbox` que define los límites geométricos del contenido del mosaico sin búfer

  - `extent` es la extensión del mosaico en el espacio de coordenadas del mosaico

  - `buffer` es la distancia del búfer en el espacio de coordenadas de mosaico

  - `clip` es un booleano que determina si las geometrías resultantes y las marcas de tiempo deben recortarse o no

      SELECT ST_AsText((mvt).geom), (mvt).times
      FROM (SELECT asMVTGeom(tgeompoint '[Point(0 0)@2001-01-01, Point(100 100)@2001-01-02]',
        stbox 'STBOX X((40,40),(60,60))') AS mvt ) AS t;
      -- LINESTRING(-256 4352,4352 -256) | {946714680,946734120}
      SELECT ST_AsText((mvt).geom), (mvt).times
      FROM (SELECT asMVTGeom(tgeompoint '[Point(0 0)@2001-01-01, Point(100 100)@2001-01-02]',
        stbox 'STBOX X((40,40),(60,60))', clip:=false) AS mvt ) AS t;
      -- LINESTRING(-8192 12288,12288 -8192) | {946681200,946767600}

## Operaciones de distancia

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

  `{geo,tpoint} |=| {geo,tpoint} → 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 tgeompoint 'Interp=Step;(Point(1 1)@2001-01-01, Point(3 1)@2001-01-03]' |=|
        geometry 'Linestring(1 3,2 2,3 3)';
      -- 1.4142135623731

  El operador `|=|` se puede utilizar para realizar una búsqueda de vecino más cercano utilizando un índice GiST o SP-GIST (ver la temporal_types_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,tpoint},{geo,tpoint}) → tpoint`

  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(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)'));
      -- POINT Z (0.75 0.75 0.75)@2001-01-03 12:00:00+00

  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,tpoint},{geo,tpoint}) → 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(
        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)'));
      -- LINESTRING Z (0.75 0.75 0.75,1.25 0.75 0.75)

  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;

  `{point,tpoint} <-> {point,tpoint} → 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 tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02)' <->
        tgeompoint '[Point(0 1)@2001-01-01, Point(1 2)@2001-01-02)';
      -- [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 espaciales:

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

### Relaciones espaciales alguna vez o siempre

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 &Z_support; &geography_support;

  `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 &Z_support; &geography_support;

  `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 &Z_support; &geography_support;

  `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

### Relaciones espaciales temporales

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 temporal_types_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,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 &Z_support; &geography_support;

  `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 &Z_support;

  `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 &Z_support; &geography_support;

  `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]}