mobilitydb
mobilitydb : MobilityDB geospatial trajectory data management & analysis platform
Overview
| ID | Extension | Package | Version | Category | License | Language |
|---|---|---|---|---|---|---|
| 1650 | mobilitydb | mobilitydb | 1.3.0 | GIS | GPL-3.0 | C |
| Attribute | Has Binary | Has Library | Need Load | Has DDL | Relocatable | Trusted |
|---|---|---|---|---|---|---|
--s-d-r | No | Yes | No | Yes | yes | no |
| Relationships | |
|---|---|
| Requires | postgis |
| Need By | mobilitydb_datagen |
| See Also | pgrouting h3_postgis timescaledb postgis_topology postgis_raster postgis_sfcgal postgis_tiger_geocoder address_standardizer |
| Siblings | mobilitydb_datagen |
need another schema
Packages
| Type | Repo | Version | PG Major Compatibility | Package Pattern | Dependencies |
|---|---|---|---|---|---|
| EXT | PGDG | 1.3.0 | 18 17 16 15 14 | mobilitydb | postgis |
| DEB | PGDG | 1.3.0 | 18 17 16 15 14 | postgresql-$v-mobilitydb | - |
| Linux / PG | PG18 | PG17 | PG16 | PG15 | PG14 |
|---|---|---|---|---|---|
el8.x86_64 | MISS | MISS | MISS | MISS | MISS |
el8.aarch64 | MISS | MISS | MISS | MISS | MISS |
el9.x86_64 | MISS | MISS | MISS | MISS | MISS |
el9.aarch64 | MISS | MISS | MISS | MISS | MISS |
el10.x86_64 | MISS | MISS | MISS | MISS | MISS |
el10.aarch64 | MISS | MISS | MISS | MISS | MISS |
d12.x86_64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
d12.aarch64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
d13.x86_64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
d13.aarch64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
u22.x86_64 | MISS | PGDG 1.2.0 | PGDG 1.2.0 | PGDG 1.2.0 | PGDG 1.2.0 |
u22.aarch64 | MISS | PGDG 1.2.0 | PGDG 1.2.0 | PGDG 1.2.0 | PGDG 1.2.0 |
u24.x86_64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
u24.aarch64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
u26.x86_64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
u26.aarch64 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 | PGDG 1.3.0 |
Source
Install
Make sure PGDG repo available:
pig repo add pgdg -u # add pgdg repo and update cacheInstall this extension with pig:
pig install mobilitydb; # install via package name, for the active PG version
pig install mobilitydb -v 18; # install for PG 18
pig install mobilitydb -v 17; # install for PG 17
pig install mobilitydb -v 16; # install for PG 16
pig install mobilitydb -v 15; # install for PG 15
pig install mobilitydb -v 14; # install for PG 14Create this extension with:
CREATE EXTENSION mobilitydb CASCADE; -- requires postgisUsage
Sources: repo README, MobilityDB 1.3 manual, v1.3.0 release
MobilityDB extends PostgreSQL and PostGIS with temporal and spatio-temporal data types, enabling efficient storage, indexing, and querying of moving object data such as vehicle trajectories, sensor readings, and time-varying attributes.
Key Documentation:
- MobilityDB Manual
- Temporal Types
- Spatial-Temporal Types
- Temporal Poses
- Temporal Circular Buffers
- Indexing
- MobilityDB Workshop
- API Reference
Getting Started
MobilityDB requires PostGIS. Enable both extensions:
CREATE EXTENSION postgis;
CREATE EXTENSION mobilitydb;Temporal Types
MobilityDB provides temporal variants of base types:
| Temporal Type | Base Type | Description |
|---|---|---|
tbool | boolean | Time-varying boolean |
tint | integer | Time-varying integer |
tfloat | float | Time-varying float |
ttext | text | Time-varying text |
tgeometry | geometry | Time-varying arbitrary geometry |
tgeography | geography | Time-varying arbitrary geography |
tgeompoint | geometry(Point) | Time-varying geometric point |
tgeogpoint | geography(Point) | Time-varying geographic point |
tnpoint | network point | Time-varying network point |
tcbuffer | circular buffer | Time-varying circular buffer |
tpose | pose | Time-varying point position and orientation |
trgeometry | rigid geometry | Time-varying rigid geometry |
MobilityDB 1.3 adds tgeometry, tgeography, tcbuffer, tpose, and trgeometry. tgeometry and tgeography support discrete or step interpolation, not linear interpolation of arbitrary geometries. The 1.3 release notes mark tcbuffer, tpose, and trgeometry as experimental.
Temporal Subtypes
Each temporal type can be represented in different subtypes depending on how values change over time:
| Subtype | Description | Example |
|---|---|---|
| Instant | Single value at a single timestamp | '25.5@2025-01-01 08:00' |
| Sequence | Continuous values over a time interval | '[25.5@08:00, 28.1@09:00, 30.0@10:00]' |
| SequenceSet | Set of non-overlapping sequences | '{[25.5@08:00, 28.1@09:00], [30.0@11:00, 31.2@12:00]}' |
Sequences use brackets to indicate inclusive [ or exclusive ( bounds, just like PostgreSQL range types.
Creating Temporal Values
Instant values:
SELECT tfloat '25.5@2025-06-01 08:00:00+00';
SELECT tgeompoint 'SRID=4326;Point(2.3522 48.8566)@2025-06-01 08:00:00+00';Sequence values (continuous interpolation):
SELECT tfloat '[20.0@2025-06-01 08:00, 25.5@2025-06-01 09:00, 22.0@2025-06-01 10:00]';Discrete sequences (stepwise interpolation):
SELECT tint 'Interp=Step;[10@2025-06-01 08:00, 20@2025-06-01 09:00, 15@2025-06-01 10:00]';SequenceSet values:
SELECT tfloat '{[20.0@08:00, 25.5@09:00], [22.0@11:00, 28.0@12:00]}';Constructing from components:
SELECT tgeompoint_inst(ST_Point(2.3522, 48.8566, 4326), '2025-06-01 08:00+00');
SELECT tgeompoint_seq(ARRAY[
tgeompoint_inst(ST_Point(2.3522, 48.8566, 4326), '2025-06-01 08:00+00'),
tgeompoint_inst(ST_Point(2.2945, 48.8584, 4326), '2025-06-01 08:30+00'),
tgeompoint_inst(ST_Point(2.3364, 48.8606, 4326), '2025-06-01 09:00+00')
]);Temporal Operations
Extracting values at a specific time:
SELECT valueAtTimestamp(temp, '2025-06-01 08:30:00+00')
FROM (SELECT tfloat '[20.0@08:00, 30.0@09:00]' AS temp) t;
-- Returns 25.0 (linear interpolation)Restricting to a time period:
SELECT atTime(trip, tstzspan '[2025-06-01 08:00, 2025-06-01 09:00]')
FROM trips;Getting the time span of a temporal value:
SELECT duration(trip), startTimestamp(trip), endTimestamp(trip)
FROM trips;Temporal comparisons:
-- Time periods when temperature exceeded 30 degrees
SELECT atValue(temperature, true)
FROM (SELECT tfloat '[20@08:00, 35@09:00, 25@10:00]' #> 30.0 AS temperature) t;Spatial-Temporal Operations
Trajectory: extract the spatial path as a geometry:
SELECT ST_AsText(trajectory(trip))
FROM trips
WHERE vehicle_id = 42;Speed calculation:
-- Speed in units per second (m/s for geographic points)
SELECT speed(trip)
FROM trips
WHERE vehicle_id = 42;Length of trajectory:
SELECT length(trip)
FROM trips
WHERE vehicle_id = 42;Space-time bounding box (stbox):
-- Get the space-time bounding box
SELECT stbox(trip)
FROM trips;
-- Construct an stbox for querying
SELECT stbox(
ST_MakeEnvelope(2.2, 48.8, 2.4, 48.9, 4326),
tstzspan '[2025-06-01, 2025-06-02]'
);Spatial restriction: values within an area:
-- Portions of a trip within a polygon
SELECT atGeometry(trip, ST_Buffer(ST_Point(2.35, 48.86, 4326), 0.01))
FROM trips;Distance between two temporal points:
SELECT distance(t1.trip, t2.trip)
FROM trips t1, trips t2
WHERE t1.vehicle_id = 1 AND t2.vehicle_id = 2;Nearest approach distance and time:
SELECT nearestApproachDistance(t1.trip, t2.trip),
nearestApproachInstant(t1.trip, t2.trip)
FROM trips t1, trips t2
WHERE t1.vehicle_id = 1 AND t2.vehicle_id = 2;Indexing
MobilityDB supports GiST and SP-GiST indexes for efficient temporal and spatio-temporal queries.
SP-GiST index for temporal types (time dimension):
CREATE INDEX ON measurements USING spgist(temperature);GiST index for spatio-temporal types (space + time):
CREATE INDEX ON trips USING gist(trip);These indexes accelerate bounding box queries, temporal overlap checks, and spatial-temporal intersection:
-- Uses GiST index for space-time filtering
SELECT vehicle_id
FROM trips
WHERE trip && stbox(
ST_MakeEnvelope(2.2, 48.8, 2.4, 48.9, 4326),
tstzspan '[2025-06-01, 2025-06-02]'
);Example: Vehicle Tracking
A complete example storing and querying vehicle GPS trajectories:
CREATE TABLE vehicles (
vehicle_id INT PRIMARY KEY,
plate TEXT,
type TEXT
);
CREATE TABLE trips (
trip_id BIGSERIAL PRIMARY KEY,
vehicle_id INT REFERENCES vehicles(vehicle_id),
trip tgeompoint,
trip_date DATE
);
CREATE INDEX ON trips USING gist(trip);
-- Insert a trip as a sequence of GPS points
INSERT INTO trips (vehicle_id, trip, trip_date) VALUES (
1,
tgeompoint_seq(ARRAY[
tgeompoint_inst(ST_Point(2.3522, 48.8566, 4326), '2025-06-01 08:00+00'),
tgeompoint_inst(ST_Point(2.2945, 48.8584, 4326), '2025-06-01 08:15+00'),
tgeompoint_inst(ST_Point(2.3364, 48.8606, 4326), '2025-06-01 08:30+00'),
tgeompoint_inst(ST_Point(2.3488, 48.8534, 4326), '2025-06-01 08:45+00')
]),
'2025-06-01'
);
-- Where was vehicle 1 at 08:20?
SELECT valueAtTimestamp(trip, '2025-06-01 08:20+00')
FROM trips WHERE vehicle_id = 1 AND trip_date = '2025-06-01';
-- What was the average speed?
SELECT twAvg(speed(trip))
FROM trips WHERE vehicle_id = 1 AND trip_date = '2025-06-01';
-- Total distance traveled
SELECT length(trip)
FROM trips WHERE vehicle_id = 1 AND trip_date = '2025-06-01';
-- Get the full trajectory as a LineString
SELECT ST_AsGeoJSON(trajectory(trip))
FROM trips WHERE vehicle_id = 1 AND trip_date = '2025-06-01';Example: Spatio-Temporal Intersection Query
Find all trips that passed through a specific area during a given time window:
-- Define area of interest: a circle around the Eiffel Tower
WITH area AS (
SELECT ST_Buffer(ST_Point(2.2945, 48.8584, 4326)::geography, 500)::geometry AS geom
)
SELECT t.vehicle_id,
t.trip_date,
atGeometry(t.trip, a.geom) AS trip_in_area,
length(atGeometry(t.trip, a.geom)) AS distance_in_area
FROM trips t, area a
WHERE t.trip && stbox(
a.geom,
tstzspan '[2025-06-01 07:00+00, 2025-06-01 10:00+00]'
)
AND eIntersects(t.trip, a.geom)
ORDER BY t.trip_date;Aggregate Functions
MobilityDB provides temporal aggregates:
-- Time-weighted average of a temporal float
SELECT twAvg(temperature) FROM sensor_data WHERE sensor_id = 1;
-- Merge multiple temporal points into one
SELECT tUnion(trip) FROM trips WHERE vehicle_id = 1 AND trip_date = '2025-06-01';
-- Centroid of a set of temporal points at each timestamp
SELECT tCentroid(trip) FROM trips WHERE trip_date = '2025-06-01';Caveats
- The catalog package and extension are both
mobilitydbversion1.3.0; the packaged matrix targets PostgreSQL 14 through 18 and requirespostgis. - The v1.3.0 release adds PostgreSQL 18 and PostGIS 3.6 support, but its migration note says the binary format changed from MobilityDB 1.2, so upgrades from 1.2 require backup and restore.
- Upstream source-build notes show
shared_preload_libraries = 'postgis-3'andmax_locks_per_transaction = 128before loading MobilityDB. Validate those settings on clusters that are not using packaged defaults. - The local package metadata still carries the curation comment
need another schema; upstream docs did not confirm a separate required schema, so avoid schema-specific guidance until that note is resolved.