Skip to content

Sample a raster file along a trajectory through GDAL - #249

Merged
estebanzimanyi merged 2 commits into
MobilityDB:mainfrom
estebanzimanyi:feat/duck-raster-value
Aug 7, 2026
Merged

Sample a raster file along a trajectory through GDAL#249
estebanzimanyi merged 2 commits into
MobilityDB:mainfrom
estebanzimanyi:feat/duck-raster-value

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

MEOS opens a raster in any GDAL-supported format, derives the bounding-box
pre-filter from its geotransform and samples a band at the instants of a
trajectory. MobilityDuck exposes that as five functions, each with and without
an explicit band, in the MobilityDB argument order:

Function Returns
rasterValue(rasterfile, traj[, band]) tfloat — the sampled values
atRasterValue(traj, rasterfile, vspan[, band]) tgeompoint — instants whose pixel is inside the range
minusRasterValue(traj, rasterfile, vspan[, band]) tgeompoint — the complement
eRasterValue(rasterfile, traj, vspan[, band]) boolean — ever inside
aRasterValue(rasterfile, traj, vspan[, band]) boolean — always inside
SELECT rasterValue('elevation.tif', traj) FROM trips;

The trajectory carries the coordinates of the raster's own reference system,
which the geotransform maps to pixels. The ever and always predicates answer
with three-valued logic, so the answer that does not apply is NULL.

Together with the Raquet tile sampling, the raster surface covers both sources:
rasterTileValue samples a tile held in the database, rasterValue samples a
raster file on disk.

test/sql/raster_value.test samples test/data/raster_4326.tif, a 2x2 UINT8
raster holding one value per world quadrant, and covers the per-quadrant values,
the band argument, the restriction and its complement, ever against always, and
the rejected band and path.

The base branch carries the MEOS pin these entry points need.

Full suite green on this commit: 1813 assertions in 78 test cases.

The pin carries the MEOS raster sampling entry points and, with them, four
upstream changes the fixtures have to follow.

minusStbox returns the complement of the corresponding at restriction, so
removing a box that covers [2000-01-01, 2000-01-02] from a three-instant
trajectory leaves the fragment after 2000-01-02 rather than nothing.

An h3index text literal is hexadecimal, as in h3-pg and in MobilityDB's own
288_th3index_compops test; a numeric cell reaches the type through a bigint
cast. A decimal string of more than sixteen digits parses as hexadecimal,
overflows and saturates, so every such literal collapses to the same invalid
cell and unrelated cells compare equal.

pgpointcloud sizes a serialized point as sizeof(SERIALIZED_POINT) - 1 plus the
schema point size, and a serialized patch from the buffer-aligned header, both
of which reserve bytes past the written content: three for a point (12 - 1 + 24
= 35), fifteen for a patch (64 - 1 - 48 = 15). MEOS emits that reserved tail as
zeros, so the literals carry it; without it the tail rule reaches into the last
coordinate.
MEOS opens a raster in any GDAL-supported format, derives the bounding-box
pre-filter from its geotransform and samples a band at the instants of a
trajectory. MobilityDuck exposes that as five functions, each with and without
an explicit band, mirroring the MobilityDB argument order:

  rasterValue(rasterfile, traj[, band])              -> tfloat
  atRasterValue(traj, rasterfile, vspan[, band])     -> tgeompoint
  minusRasterValue(traj, rasterfile, vspan[, band])  -> tgeompoint
  eRasterValue(rasterfile, traj, vspan[, band])      -> boolean
  aRasterValue(rasterfile, traj, vspan[, band])      -> boolean

The trajectory carries the coordinates of the raster's own reference system,
which the geotransform maps to pixels. The ever and always predicates answer
with three-valued logic, so the answer that does not apply surfaces as NULL.

test/sql/raster_value.test samples test/data/raster_4326.tif, a 2x2 UINT8
raster holding one value per world quadrant, and covers the per-quadrant
values, the band argument, the restriction and its complement, ever against
always, and the rejected band and path.
@estebanzimanyi
estebanzimanyi merged commit fd22b49 into MobilityDB:main Aug 7, 2026
9 checks passed
@estebanzimanyi
estebanzimanyi deleted the feat/duck-raster-value branch August 7, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant