Raquet is a cloud-native raster format that stores raster tiles as rows in an Apache Parquet file. Each row holds the pixel bytes for one Web-Mercator tile together with its QUADBIN cell identifier, a 64-bit integer that encodes the tile's zoom level and Morton-interleaved x/y coordinates. No separate spatial metadata is required: the bounding box and pixel-to-coordinate mapping are fully determined by the QUADBIN value.
The typical query pattern joins a trajectory against a Raquet table in two steps:
-- Step 1: identify which tiles the trajectory overlaps SELECT DISTINCT q FROM unnest(quadbins(traj, 8)) AS q; -- Step 2: sample each matching tile SELECT raster_tileValueQuadbin(traj, band_data, width, height, quadbin, 'FLOAT32', nodata, true) FROM elevation_raquet WHERE quadbin = ANY(quadbins(traj, 8));
Return the distinct QUADBIN cells at a zoom level covered by a trajectory
quadbins(tgeompoint,integer) → bigint[]
Returns the set of unique QUADBIN cells (deduplicated) whose Web-Mercator tile envelopes contain at least one instant of traj. The result is suitable as a WHERE-clause join key against a Raquet table. zoom must be in [0, 15].
-- Three instants spanning three tiles at zoom 3
SELECT quadbins(tgeompoint 'SRID=4326;{Point(-60 45)@2024-01-01,
Point(0 45)@2024-01-02, Point(60 45)@2024-01-03}', 3);
-- {5202501994543054848,5203346419473186816,5203416788217364480}
-- Count of Raquet tiles a ship trajectory overlaps at zoom 8
SELECT array_length(quadbins(trip, 8), 1) AS tile_count
FROM trips
ORDER BY tile_count DESC;
Sample a Raquet raster chip along a trajectory using a QUADBIN cell for georeferencing
rasterTileValueQuadbin(tgeompoint,bytea,integer,integer,bigint,text,float8,boolean) → tfloat
Evaluates a row-major single-band pixel array at each instant of traj (SRID 4326). The tile georeferencing (bounding box, pixel-to-coordinate mapping) is derived from quadbin alone via the Web-Mercator slippy-tile transform. The pixtype argument must be one of UINT8, INT16, INT32, FLOAT32, or FLOAT64. When has_nodata is true, instants whose pixel equals nodata are silently dropped. Returns NULL when no instant survives.
-- Sample elevation tiles from a Raquet Parquet table -- for all ship trajectories SELECT t.tripid, rasterTileValueQuadbin(t.trip, r.band_data, r.width, r.height, r.quadbin, 'FLOAT32', r.nodata, true) FROM trips t JOIN elevation_raquet r ON r.quadbin = ANY(quadbins(t.trip, 8)); -- Average sea-surface temperature per trajectory SELECT t.tripid, avgValue(rasterTileValueQuadbin(t.trip, r.band_data, 256, 256, r.quadbin, 'INT16', -9999, true)) AS mean_sst FROM trips t JOIN sst_raquet r ON r.quadbin = ANY(quadbins(t.trip, 6));
Construct a Raquet raster tile from its pixel bytes, dimensions, QUADBIN cell and pixel type
raquet(bytea,integer,integer,bigint,text,float8) → raquet
Packages a row-major single-band pixels array of width × height pixels of type pixtype (one of UINT8, INT16, INT32, FLOAT32, or FLOAT64), georeferenced by the quadbin cell, into a single self-describing raquet value. The nodata argument is optional; when omitted (NULL) the tile carries no nodata sentinel. An error is raised when the pixels array is smaller than width × height × the pixel size. A raquet is a GDAL-free, variable-length value with a portable Hex-WKB text and binary representation, distinct from and coexisting with the PostGIS raster type used by rasterValue.
-- Package the loose tile columns of a Raquet table into raquet values
SELECT raquet(band_data, width, height, quadbin, 'FLOAT32', nodata) AS tile
FROM elevation_raquet;
-- A 2 x 2 UINT8 tile with no nodata
SELECT raquet('\x01020304'::bytea, 2, 2, 5193776270265024512, 'UINT8');
Decode an in-memory raster file into a Raquet raster tile via GDAL
raquetRead(bytea,bigint) → raquet
Reads the bytes of rasterfile, a raster in any format GDAL supports (GeoTIFF, PNG, …), through GDAL's /vsimem/ virtual filesystem, and packs its first band, row-major, into a single self-describing raquet value georeferenced by the quadbin cell. The band data type must be one of Byte, Int16, Int32, Float32, or Float64; the band nodata value, when set, is carried into the tile. Because the file is supplied as bytes, no server-side file access is required. GDAL performs the decode, so the raster's format driver must be permitted by PostGIS's postgis.gdal_enabled_drivers setting (which disables all drivers by default); enable it with, for example, SET postgis.gdal_enabled_drivers = 'ENABLE_ALL'. This is the ingest counterpart of the raquet constructor, which builds a tile from already-decoded pixel bytes.
When quadbin is omitted or NULL, the tile identifier is derived from the raster's georeferencing: the raster must carry an EPSG:3857 (Web-Mercator) spatial reference and an axis-aligned geotransform describing a single QUADBIN tile. A raster with no spatial reference, one that is not in EPSG:3857, or a geotransform that is rotated or not aligned to the tile grid raises an error rather than being coerced.
-- Decode a GeoTIFF stored in a bytea column into a raquet tile SELECT raquetRead(file_bytes, quadbin) AS tile FROM elevation_files; -- Derive the QUADBIN cell from an EPSG:3857 GeoTIFF's georeferencing SELECT raquetRead(file_bytes) AS tile FROM elevation_files;
Sample a raquet raster tile along a trajectory
rasterTileValue(tgeompoint,raquet) → tfloat
Evaluates the tile at each instant of traj (SRID 4326), returning the sampled pixel values as a tfloat. This is the typed equivalent of rasterTileValueQuadbin: the dimensions, QUADBIN cell, pixel type and nodata handling are taken from the raquet value instead of from separate arguments. Returns NULL when no instant falls inside the tile or survives nodata filtering.
-- Sample pre-packaged raquet tiles along ship trajectories SELECT t.tripid, rasterTileValue(t.trip, r.tile) FROM trips t JOIN elevation_tiles r ON r.quadbin = ANY(quadbins(t.trip, 8));
Sample an array of raquet raster tiles along a trajectory
rasterTileValue(tgeompoint,raquet[]) → tfloat
Evaluates every tile of rast at each instant of traj (SRID 4326) and returns the sampled pixel values as a single tfloat. A trajectory that leaves one tile is covered by several of them, each contributing the instants that fall inside it. Tiles of one zoom level partition the plane, so they contribute disjoint instants. Tiles of different zoom levels overlap, and where two of them sample the same instant the value of the tile of higher zoom is kept, that being the one carrying the finer resolution. Returns NULL when no instant falls inside a tile or survives nodata filtering.
-- Sample a trajectory across every tile it crosses, in one value SELECT t.tripid, rasterTileValue(t.trip, array_agg(r.tile)) FROM trips t JOIN elevation_tiles r ON r.quadbin = ANY(quadbins(t.trip, 8)) GROUP BY t.tripid, t.trip;