MobilityDB查询完全手册:时空重叠、距离计算与轨迹插值SQL函数大全
【免费下载链接】MobilityDBMobilityDB is a geospatial trajectory data management & analysis platform, built on PostgreSQL and PostGIS.项目地址: https://gitcode.com/gh_mirrors/mo/MobilityDB
MobilityDB 是一个构建在 PostgreSQL 和 PostGIS 之上的时空轨迹数据管理与分析平台。本手册面向新手,系统讲解三大高频查询场景:时空重叠判断(谁在谁附近出现过)、轨迹距离计算(最近接近距离)和轨迹插值(任意时刻位置),帮助你用 SQL 快速上手 MobilityDB 轨迹数据库查询。
🚗 先认识核心类型:TGeomPoint
在写查询之前,先理解 MobilityDB 的轨迹类型体系。一条轨迹由"时间-位置对"(TValue)序列构成,每个值代表某个时刻的一个点。
- tgeompoint:平面坐标系(如 UTM 投影坐标)下的移动点轨迹
- tgeogpoint:地理坐标系(经纬度,米制单位)下的移动点轨迹
- tfloat / tbox / stbox:轨迹上的其他数值和时间-空间包围盒类型
一条轨迹还可以用tstzspan(时间跨度)和stbox(空间包围盒)共同描述它的时间和空间范围,这正是后面所有时空查询的基础。
🕒 时空重叠查询:轨迹经过某区域了吗?
时空重叠是轨迹分析的第一需求:"这条车轨在 8 点到 9 点之间是否穿过公园?"MobilityDB 提供了两类运算符。
时间重叠运算符
轨迹与时间区间(tstzspan)的关系判断,定义见 062_tpoint_posops.in.sql:
| 运算符 | 含义 | 示例语义 |
|---|---|---|
@> | 包含(contains) | 时间区间完全覆盖轨迹 |
<@ | 被包含(contained) | 轨迹完全落在时间区间内 |
& | 重叠(overlap) | 轨迹与时间区间有交集 |
<<#/#>> | 之前 / 之后(strict before / after) | 轨迹严格早于 / 晚于时间区间 |
&<#/#&> | 之前(含端点) / 之后(含端点) | 端点接触也算 |
-- 查询 2024 年 1 月 1 日 8:00-9:00 之间活动的轨迹 SELECT id FROM tpts WHERE tgeom @> '[2024-01-01 08:00+00, 2024-01-01 09:00+00]'::tstzspan;时空拓扑关系函数
当对象是"区域 + 轨迹"时,使用带t前缀的函数(完整清单见 072_tpoint_tempspatialrels.in.sql)。它们返回tbool类型——即"什么时间段内满足该关系",比普通布尔值信息量更大:
| 函数 | 作用 |
|---|---|
tContains(geom, tgeompoint) | 轨迹在何时段完全位于区域内 |
tIntersects(geom, tgeompoint) | 轨迹在何时段与区域相交(经过判断首选) |
tDisjoint(geom, tgeompoint) | 轨迹与区域是否始终不相交 |
tCovers/tTouches | 覆盖 / 仅接触(相切) |
tDwithin(geom, tgeompoint, dist) | 轨迹在何时段距离区域不超过 dist 米 |
-- 找出所有曾进入 100 米缓冲区的路径轨迹 SELECT id FROM tpts WHERE tDwithin('POLYGON((0 0, 0 1000, 1000 1000, 1000 0, 0 0))', tgeom, 100);💡 小技巧:判断"是否经过"只需tIntersects(...) IS TRUE,若想拿到具体时间段,直接保留 tbool 结果即可。
📏 距离计算函数:两条轨迹最近有多近?
距离函数定义在 064_tpoint_distance.in.sql,是事故检测、跟车分析的核心:
| 函数 | 运算符 | 返回类型 | 说明 |
|---|---|---|---|
tDistance(a, b) | <-> | tfloat | 任意时刻两轨迹间的距离变化曲线 |
nearestApproachDistance(a, b) | |=| | float | 最近接近距离(标量,最常用) |
nearestApproachInstant(a, b) | — | tgeompoint | 最近接近时刻与双方位置 |
shortestLine(a, b) | — | geometry | 最近点之间的连线,可用于可视化 |
-- 找出最近距离小于 50 米的轨迹对(潜在碰撞) SELECT a.id, b.id, nearestApproachDistance(a.tgeom, b.tgeom) AS nad FROM tpts a JOIN tpts b ON a.id < b.id WHERE a.tgeom |=| b.tgeom < 50.0;nearestApproachInstant配合shortestLine还能画出"何时何地最接近"的连线,非常适合事故复盘:
SELECT shortestLine(nai1, nai2) FROM nearestApproachInstant(a.tgeom, b.tgeom) LATERAL (SELECT 1) x; -- 实际写法见官方文档示例下图对比了不同距离度量方式(欧氏距离与基于 SED 的度量)在轨迹分析中的差异,帮助你选择合适的度量:
🎯 轨迹插值:任意时刻,车在哪里?
轨迹本质上是离散采样点序列,但tAtTime系列函数可以对轨迹进行连续插值,返回任意时刻的位置——这是 MobilityDB 最有魔法感的查询能力。
核心插值函数
| 函数 | 作用 |
|---|---|
tAtTime(tgeompoint, t) | 轨迹在时刻 t 的插值位置(支持时间戳、时间区间) |
tAtCumLength(tgeompoint, l) | 轨迹在累计里程 l 处的位置 |
tAtLength/tAtTime反向查询 | 已知位置反查时间或里程 |
trajectory(tgeompoint) | 将轨迹投影为普通 LINESTRING,便于 PostGIS 可视化 |
-- 查询 08:30 时所有车辆的位置(插值结果) SELECT id, tAtTime(tgeom, '2024-01-01 08:30:00+00') AS pos FROM tpts; -- 用 PostGIS 渲染整条轨迹线 SELECT id, trajectory(tgeom) FROM tpts;时间区间参数同样支持:tAtTime(tgeom, '[08:00+00, 09:00+00]')会返回该时段内的分段轨迹。
轨迹切割与采样
围绕插值,还有一组"切轨迹"的实用函数(定义见 056_tpoint_spatialfuncs.in.sql):
splitN(tgeom, n)/splitNSegments:把轨迹按段数切分splitNTimes(tgeom, n):把轨迹按时长均分resample:按固定时间间隔重采样length(tgeom)/cumulativeLength(tgeom):轨迹总长与累计里程曲线convexHull(tgeom):轨迹的凸包(活动范围分析)
🧩 组合查询实战:三个典型场景
场景 1:某区域内、某时段内、曾减速到 10km/h 以下的车辆
SELECT id FROM tpts WHERE tIntersects(geom_col, tgeom) IS TRUE -- 空间+时间过滤 AND minSpeed(tgeom) < 2.78; -- 速度分析场景 2:找出与事件点最近接近距离最小的前 10 条轨迹
SELECT id, nearestApproachDistance(tgeom, event_point) AS nad FROM tpts ORDER BY nad LIMIT 10;场景 3:还原两条轨迹的最接近瞬间
SELECT nearestApproachInstant(a.tgeom, b.tgeom) AS nai FROM tpts a, tpts b WHERE a.id = 1 AND b.id = 2;⚡ 性能提示:为轨迹列建立 GIST 时空索引(gist_tgeompoint运算符类,见 073_tpoint_gist.in.sql)后,@>、&、<->等运算可走索引扫描,大表查询提速显著。
📚 函数源码与文档速查
| 类别 | 核心文件 |
|---|---|
| 距离函数 | mobilitydb/sql/geo/064_tpoint_distance.in.sql |
| 时空拓扑关系 | mobilitydb/sql/geo/072_tpoint_tempspatialrels.in.sql |
| 时间/位置运算符 | mobilitydb/sql/geo/062_tpoint_posops.in.sql |
| 包围盒与切分 | mobilitydb/sql/geo/060_tpoint_boxops.in.sql |
| 空间函数 | mobilitydb/sql/geo/056_tpoint_spatialfuncs.in.sql |
| 时空索引 | mobilitydb/sql/geo/073_tpoint_gist.in.sql |
| 时间核心 API 头文件 | meos/include/temporal/temporal.h |
| 时间类型设计笔记 | doc/contributing/new_temporal_type.md |
更多类型(区域轨迹tgeometry、姿态轨迹tpose、轨迹缓冲tcbuffer)都遵循同一套"时间 × 空间"函数模式,掌握本文的tgeompoint用法后,其他类型可无缝迁移。现在打开你的 PostgreSQL 客户端,用CREATE EXTENSION mobilitydb;开始第一条轨迹查询吧!
【免费下载链接】MobilityDBMobilityDB is a geospatial trajectory data management & analysis platform, built on PostgreSQL and PostGIS.项目地址: https://gitcode.com/gh_mirrors/mo/MobilityDB
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考