Raster-Specific Operations

The sections above state what a raster shares with the other tessellations. The operations below are the raster's own: a raster cell carries a value where an H3, QUADBIN or S2 cell carries only identity, so a trajectory read against a raster answers a tfloat rather than a temporal cell.

MobilityDB's raster sampling operator evaluates a raster band at the instants of a moving-point trajectory and returns a tfloat. Instants whose position falls outside the raster extent or on a nodata pixel are silently dropped. The sampling operators are double-valued whatever the pixel type of the band, so a pixel type belongs to the sampling surface when every value it can hold is exactly representable in a double precision number. That is what lets a band of any type be sampled into one tfloat, and a column holding tiles of several pixel types be read by a single query. A pixel type is also accepted under the name PostGIS raster gives it, so the band type an ST_BandPixelType call reports (8BUI, 16BSI, 32BF, …) passes into the tile constructors as it stands. PostGIS raster carries no 16-bit float and no 64-bit integer, so float16, int64 and uint64 take the spelling its grammar gives them, 16BF, 64BSI and 64BUI. Its 1BB, 2BUI and 4BUI types bound a pixel to less than a byte while PostGIS stores each of them a byte a pixel, so such a band is already the bytes of an unsigned 8-bit band and the constructors read it as uint8; the bound is the only thing the name adds, and a tile does not carry it. The name a tile reports is the one the RaQuet specification gives the type. The types uint64 and int64 hold values beyond that domain: a tile of either is stored and read back exactly, while sampling a pixel whose value no double precision number names raises an error rather than answering with a neighbouring value. This enables queries such as what elevation profile did each vehicle follow? or which trips entered a temperature threshold band?

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 rasterTileValueQuadbin(traj, band_data, width, height, quadbin, 'float32', nodata,
  true) FROM elevation_raquet WHERE quadbin = ANY(quadbins(traj, 8));

The restriction and predicate operators that close the section compose rasterValue with the standard MobilityDB temporal restriction and predicate functions. They accept an optional band argument (default 1) and call rasterValue exactly once per invocation.

To use the operators described here, MobilityDB must be built with -DRASTER=ON. On such a build the generated mobilitydb.control declares requires = 'postgis, postgis_raster', so a single CASCADE creates the full stack:

CREATE EXTENSION mobilitydb CASCADE;
-- NOTICE:  installing required extension "postgis"
-- NOTICE:  installing required extension "postgis_raster"

PostGIS raster is part of the standard postgresql-N-postgis-3 package on Debian/Ubuntu; no extra package is required. Pass -DRASTER=ON to CMake:

cmake -DRASTER=ON ..
make -j$(nproc)
sudo make install

To include raster in the CI coverage build alongside other optional families, add -DRASTER=ON to the cmake invocation in .github/workflows/pgversion.yml.