Poses estáticas y cadenas de poses estáticas

Una pose 2D es un par de la forma (point2D,radius) donde point2D es un punto geométrico 2D y radius es un valor float que representa un ángulo de rotación en (-π, π] expresado en radianes. Una pose 3D es una tupla de la forma (point3D,W,Y,X,Z) donde point3D es un punto geométrico 3D, y W, X, Y y Z son cuatro floats que representan un cuaternión unitario. Ejemplos de entrada de valores de pose son los siguientes:

SELECT pose 'Pose(Point(1 1), 0.5)';
SELECT pose 'Pose(Point Z(1 1 1), 0.5, 0.5, 0.5, 0.5)';

Se puede especificar un SRID para una pose ya sea al comienzo del literal de pose o antes del literal de punto, como se muestra a continuación.

SELECT pose 'SRID=3812;Pose(Point(1 1), 0.5)';
SELECT pose 'Pose(SRID=5676;Point Z(1 1 1), 0.5, 0.5, 0.5, 0.5)';

Al igual que para otros tipos espaciales, un pose puede ser planar (geométrico) o geodésico (geográfico). Un pose geodésico se denota con la palabra clave GeodPose, de la misma manera que un stbox geodésico se denota con GEODSTBOX.

SELECT pose 'GeodPose(Point(1 1), 0.5)';
SELECT pose 'SRID=4326;GeodPose(Point Z(1 1 1), 1, 0, 0, 0)';

Los valores del tipo pose deben satisfacer varias restricciones para que estén bien definidos. Ejemplos de valores incorrectos del tipo pose son los siguientes.

-- Empty point
select pose 'Pose(Point empty, 0.5)';
-- Incorrect point value
SELECT pose 'Pose(Linestring(1 1,2 2), 1.0)';
-- Incorrect radius value
SELECT pose 'Pose(Point(1 1), -10.0)';
-- Incorrect 3D point
SELECT pose 'Pose(Point Z(1 1), 1.0)';
-- Incomplete 3D orientation
SELECT pose 'Pose(Point Z(1 1 1), 1.0)';

A continuación damos las funciones y operadores para el tipo pose.

Entrada y salida

  • Devuelve la representación de texto conocido (WKT) o la representación extendida de texto conocido (EWKT)

    asText({pose,posechain,pose[],posechain[]}) → {text,text[]}
    asEWKT({pose,posechain,pose[],posechain[]}) → {text,text[]}
    
    SELECT asText(pose 'SRID=4326;Pose(Point(0 0),1)');
    -- Pose(POINT(0 0),1)
    SELECT asText(ARRAY[pose 'Pose(Point(0 0),1)', 'Pose(Point(1 1),2)']);
    -- {"Pose(POINT(0 0),1)","Pose(POINT(1 1),2)"}
    SELECT asEWKT(pose 'SRID=4326;Pose(Point(0 0),1)');
    -- SRID=4326;Pose(POINT(0 0),1)
    SELECT asEWKT(ARRAY[pose 'Pose(SRID=5676;Point(0 0),1)', 'Pose(SRID=5676;Point(1 1),2)']);
    -- {"Pose(SRID=5676;POINT(0 0),1)","Pose(SRID=5676;POINT(1 1),2))"}
    
  • Devuelve la representación binaria conocida (WKB), la representación extendida binaria conocida (EWKB), la representación hexadecimal binaria conocida (HexWKB), o la representación hexadecimal extendida binaria conocida (HexEWKB)

    asBinary({pose,posechain},endian text='') → bytea
    asEWKB({pose,posechain},endian text='') → bytea
    asHexWKB({pose,posechain},endian text='') → text
    asHexEWKB({pose,posechain},endian text='') → text
    

    La cadena escribe sus indicadores y su único SRID una sola vez, después el número de eslabones y después los valores de cada eslabón en orden. 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.

    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(pose 'Pose(Point(1 2),1)');
    -- \x0101000000000000f03f0000000000000040000000000000f03f
    SELECT asEWKB(pose 'SRID=7844;Pose(Point(1 2),1)');
    -- \x0141a41e0000000000000000f03f0000000000000040000000000000f03f
    SELECT asHexWKB(pose 'Pose(Point(1 2),1)');
    -- 0101000000000000F03F0000000000000040000000000000F03F
    SELECT asHexEWKB(pose 'SRID=3812;Pose(Point(1 2),1)');
    -- 0141E40E0000000000000000F03F0000000000000040000000000000F03F
    
  • Entrada desde la representación de texto conocido (WKT) o desde la representación extendida de texto conocido (EWKT)

    poseFromText(text) → pose
    poseFromEWKT(text) → pose
    posechainFromText(text) → posechain
    posechainFromEWKT(text) → posechain
    
    SELECT asEWKT(poseFromText(text 'Pose(Point(1 2),1)'));
    -- Pose(POINT(1 2),1)
    SELECT asEWKT(poseFromEWKT(text 'SRID=3812;Pose(Point(1 2),1)'));
    -- SRID=3812;Pose(POINT(1 2),1)
    SELECT asEWKT(posechainFromText('PoseChain(Pose(Point(0 0),0),Pose(Point(1 0),1))'));
    -- PoseChain(Pose(POINT(0 0),0),Pose(POINT(1 0),1))
    SELECT asEWKT(posechainFromEWKT('SRID=3812;PoseChain(Pose(Point(0 0),0))'));
    -- SRID=3812;PoseChain(Pose(POINT(0 0),0))
    
  • Entrada desde la representación binaria conocida (WKB), desde la representación extendida binaria conocida (EWKB), o desde la representación hexadecimal extendida binaria conocida (HexEWKB)

    poseFromBinary(bytea) → pose
    poseFromEWKB(bytea) → pose
    poseFromHexEWKB(text) → pose
    posechainFromBinary(bytea) → posechain
    posechainFromEWKB(bytea) → posechain
    posechainFromHexEWKB(text) → posechain
    
    SELECT asEWKT(poseFromBinary('\x0101000000000000f03f0000000000000040000000000000f03f'));
    -- Pose(POINT(1 2),1)
    SELECT asEWKT(poseFromEWKB(
      '\x0141a41e0000000000000000f03f0000000000000040000000000000f03f'));
    -- SRID=7844;Pose(POINT(1 2),1)
    SELECT asEWKT(poseFromHexEWKB(
      '0141E40E0000000000000000F03F0000000000000040000000000000F03F'));
    -- SRID=3812;Pose(POINT(1 2),1)
    SELECT posechainFromBinary(asBinary(posechain 'PoseChain(Pose(Point(1 2),0.5))')) =
      posechain 'PoseChain(Pose(Point(1 2),0.5))';
    -- t
    SELECT posechainFromHexEWKB(asHexEWKB( posechain 'SRID=3812;
      PoseChain(Pose(Point(1 2),0.5))')) = posechain 'SRID=3812;PoseChain(Pose(Point(1 2),
      0.5))';
    -- t
    

Constructores

  • Constructor para poses

    pose(geompoint2D,float) → pose
    pose(geompoint3D,float,float,float,float) → pose
    pose(geompoint3D,yaw float,pitch float,roll float) → pose
    

    La forma de tres ángulos toma la orientación en la otra codificación que prescribe el estándar OGC GeoPose v1.0, una terna yaw / pitch / roll en radianes bajo la convención Tait-Bryan intrínseca ZYX, y almacena el cuaternión que denota. Es la inversa de ypr.

    SELECT asText(pose(ST_Point(1,1), radians(45)), 6);
    -- Pose(POINT(1 1),0.785398)
    SELECT asEWKT(pose(ST_Point(1,1,3812), radians(45)), 6);
    -- SRID=3812;Pose(POINT(1 1),0.785398)
    SELECT asText(pose(ST_PointZ(1,1,1), 1, 0, 0, 0));
    -- Pose(POINT Z (1 1 1),1,0,0,0)
    SELECT asText(pose(ST_PointZ(1,1,1), radians(90), 0, 0), 6);
    -- Pose(POINT Z (1 1 1),0.707107,0,0,0.707107)
    

Conversión de tipos

Los valores del tipo pose se pueden convertir al tipo de punto geometry utilizando un CAST explícito o utilizando la notación :: como se muestra a continuación.

  • Convierte una pose y, opcionalmente, una marca de tiempo o un período, en una caja espaciotemporal

    {pose,posechain}::stbox
    stbox({pose,posechain}) → stbox
    stbox({pose,posechain},{timestamptz,tstzspan}) → stbox
    

    La caja cubre la posición compuesta de cada prefijo de la cadena y no solo la del conjunto: cada articulación es un lugar, y una ventana de consulta que alcanza el codo pero no la mano alcanza igualmente la cadena.

    SELECT stbox(pose 'SRID=5676;Pose(Point(1 1),0.3)');
    -- SRID=5676;STBOX X((1,1),(1,1))
    SELECT stbox(pose 'Pose(Point(1 1),0.3)', timestamptz '2001-01-01');
    -- STBOX XT(((1,1),(1.3,1.3)),[2001-01-01, 2001-01-01])
    SELECT stbox(pose 'Pose(Point(1 1),0.3)', tstzspan '[2001-01-01,2001-01-02]');
    -- STBOX XT(((1,1),(1.3,1.3)),[2001-01-01, 2001-01-02])
    
  • Convierte una pose en un punto geométrico

    pose::geompoint
    
    SELECT ST_AsText(pose(ST_Point(1, 1), 1)::geometry);
    -- POINT(1 1)
    SELECT ST_AsEWKT(pose(ST_PointZ(1, 1, 1, 5676), 1, 0, 0, 0)::geometry);
    -- SRID=5676;POINT(1 1 1)
    

Accesores

  • Devuelve el punto, que para una cadena de poses es el punto de su marco más interior

    point({pose,posechain}) → geometry
    
    SELECT ST_AsText(point(pose 'Pose(Point(1 1), 0.3)'));
    -- POINT(1 1)
    
  • Devuelve el cuaternión de orientación de una pose

    quaternion(pose) → quaternion
    

    Las componentes se devuelven en el orden W, X, Y, Z, la convención de Hamilton en la que una pose 3D las almacena. Esta es una de las dos codificaciones de orientación que prescribe el estándar OGC GeoPose v1.0; la otra, yaw / pitch / roll, la proporciona ypr. Ambas están definidas para las dos dimensiones: la orientación de una pose 2D es un giro alrededor de la vertical local por su ángulo almacenado, de modo que coloca la mitad de ese ángulo en W y Z y deja X e Y en cero. Este es el cuaternión que un documento GeoPose Basic-Quaternion lleva para una pose plana.

    SELECT quaternion(pose 'Pose(Point Z(1 1 1), 0, 0, 0, 1)');
    -- (0,0,0,1)
    SELECT quaternion(pose 'Pose(Point(1 1), 0)');
    -- (1,0,0,0)
    

Transformaciones

  • Redondea el punto y la orientación de la pose al número de posiciones decimales

    round({pose,posechain},integer=0) → {pose,posechain}
    
    SELECT asText(round(pose(ST_Point(1.123456789,1.123456789), 0.123456789), 6));
    -- Pose(POINT(1.123457 1.123457),0.123457)
    

Sistema de referencia espacial

  • Devuelve o establece el identificador de referencia espacial, que para una cadena de poses es el identificador de su marco exterior

    SRID({pose,posechain}) → integer
    setSRID({pose,posechain},integer) → {pose,posechain}
    
    SELECT SRID(pose 'Pose(SRID=5676;Point(1 1), 0.3)');
    -- 5676
    SELECT asEWKT(setSRID(pose 'Pose(Point(0 0),1)', 4326));
    -- SRID=4326;Pose(POINT(0 0),1)
    
  • Transforma a un identificador de referencia espacial

    transform({pose,posechain},integer) → {pose,posechain}
    transformPipeline({pose,posechain},pipeline text,srid integer,
      is_forward boolean=true) → {pose,posechain}
    

    La función transform especifica la transformación con un SRID de destino. Se genera un error cuando la entrada tiene un SRID desconocido (representado por 0). En una pose 3D, la orientación se reexpresa en la base del marco de destino en el punto de la pose: la corrección está definida para el par canónico de OGC GeoPose, WGS-84 geográfico (EPSG:4326) ↔ WGS-84 ECEF (EPSG:4978), tomando la base estándar Este-Norte-Arriba en el punto geográfico como pivote de rotación, y para cualquier otro par de SRID transform emite un NOTICE y deja pasar la orientación sin cambios. En una pose 2D, el ángulo es intrínseco a la proyección de origen y se deja pasar sin cambios. En una cadena solo el eslabón exterior nombra un marco y solo él se transforma, siendo cada uno de los demás eslabones una transformación rígida leída en los ejes de su marco padre, que un cambio del marco exterior deja como estaban. 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 de la pose de entrada se ignora y el SRID de la pose de salida se establecerá en cero a menos que se proporcione un valor a través del parámetro opcional 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(pose 'SRID=4326;Pose(Point(4.35 50.85),1)', 3812), 6);
    -- SRID=3812;Pose(POINT(648679.018035 671067.055638),1)
    
    -- Round-tripping a 3D pose through ECEF and back lands at the input pose
    SELECT asEWKT(round( transform(transform(pose 'SRID=4326;Pose(Point(8 47 0), 1, 0, 0, 0)',
      4978), 4326), 6));
    -- SRID=4326;Pose(POINT Z (8 47 0),1,0,0,0)
    -- At the equator-meridian (lat=lon=0), the body identity quaternion in the ECEF basis is
    -- the canonical East-North-Up to ECEF rotation
    SELECT asEWKT(round(transform(pose 'SRID=4326;Pose(Point(0 0 0), 1, 0, 0, 0)', 4978), 6));
    -- SRID=4978;Pose(POINT Z (6378137 0 0),0.5,0.5,0.5,0.5)
    
    WITH test(pose, pipeline) AS (
      SELECT pose 'Pose(SRID=4326;Point(4.3525 50.846667),1)',
        text 'urn:ogc:def:coordinateOperation:EPSG::16031' )
    SELECT asEWKT(transformPipeline(transformPipeline(pose, pipeline, 4326), pipeline, 4326,
      false), 6) FROM test;
    -- SRID=4326;Pose(POINT(4.3525 50.846667),1)
    

Operaciones de distancia

  • Devuelve la distancia

    distance({geo,pose},pose) → float
    distance(pose,{geo,pose}) → float
    {geo,pose} <-> pose → float
    

    Solo se tiene en cuenta el componente de punto de la pose, la orientación se ignora. La distancia se calcula en dos dimensiones, incluso cuando los argumentos son tridimensionales. El resultado es NULL cuando la geometría está vacía.

    SELECT round(distance(geometry 'Point(1 0)', pose 'Pose(Point(4 0),0)'), 6);
    -- 3
    SELECT round(pose 'Pose(Point(0 0),0)' <-> pose 'Pose(Point(3 4),0)', 6);
    -- 5
    SELECT round(pose 'Pose(Point(0 0 0), 1, 0, 0, 0)' <->
      pose 'Pose(Point(3 4 12), 1, 0, 0, 0)', 6);
    -- 5
    SELECT round(geometry 'Point empty' <-> pose 'Pose(Point(4 0),0)', 6);
    -- NULL
    
  • Devuelve la distancia de aproximación más cercana

    nearestApproachDistance({stbox,pose},{pose,stbox}) → float
    {stbox,pose} |=| {pose,stbox} → float
    

    El valor es la menor distancia sobre el tiempo que comparten los dos argumentos, y es NULL cuando no comparten ninguno. Una pose no lleva período, por lo que está presente en todo tiempo que abarca la caja. Solo se tiene en cuenta el componente de punto de la pose, la orientación se ignora.

    SELECT round(nearestApproachDistance(stbox 'STBOX X((1,-1),(3,1))', pose 'Pose(Point(4 0),0)'), 6);
    -- 1
    SELECT round(pose 'Pose(Point(4 0),0)' |=| stbox 'STBOX X((1,-1),(3,1))', 6);
    -- 1
    

Comparaciones

Los operadores de comparación (=, < y así sucesivamente) están disponibles para poses. Excepto la igualdad y la desigualdad, los otros operadores de comparación no son útiles en el mundo real pero permiten que los índices de árbol B se construyan en poses.

  • Comparaciones tradicionales

    {pose,posechain} {=, <>, <, >, <=, >=} {pose,posechain} → boolean
    

    El orden compara la dimensión, después el SRID, después los eslabones en orden y por último el número de eslabones, de modo que una cadena precede a toda cadena que la extiende.

    SELECT pose 'Pose(Point(3 3), 0.5)' = pose 'Pose(Point(3 3), 0.5)';
    -- true
    SELECT pose 'Pose(Point(3 3), 0.5)' <> pose 'Pose(Point(3 3), 0.6)';
    -- true
    SELECT pose 'Pose(Point(3 3), 0.5)' < pose 'Pose(Point(3 3), 0.6)';
    -- true
    SELECT pose 'Pose(Point(3 3), 0.6)' > pose 'Pose(Point(2 2), 0.6)';
    -- true
    SELECT pose 'Pose(Point Z(1 1 1), 0.5, 0.5, 0.5, 0.5)' <=
      pose 'Pose(Point Z(2 2 2), 0.5, 0.5, 0.5, 0.5)';
    -- true
    SELECT pose 'Pose(Point(1 1), 0.6)' >= pose 'Pose(Point(1 1), 0.5)';
    -- true
    
  • ¿Son los dos valores aproximadamente iguales con respecto a un valor épsilon?

    same(pose,pose) → boolean
    same(posechain,posechain) → boolean
    pose ~= pose → boolean
    posechain ~= posechain → boolean
    
    SELECT pose 'Pose(SRID=5676;Point(1 1), 0.3)' ~= pose 'Pose(SRID=5676;
      Point(1 1.0000001), 0.30000001)';
    -- true