Tabla de contenidos
El tipo pose se utiliza para representar la ubicación y la orientación de objetos geométricos dentro de sistemas de coordenadas anclados a la superficie de la Tierra o dentro de otros sistemas de coordenadas astronómicas. La ubicación se representa mediante un punto 2D o 3D. Para las poses 2D, la orientación se define mediante un ángulo de rotación en (-π, π] expresado en radianes. Para las poses 3D, la orientación se define mediante cuatro valores flotantes W, X, Y, Z, que representan un cuaternión unitario
donde
.
El grupo de trabajo de estándares GeoPose (SWG), que trabaja bajo los auspicios del Open Geospatial Consortium, ha definido un estándar para intercambiar información de poses entre distintos usuarios, dispositivos y plataformas. Se puede encontrar más información sobre el estándar en el repositorio de GitHub del SWG GeoPose.
El tipo pose sirve como tipo base para definir el tipo de pose temporal tpose. El tipo tpose tiene una funcionalidad similar al tipo de punto temporal tgeompoint. Por lo tanto, la mayoría de las funciones y operadores descritos anteriormente para el tipo tgeompoint también son aplicables para el tipo tpose. Además, hay funciones específicas definidas para el tipo tpose.
El tipo tpose se utiliza para definir el tipo trgeometry (es decir, geometría rígida temporal) definido en el siguiente capítulo. La implementación de estos tipos en MobilityDB se ha estudiado en la siguiente tesis doctoral.
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)';
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.
-- Punto vacío select pose 'Pose(Point empty, 0.5)'; -- Valor de punto incorrecto SELECT pose 'Pose(Linestring(1 1,2 2), 1.0)'; -- Valor de radio incorrecto SELECT pose 'Pose(Point(1 1), -10.0)'; -- Punto 3D incorrecto SELECT pose 'Pose(Point Z(1 1), 1.0)'; -- Orientación 3D incompleta SELECT pose 'Pose(Point Z(1 1 1), 1.0)';
A continuación damos las funciones y operadores para el tipo pose.
Devuelve la representación de texto conocido (Well-Known Text o WKT) o la representación extendida de texto conocido (Extended Well-Known Text o EWKT)
asText({pose,pose[]}) → {text,text[]}
asEWKT({pose,pose[]}) → {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 (Well-Known Binary o WKB), la representación extendida binaria conocida (Extended Well-Known Binary o EWKB), la representación hexadecimal binaria conocida (Hexadecimal Well-Known Binary o HexWKB), o la representación hexadecimal extendida binaria conocida (Hexadecimal Extended Well-Known Binary o HexEWKB)
asBinary(pose,endian text='') → bytea asEWKB(pose,endian text='') → bytea asHexWKB(pose,endian text='') → text asHexEWKB(pose,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 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 (Well-Known Text o WKT) o desde la representación extendida de texto conocido (Extended Well-Known Text o EWKT)
poseFromText(text) → pose poseFromEWKT(text) → pose
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)
Entrada desde la representación binaria conocida (Well-Known Binary o WKB), desde la representación extendida binaria conocida (Extended Well-Known Binary o EWKB), o desde la representación hexadecimal extendida binaria conocida (Hexadecimal Extended Well-Known Binary o HexEWKB)
poseFromBinary(bytea) → pose poseFromEWKB(bytea) → pose poseFromHexEWKB(text) → pose
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)
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)
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.
Convertir una pose y, opcionalmente, una marca de tiempo o un período, en una caja espaciotemporal
pose::stbox
stbox(pose) → stbox
stbox(pose,{timestamptz,tstzspan}) → stbox
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])
Convertir 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)
Devuelve el punto
point(pose) → geompoint
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)
Devuelve o establece el identificador de referencia espacial
SRID(pose) → integer setSRID(pose) → pose
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)
Transformar a un identificador de referencia espacial
transform(pose,integer) → pose transformPipeline(pose,pipeline text,to_srid integer,is_forward boolean=true) → pose
La función transform especifica la transformación con un SRID de destino. Se genera un error cuando la pose de 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), y toma la base estándar Este-Norte-Arriba en el punto geográfico como pivote de rotación. 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.
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 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(pose 'SRID=4326;Pose(Point(4.35 50.85),1)', 3812), 6); -- SRID=3812;Pose(POINT(648679.018035 671067.055638),1)
-- Un viaje de ida y vuelta de una pose 3D por ECEF aterriza en la pose de entrada
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)
-- En el cruce del ecuador y el meridiano (lat=lon=0), el cuaternión identidad
-- del cuerpo en la base ECEF es la rotación canónica Este-Norte-Arriba a ECEF
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)
Devuelve la distancia
distance({geo,stbox,pose},pose) → float
distance(pose,{geo,stbox,pose}) → float
{geo,stbox,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(distance(stbox 'STBOX X((1,-1),(3,1))', pose 'Pose(Point(4 0),0)'), 6); -- 1 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
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 {=, <>, <, >, <=, >=} pose
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 las poses aproximadamente iguales con respecto a un valor épsilon?
pose ~= pose → boolean
SELECT pose 'Pose(SRID=5676;Point(1 1), 0.3)' ~= pose 'Pose(SRID=5676;Point(1 1.0000001), 0.30000001)'; -- true