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 reads a raster band along a moving-point trajectory and returns a tfloat. A position outside the raster extent or on a nodata pixel carries no value. 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?

A Raquet table keeps the QUADBIN cell of a tile in its block column as a 64-bit integer, beside the metadata row at block = 0, which holds no QUADBIN index. A query casts the cells of a trajectory to bigint to read that column, and a cell read from it to quadbin, the cast checking that it is a QUADBIN index. The typical query pattern joins a trajectory against a Raquet table in two steps:

-- Step 1: identify which tiles the trajectory overlaps
SELECT getValues(tquadbin(traj, 8));
-- Step 2: sample each matching tile, a 256 x 256 float32 band without nodata
SELECT rasterTileValueQuadbin(traj, band_1, 256, 256, block::quadbin, 'float32', 0,
  false) FROM elevation_raquet
WHERE block IN (SELECT unnest(getValues(tquadbin(traj, 8)))::bigint);

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.

A raster function takes the name of its PostGIS raster counterpart with the ST_ prefix removed, and the names and defaults of its arguments. One signature answers each operation, so a PostGIS form that only fixes an argument of another is written through that other form. A name the SQL standard reserves takes the type as a prefix, so ST_Value is rasterValue, and the Well-Known Binary functions take the names every MobilityDB type takes.

PostGIS rasterMobilityDB
ST_ValuerasterValue
ST_Clipclip
ST_Transformtransform
ST_Rescalerescale
ST_Reclassreclass
ST_SummaryStatssummaryStats
ST_DumpAsPolygonsdumpAsPolygons
ST_NumBands, ST_Width, ST_Height, ST_SRIDnumBands, width, height, SRID
ST_UpperLeftX, ST_UpperLeftY, ST_ScaleX, ST_ScaleY, ST_SkewX, ST_SkewYupperLeftX, upperLeftY, scaleX, scaleY, skewX, skewY
ST_BandPixelType, ST_BandNoDataValuebandPixelType, bandNoDataValue
ST_AsBinary, ST_AsHexWKBasBinary, asHexWKB
ST_RastFromWKB, ST_RastFromHexWKBrasterFromBinary, rasterFromHexWKB

asBinary and asHexWKB take a byte order where PostGIS takes outasin, and without one answer the bytes of ST_AsBinary and ST_AsHexWKB.

To use the operators described here, MobilityDB must be built with -DQUADBIN=ON and -DRASTER=ON, since a Raquet tile is identified by a quadbin cell. 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 -DQUADBIN=ON and -DRASTER=ON to CMake:

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

The CI builds, .github/workflows/pgversion.yml among them, pass -DALL=ON, which includes raster alongside the other optional families.