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 Z (1.12 1.12 1. {"[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=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.1, “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 do things like translate, rotate, scale in one step
affine(tgeo,float a, float b, float c, float d, float e, float f, float g,
float h, float i, float xoff, float yoff, float zoff) → tgeo
affine(tgeo,float a, float b, float d, float e, float xoff, float yoff) → 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,float radians) → tgeo
rotate(tgeo,float radians,float x0,float y0) → tgeo
rotate(tgeo,float radians,geometry origin) → 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,float Xfactor,float Yfactor,float Zfactor) → tgeo
scale(tgeo,float Xfactor,float Yfactor) → tgeo
scale(tgeo,geometry factor) → tgeo
scale(tgeo,geometry factor,geometry origin) → 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=4096,buffer=256,clip=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 geometry 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(tgeompoint,maxDist=0.0,minDuration='0 minutes') → tgeompoint
The size of the area is computed as the diagonal of the minimum rotated rectangle of the points in the subsequence. 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. 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]} */