Return the temporal cell at the given resolution that contains each point in a temporal geodetic or planar point
th3index(tpoint,integer) → th3index tquadbin(tpoint,integer) → tquadbin ts2cell(tpoint,integer) → ts2cell
SRID must be 4326 for the tgeompoint overloads. The constructor over a temporal point is stated for every grid, over a geodetic and a planar point.
A trajectory that states nothing between its instants, discrete or stepwise, yields the cells holding them and keeps its interpolation; one that moves between them yields every cell it crosses on the way, since the segment is traversed cell by cell rather than sampled. The segment is traversed along the path its point follows: the great circle of a tgeogpoint, so a trajectory crossing the antimeridian or passing near a pole yields the cells along its shortest route, and the straight line in longitude and latitude of a tgeompoint. A great circle bends toward the pole in longitude and latitude, so the arc between two positions in one QUADBIN tile may leave the tile and come back to it. An S2 cell edge is an arc of a great circle, which a straight line in longitude and latitude is not, so that line between two positions in one S2 cell may likewise leave the cell and come back to it. A QUADBIN tile holds its west and north boundaries, so a path through the point where four tiles meet passes through the tile east of the meridian and south of the parallel meeting there. Each instant of the result marks the time the trajectory entered that cell, and the last cell holds to the end of the trajectory, so the result spans its period. Under an exclusive upper bound, a cell the trajectory reaches only at its end, holding it for no time, is not part of the result. Two crossings falling in the same microsecond, the smallest separation a timestamp states, leave the cell entered at that instant: a cell left again before it holds any time is not part of the result. A crossing at an end of a segment is stated at the instant of that end, as the space split of spaceSplit states the tile of a corner, so the cover of a trajectory cut at successive half-open periods merges into the cover of the whole trajectory. The distinct cells of the result, which getValues answers, are the tiles a trajectory covers, the join key of a Raquet table, where a tile the trip crosses and the key omits is a tile the join never reads.
SELECT getResolution(th3index(tgeogpoint 'POINT(-73.96 40.78)@2001-01-01', 9)); -- 9@2001-01-01 SELECT getResolution(th3index(tgeompoint 'SRID=4326;POINT(-73.96 40.78)@2001-01-01', 9)); -- 9@2001-01-01 SELECT getResolution(tquadbin(tgeompoint 'SRID=4326;POINT(-73.96 40.78)@2001-01-01', 9)); -- 9@2001-01-01 SELECT getResolution(tquadbin(tgeogpoint 'POINT(-73.96 40.78)@2001-01-01', 9)); -- 9@2001-01-01 SELECT numInstants(tquadbin(tgeogpoint '[POINT(-170 65)@2001-01-01, POINT(-100 65)@2001-01-02]', 2)); -- 4 SELECT getResolution(ts2cell(tgeogpoint 'POINT(-73.96 40.78)@2001-01-01', 9)); -- 9@2001-01-01 SELECT getResolution(ts2cell(tgeompoint 'SRID=4326;POINT(-73.96 40.78)@2001-01-01', 9)); -- 9@2001-01-01 SELECT numInstants(ts2cell(tgeompoint 'SRID=4326;[POINT(-15 44.5)@2001-01-01, POINT(15 44.5)@2001-01-02]', 0)); -- 4
Split a temporal point at the QUADBIN cells it crosses
quadbinSplit(tpoint,integer) → {(cell,tpoint)}
The cover states which cell a trajectory holds and when. The split states the same cells and, beside each, the trajectory over the periods the cover states for that cell, so a value indexed by cell is read in one pass where the cover alone asks for a restriction per cell. The cells of a split are the cells of the cover, the fragment of a cell is the trajectory restricted to the periods the cover states for it, and the fragments merge into the trajectory. A trajectory reaching a cell at its last instant holds it there for an instant, and the split states that fragment over that instant.
The segment is traversed along the path its point follows, so a geodetic trajectory is split at the cells its great circles cross and a planar one at the cells its straight line in longitude and latitude crosses. The period of a fragment is what getTime answers for it, so the split carries no period of its own.
SELECT (s).cell, asText((s).tpoint, 6) AS tpoint
FROM (SELECT quadbinSplit(tgeompoint
'SRID=4326;[Point(-135 -10)@2001-01-01, Point(-45 10)@2001-01-03]', 2) AS s) t;
-- 4823ffffffffffff | {[POINT(-90 0)@2001-01-02, POINT(-45 10)@2001-01-03]}
-- 4828ffffffffffff | {[POINT(-135 -10)@2001-01-01, POINT(-90 0)@2001-01-02)}
SELECT count(*) FROM quadbinSplit(tgeogpoint
'[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 2);
-- 2
SELECT count(*) FROM quadbinSplit(tgeompoint
'SRID=4326;[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 2);
-- 1
Split a temporal point at the H3 cells it crosses
h3Split(tpoint,integer) → {(cell,tpoint)}
The cover states which cell a trajectory holds and when. The split states the same cells and, beside each, the trajectory over the periods the cover states for that cell, so a value indexed by cell is read in one pass where the cover alone asks for a restriction per cell. The cells of a split are the cells of the cover, the fragment of a cell is the trajectory restricted to the periods the cover states for it, and the fragments merge into the trajectory. The period of a fragment is what getTime answers for it, so the split carries no period of its own.
The segment is traversed along the path its point follows, so a geodetic trajectory is split at the cells its great circles cross and a planar one at the cells its straight line in longitude and latitude crosses. An H3 cell is a hexagon on the sphere, and a great circle is the shortest path between two positions on it, so a geodetic trajectory crosses no more of those cells than the straight line in longitude and latitude between the same positions does.
SELECT (s).cell, asText((s).tpoint, 6) AS tpoint
FROM (SELECT h3Split(tgeompoint
'SRID=4326;[Point(-0.1 51.5)@2001-01-01, Point(0.1 51.5)@2001-01-02]', 4) AS s) t;
-- 84194adffffffff | {[POINT(-0.1 51.5)@2001-01-01, POINT(0.004068 51.5)@2001-01-01 12:29:17.362145)}
-- 84194e7ffffffff | {[POINT(0.004068 51.5)@2001-01-01 12:29:17.362145, POINT(0.1 51.5)@2001-01-02]}
SELECT count(*) FROM h3Split(tgeogpoint
'[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 2);
-- 14
SELECT count(*) FROM h3Split(tgeompoint
'SRID=4326;[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 2);
-- 16
Split a temporal point at the S2 cells it crosses
s2Split(tpoint,integer) → {(cell,tpoint)}
The cover states which cell a trajectory holds and when. The split states the same cells and, beside each, the trajectory over the periods the cover states for that cell, so a value indexed by cell is read in one pass where the cover alone asks for a restriction per cell. The cells of a split are the cells of the cover, the fragment of a cell is the trajectory restricted to the periods the cover states for it, and the fragments merge into the trajectory. The period of a fragment is what getTime answers for it, so the split carries no period of its own.
The segment is traversed along the path its point follows, so a geodetic trajectory is split at the cells its great circles cross and a planar one at the cells its straight line in longitude and latitude crosses. The two paths cross different cells, and the count of them is a property of the trajectory rather than of the grid: the arc from longitude -170 to -100 along latitude 65 crosses as many S2 cells as the straight line between the same positions does, while the cells themselves differ.
SELECT count(*) FROM s2Split(tgeogpoint
'[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 6);
-- 29
SELECT count(*) FROM s2Split(tgeompoint
'SRID=4326;[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 6);
-- 29
SELECT getValues(ts2cell(tgeogpoint
'[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 6))
= getValues(ts2cell(tgeompoint
'SRID=4326;[Point(-170 65)@2001-01-01, Point(-100 65)@2001-01-02]', 6));
-- f
Return the centroid of a cell, or of each cell in a trajectory
cellToPoint({h3index,quadbin}) → geometry
cellToPoint(s2cell) → geography
cellToPoint({th3index,ts2cell}) → tgeogpoint
cellToPoint(tquadbin) → tgeompoint
tgeompoint(th3index) → tgeompoint
The centroid is in SRID 4326, and its type follows the grid. An S2 cell answers a geodetic point, since its edges are arcs of great circles, and a QUADBIN tile a planar one, since the tile is a rectangle in longitude and latitude. An H3 cell answers a planar point and a temporal H3 cell a geodetic one, and tgeompoint answers the same centroid as a planar point, so H3 is the one grid publishing both forms for a trajectory. The operation is named cellToPoint for every grid, the cell_to_point slot of the descriptor being what fixes it.
SELECT ST_AsText(cellToPoint(h3index '871fa44a8ffffff'), 6); -- POINT(4.297401 50.8043) SELECT asText(cellToPoint(th3index '871fa44a8ffffff@2001-01-01'), 6); -- POINT(4.297401 50.8043)@2001-01-01 SELECT asText(tgeompoint(th3index '871fa44a8ffffff@2001-01-01'), 6); -- POINT(4.297401 50.8043)@2001-01-01 SELECT ST_AsText(cellToPoint(quadbin '48a6227affffffff'), 6); -- POINT(4.394531 50.847573) SELECT asText(cellToPoint(tquadbin '48a6227affffffff@2001-01-01'), 6); -- POINT(4.394531 50.847573)@2001-01-01 SELECT ST_AsText(cellToPoint(s2cell '47c3c'), 6); -- POINT(4.222019 50.936164) SELECT asText(cellToPoint(ts2cell '47c3c@2001-01-01'), 6); -- POINT(4.222019 50.936164)@2001-01-01
Return the polygon boundary of a cell, or of each cell in a trajectory
cellToBoundary({h3index,quadbin}) → geometry
cellToBoundary(s2cell) → geography
cellToBoundary({th3index,ts2cell}) → tgeography
cellToBoundary(tquadbin) → tgeometry
The boundary is in SRID 4326, and its type follows the grid as the centroid of cellToPoint does: a geography for S2, a geometry for QUADBIN, and for H3 a geometry for a cell and a geography for a trajectory. The ring closes on its first vertex, so an H3 hexagon carries seven points and a QUADBIN square or an S2 spherical quadrilateral five.
SELECT ST_NPoints(cellToBoundary(h3index '871fa44a8ffffff')); -- 7 SELECT ST_GeometryType(getValue(cellToBoundary(th3index '871fa44a8ffffff@2001-01-01'))::geometry); -- ST_Polygon SELECT ST_NPoints(getValue(cellToBoundary(th3index '871fa44a8ffffff@2001-01-01'))::geometry); -- 7 SELECT ST_GeometryType(getValue(cellToBoundary(tquadbin '48a6227affffffff@2001-01-01'))::geometry); -- ST_Polygon SELECT ST_NPoints(getValue(cellToBoundary(tquadbin '48a6227affffffff@2001-01-01'))::geometry); -- 5 SELECT ST_GeometryType(getValue(cellToBoundary(ts2cell '47c3c@2001-01-01'))::geometry); -- ST_Polygon SELECT ST_NPoints(getValue(cellToBoundary(ts2cell '47c3c@2001-01-01'))::geometry); -- 5