Table of Contents
The pose
type is used to represent the location and orientation of geometric objects within coordinate systems anchored to the earth's surface or within other astronomical coordinate systems. The location is represented by a 2D or 3D point. For 2D poses, the orientation is defined by a rotation angle in (-π, π] expressed in radians. For 3D poses, the orientation is defined by four float values W
, X
, Y
, Z
, representing a unit quaternion
where
.
The GeoPose Standards Working Group (SWG), working under the auspices of the Open Geospatial Consortium, has defined a standard for exchanging pose information across different users, devices, and platforms. More information about the standard can be found in the GitHub repository of the GeoPose SWG.
The pose
type serves as base type for defining the temporal pose type tpose
. The tpose
type has similar functionality as the temporal point type tgeompoint
. Thus, most functions and operators described before for the tgeompoint
type are also applicable for the tpose
type. In addition, there are specific functions defined for the tpose
type.
A 2D pose
is a couple of the form (point2D,radius)
where point2D
is a 2D geometric point and radius
is a float
value representing a rotation angle in (-π, π] expressed in radians. A 3D pose
is a tuple of the form (point3D,W,Y,X,Z)
where point3D
is a 3D geometric point, and W
, and X
, Y
, and Z
are four floats
representing a unit quaternion. Examples of input of pose values are as follows:
SELECT pose 'Pose(Point(1 1), 0.5)'; SELECT pose 'Pose(Point Z(1 1 1), 0.5, 0.5, 0.5, 0.5)';
An SRID can be specified for a pose either at the begining of the pose literal or before the point literal as shown below.
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)';
Values of the pose type must satisfy several constraints so that they are well defined. Examples of incorrect pose type values are as follows.
-- 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)';
We give next the functions and operators for the pose type.
Return the Well-Known Text (WKT) or the Extended Well-Known Text (EWKT) representation
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))"}
Return the Well-Known Binary (WKB), the Extended Well-Known Binary (EWKB), or the Hexadecimal Extended Well-Known Binary (HexEWKB) representation
asBinary(pose,endian text='') → bytea
asEWKB(pose,endian text='') → bytea
asHexEWKB(pose,endian text='') → text
The result is encoded using either the little-endian (NDR) or the big-endian (XDR) encoding. If no encoding is specified, then the encoding of the machine is used.
SELECT asBinary(pose 'Pose(Point(1 2),1)'); -- \x0101000000000000f03f0000000000000040000000000000f03f SELECT asEWKB(pose 'SRID=7844;Pose(Point(1 2),1)'); -- \x0141a41e0000000000000000f03f0000000000000040000000000000f03f SELECT asHexEWKB(pose 'SRID=3812;Pose(Point(1 2),1)'); -- 0141E40E0000000000000000F03F0000000000000040000000000000F03F
Input from the Well-Known Text (WKT) or from the Extended Well-Known Text (EWKT) representation
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)
Input from the Well-Known Binary (WKB), from the Extended Well-Known Binary (EWKB), or from the Hexadecimal Extended Well-Known Binary (HexEWKB) representation
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 for poses
pose(geompoint2D,float) → pose
pose(geompoint3D,float,float,float,float) → pose
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)
Values of the pose
type can be converted to the geometry
point type using an explicit CAST
or using the ::
notation as shown below.
Convert a pose and, optionally, a timestamp or a period, into a spatiotemporal box
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])
Convert a pose into geometry point
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)
Return the point
point(pose) → geompoint
SELECT ST_AsText(point(pose 'Pose(Point(1 1), 0.3)')); -- Point(1 1)
Return the rotation
rotation(pose2D) → float
SELECT rotation(pose 'Pose(Point(1 1), 0.3)'); -- 0.3
Return the orientation
orientation(pose3D) → (X,W,Z,T)
SELECT orientation(pose 'Pose(Point Z(1 1 1), 0, 0, 0, 1)'); -- (0, 0, 0, 1)
Return or set the spatial reference identifier
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)
Transform to a spatial reference identifier
transform(pose,integer) → pose
transformPipeline(pose,pipeline text,to_srid integer,is_forward bool=true) → pose
The transform
function specifies the transformation with a target SRID. An error is raised when the input pose has an unknown SRID (represented by 0).
The transformPipeline
function specifies the transformation with a defined coordinate transformation pipeline represented with the following string format:
urn:ogc:def:coordinateOperation:AUTHORITY::CODE
The SRID of the input pose is ignored, and the SRID of the output pose will be set to zero unless a value is provided via the optional to_srid
parameter. As stated by the last parameter, the pipeline is executed by default in a forward direction; by setting the parameter to false, the pipeline is executed in the inverse direction.
SELECT asEWKT(transform(pose 'SRID=4326;Pose(Point(4.35 50.85),1)', 3812), 6); -- SRID=4326;Pose(POINT(648679.018035 671067.055638),1)
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)
The comparison operators (=, <, and so on) are available for poses. Excepted the equality and inequality, the other comparison operators are not useful in the real world but allow B-tree indexes to be constructed on poses.
Traditional comparisons
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
Are the poses approximately equal with respect to an epsilon value?
pose ~= pose → boolean
SELECT pose 'Pose(SRID=5676;Point(1 1), 0.3)' ~= pose 'Pose(SRID=5676;Point(1 1.0000001), 0.30000001)'; -- true