Round the coordinate values to a number of decimal places
round(tspatial,integer=0) → tspatial
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(tgeography 'Linestring(1.12345 1.12345,2.12345 2.12345)@2001-01-01',
2));
-- LINESTRING(1.12 1.12,2.12 2.12)@2001-01-01
Return an array of fragments of the temporal point which are simple
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]}"} */
Construct a geometry/geography with M measure from a temporal point and a temporal float
geoMeasure(tpoint,tfloat,segmentize boolean=false) → geo
The last argument segmentize states whether the resulting value is a either Linestring M or a MultiLinestring M where each component is a segment of two points.
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))
A typical visualization for mobility data is to show on a map the trajectory of the moving object using different colors according to the speed. Figure 7.3, “Visualizing the speed of a moving object using a color ramp in QGIS.” shows the result of the query below using a color ramp in 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)) */
The following expression is used in QGIS to achieve this. The scale_linear function transforms the M value of each composing segment to the range [0, 1]. This value is then passed to the ramp_color function.
ramp_color('RdYlBu', scale_linear(
m(start_point(geometry_n($geometry,@geometry_part_num))), 0, 2, 0, 1) )
Return the 3D affine transform of a temporal geometry to translate, rotate, and/or scale it in a single step
affine(tgeo,a float,b float,c float,d float,e float,f float,g float, h float,i float,xoff float,yoff float,zoff float) → tgeo affine(tgeo,a float,b float,d float,e float,xoff float,yoff float) → tgeo
-- Rotate a 3D temporal point 180 degrees about the z axis SELECT asEWKT(affine(temp, cos(pi()), -sin(pi()), 0, sin(pi()), cos(pi()), 0, 0, 0, 1, 0, 0, 0)) FROM (SELECT tgeompoint '[POINT(1 2 3)@2001-01-01, POINT(1 4 3)@2001-01-02]' AS temp) t; -- [POINT Z (-1 -2 3)@2001-01-01, POINT Z (-1 -4 3)@2001-01-02] SELECT asEWKT(rotate(temp, pi())) FROM (SELECT tgeompoint '[POINT(1 2 3)@2001-01-01, POINT(1 4 3)@2001-01-02]' AS temp) t; -- [POINT Z (-1 -2 3)@2001-01-01, POINT Z (-1 -4 3)@2001-01-02] -- Rotate a 3D temporal point 180 degrees in both the x and z axis SELECT asEWKT(affine(temp, cos(pi()), -sin(pi()), 0, sin(pi()), cos(pi()), -sin(pi()), 0, sin(pi()), cos(pi()), 0, 0, 0)) FROM (SELECT tgeometry '[Point(1 1)@2001-01-01, Linestring(1 1,2 2)@2001-01-02]' AS temp) t; -- [POINT(-1 -1)@2001-01-01, LINESTRING(-1 -1,-2 -2)@2001-01-02]
Return the temporal point rotated counter-clockwise about the origin point
rotate(tgeo,radians float) → tgeo rotate(tgeo,radians float,x0 float,y0 float) → tgeo rotate(tgeo,radians float,origin geometry) → tgeo
-- Rotate a temporal point 180 degrees SELECT asEWKT(rotate(tgeompoint '[Point(5 10)@2001-01-01, Point(5 5)@2001-01-02, Point(10 5)@2001-01-03]', pi()), 6); -- [POINT(-5 -10)@2001-01-01, POINT(-5 -5)@2001-01-02, POINT(-10 -5)@2001-01-03] -- Rotate 30 degrees counter-clockwise at x=5, y=10 SELECT asEWKT(rotate(tgeompoint '[Point(5 10)@2001-01-01, Point(5 5)@2001-01-02, Point(10 5)@2001-01-03]', pi()/6, 5, 10), 6); -- [POINT(5 10)@2001-01-01, POINT(7.5 5.67)@2001-01-02, POINT(11.83 8.17)@2001-01-03] -- Rotate 60 degrees clockwise from centroid SELECT asEWKT(rotate(temp, -pi()/3, ST_Centroid(traversedArea(temp))), 2) FROM (SELECT tgeometry '[Point(5 10)@2001-01-01, Point(5 5)@2001-01-02, Linestring(5 5,10 5)@2001-01-03]' AS temp) AS t; /* [POINT(10.58 9.67)@2001-01-01, POINT(6.25 7.17)@2001-01-02, LINESTRING(6.25 7.17,8.75 2.83)@2001-01-03] */
Return a temporal point scaled by given factors
scale(tgeo,xfactor float,yfactor float,zfactor float) → tgeo scale(tgeo,xfactor float,yfactor float) → tgeo scale(tgeo,factor geometry) → tgeo scale(tgeo,factor geometry,origin geometry) → tgeo
SELECT asEWKT(scale(tgeompoint '[Point(1 2 3)@2001-01-01, Point(1 1 1)@2001-01-02]', 0.5, 0.75, 0.8)); -- [POINT Z (0.5 1.5 2.4)@2001-01-01, POINT Z (0.5 0.75 0.8)@2001-01-02] SELECT asEWKT(scale(tgeompoint '[Point(1 2 3)@2001-01-01, Point(1 1 1)@2001-01-02]', 0.5, 0.75)); -- [POINT Z (0.5 1.5 3)@2001-01-01, POINT Z (0.5 0.75 1)@2001-01-02] SELECT asEWKT(scale(tgeompoint '[Point(1 2 3)@2001-01-01, Point(1 1 1)@2001-01-02]', geometry 'Point(0.5 0.75 0.8)')); -- [POINT Z (0.5 1.5 2.4)@2001-01-01, POINT Z (0.5 0.75 0.8)@2001-01-02] SELECT asEWKT(scale(tgeometry '[Point(1 1)@2001-01-01, Linestring(1 1,2 2)@2001-01-02]', geometry 'Point(2 2)', geometry 'Point(1 1)')); -- [POINT(1 1)@2001-01-01, LINESTRING(1 1,3 3)@2001-01-02]
Transform a temporal geometric point into the coordinate space of a Mapbox Vector Tile
asMVTGeom(tpoint,bounds,extent integer=4096,buffer integer=256, clip boolean=true) → (geom,times)
The result is a couple composed of a geometry value and an array of associated timestamp values encoded as Unix epoch. The parameters are as follows:
tpoint is the temporal point to transform
bounds is an stbox defining the geometric bounds of the tile contents without buffer
extent is the tile extent in tile coordinate space
buffer is the buffer distance in tile coordinate space
clip is a Boolean that determines if the resulting geometries and timestamps should be clipped or not
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}
Extract from a temporal point with linear interpolation the subsequences where the point stays within an area with a specified maximum size for at least the given duration
stops(tpoint,maxdist float=0.0,minduration interval='0 minutes') → tpoint
The size of the area is the greatest distance between two points of the subsequence, which is the quantity the temporal float form of the function reads as the difference between the greatest and the least value it takes. If maxDist is not given it is assumed 0.0 and thus, the function extracts the constant segments of the given temporal point. The distance is computed in the units of the coordinate system for a tgeompoint and in meters on the WGS84 spheroid for a tgeogpoint. Note that even though the function accepts 3D geometries, the computation is always performed in 2D.
SELECT asText(stops(tgeompoint '[Point(1 1)@2001-01-01, Point(1 1)@2001-01-02,
Point(2 2)@2001-01-03, Point(2 2)@2001-01-04]'));
/* {[POINT(1 1)@2001-01-01, POINT(1 1)@2001-01-02), [POINT(2 2)@2001-01-03,
POINT(2 2)@2001-01-04]} */
SELECT asText(stops(tgeompoint '[Point(1 1 1)@2001-01-01, Point(1 1 1)@2001-01-02,
Point(2 2 2)@2001-01-03, Point(2 2 2)@2001-01-04]', 1.75));
/* {[POINT Z (1 1 1)@2001-01-01, POINT Z (1 1 1)@2001-01-02, POINT Z (2 2 2)@2001-01-03,
POINT Z (2 2 2)@2001-01-04]} */