基于Ganos轨迹引擎的运输车辆到达性分析

简介: 本文介绍了由阿里巴巴达摩院数据库与存储实验室研发的多模态时空数据库Ganos轨迹引擎在运输车辆位置分析中的应用场景。Ganos通过在数据库中原生内置移动对象的存储、检索与分析能力,打造了全球首个移动对象数据库,为交通、物流、出行、生活服务类客户提供海量轨迹数据的分析挖掘能力。通过阅读本文,用户可以更好的理解Ganos轨迹模型的存储结构与轨迹引擎的相关能力,助力业务开发走向便捷。

能力介绍

关于Ganos

Ganos是阿里云数据库产品事业部联合阿里巴巴达摩院数据库与存储实验室联合共同研发的新一代云原生位置智能引擎,它将时空数据处理能力融入了云原生关系型数据库PolarDB、云原生多模数据库Lindorm、云原生数据仓库AnalyticDB和云数据库RDS PG等核心产品中。Ganos目前拥有几何、栅格、轨迹、表面网格、体网格、3D实景、点云、路径、地理网格、快显十大核心引擎,为数据库构建了面向新型时空多模多态数据的一体化表达、存储、查询与分析计算能力。

本文介绍的轨迹引擎能力,依托阿里云云原生关系型数据库PolarDB、云原生数据仓库AnalyticDB和云数据库RDS PG建设输出。

关于轨迹模型

轨迹模型是Ganos时空数据库中一个重要的模型,用来支持行人、汽车、船只、飞机等移动对象的处理和分析。轨迹数据在应用上有两种视角,一种是离散的点,将轨迹视为一个点集并进行操作;另一种是连续的线,将轨迹视为一条空间中随时间变化的折线。两种表示各有其适用的范围,连续的轨迹线对采样频率不敏感,可以当作折线进行各类的空间运算;离散的轨迹点虽然对采样方式、采样频率更敏感,但对算法来说更加友善和简单,常见的相似度计算、轨迹切分等函数,都是基于对点的操作。

time

x

y

speed

2020-04-11 17:42:30

114.35

39.28

4.3

2020-04-11 17:43:30

114.36

39.28

4.8

2020-04-11 17:45:00

114.35

39.29

3.5


轨迹常用的操作

在实际的使用中,常常出现需要轨迹的采样点满足一定条件的情况。例如:

  1. 实时数据的存储

搭载了GPS的汽车、共享单车等交通工具,其轨迹点的产生频率是非常快的——可能每1-5秒就会产生一个新的采样点。实时的轨迹点在实时检测场景中非常有用,然而当轨迹点数量过多后,中间每个点所提供的信息实际上并不多,但会挤占大量的存储空间。此时,我们希望去除掉一些轨迹点,使得尽可能保有轨迹信息的情况下,降低存储空间。

  1. 轨迹数据的预处理

在实际场景中,常常会由于各种原因带来采样数据不准确的情况。非人为的因素包括定位系统的误差,信号传递质量的不稳定,设备的损坏等;人为因素包括手动关闭采样,或在不进行采样时挪动物体等。在这些情况下,经常需要对轨迹上的特殊点:如漂移点,驻留点,跳跃点进行特殊处理。

  1. 轨迹特征提取

业务上,很多时候不仅直接使用轨迹,同时还需要提取轨迹的一些特征信息。最基础的特征信息包括长度、点数、时间范围等,而高阶的特征则包括轨迹间的相似度,密度聚类的聚簇位置等等。在很多高阶特征计算时,使用的都是离散的近似算法,例如DTW,LCSS,EDR等等距离。而此类算法对上述我们提到的轨迹简化、采样不准问题常常比较敏感,使用简化后的轨迹或采样不均匀的轨迹都会造成结果的差异。因此,我们常常需要对轨迹进行重新采样,使得点与点之间的时间或空间差值趋于均匀。

使用场景

场景概述

交通运输公司每天管理着大量的运输车辆,车辆上安装有GPS信息可以每间隔数秒获取实时位置,同时车辆位置信息与车辆状态信息、车辆运输单信息等业务数据进行关联,后续开展深度的轨迹分析与挖掘,主要的应用场景包括:

  1. 轨迹存储查询与展示:运输车辆的轨迹数据主要包含运输单、经度、维度、时间这四个字段,推送频次为每5秒一个点,正常情况下一个公司每天有成百数千辆车同时在途,每天约有千万级轨迹数据写入;获取到轨迹数据后需要进行轨迹预处理(压缩、抽稀等),并将结果显示在业务系统上
  2. 到达性分析:为了保证运输车辆的及时到达,往往会在地图上设置多个电子围栏(如高速路出口等重要位置),如果在某个时间点还没触碰到这个电子围栏,那么就意味着该车有可能在规定的时间内不能把货物送到客户手中,就要触发预警通知相关工作人员处理
  3. 停留点分析:长途运输车辆往往需要中途休息,为了避免驾驶人员开夜车造成可能的安全隐患,需要监管运输车辆是否在夜间存在停留点(即大量的轨迹没有空间位置上的移动),如果在夜间时间段内停留点没有产生,则需要提醒驾驶员尽快休息
  4. 轨迹相似度:运输车队有部分车辆发生了位置偏离,可能由于车辆驶入了错误的路线,造成货运出现到达性风险,需要根据多个车辆轨迹的相似情况,寻找异常轨迹,及时发现可能的风险


功能分析

为实现上述场景,可能需要针对车辆轨迹进行预处理、分析与压缩,最终支持前端展示,可能用到的主要功能包括:

  1. 轨迹切分(ST_Split):使用用几何对象将一条轨迹切分为多条子轨迹,可以帮助业务把一辆运输车的总体轨迹按不同的运货单切开
  2. 轨迹构造(ST_append):向一条轨迹中不断追加新的轨迹点而获取到全新的轨迹对象,可以帮助业务实时构造不断变长的轨迹
  3. 轨迹空间关系判断(ST_2DIntersects):判断轨迹是否与几何对象相关,可以帮助业务分析在相关时间段是否触碰到了电子围栏的规定范围
  4. 轨迹驻点(ST_StayPoint):提取轨迹的停留点,可以帮助业务判断在任意时间段内车辆的停留时长从而判断是否存在疲劳驾驶的行为
  5. 轨迹简化(ST_Compress):压缩轨迹,可以帮助业务根据空间距离偏移阈值、角度偏离阈值、加速度偏离阈值等方式进行压缩,以减少最终渲染的数据量

技术实现

创建扩展

连接数据库,执行以下SQL语句,创建ganos_trajectory扩展。

CREATE EXTENSION ganos_spatialref;
CREATE EXTENSION ganos_geometry;
CREATE EXTENSION ganos_trajectory;

轨迹表配置

配置轨迹点表,轨迹表,电子围栏表

-- 定义轨迹点表,包含运输单号、经度、纬度、时间四个字段
CREATE TABLE bill_point(id integer, longitude double precision, latitude double precision, sample_time timestamp);
-- 定义轨迹表, 包含运输单号、轨迹对象两个字段
CREATE TABLE bill_traj(id integer UNIQUE, traj trajectory);
--创建空间索引
CREATE INDEX ON bill_traj USING gist(traj);
-- 定义电子围栏表,包含围栏查询的id,时间和空间范围
CREATE TABLE fence(id integer, fence_time timestamp, area geometry);
-- 建立id和时间索引
CREATE INDEX ON fence USING btree(id);
CREATE INDEX ON fence USING btree(fence_time);
-- 创建Trigger函数
CREATE OR REPLACE FUNCTION trajectory_sync_point() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO bill_traj
SELECT NEW.id, ST_MakeTrajectory(array_agg(ROW(NEW.sample_time, NEW.longitude, NEW.latitude)), false, '{}'::cstring[])
ON CONFLICT(id) DO UPDATE
  SET traj = ST_Append(bill_traj.traj, excluded.traj);
RETURN NULL;
END;
$$
LANGUAGE plpgsql STRICT PARALLEL SAFE;
-- 创建同步Trigger
CREATE TRIGGER point_trigger AFTER INSERT ON bill_point
    FOR EACH ROW EXECUTE PROCEDURE trajectory_sync_point();

通过点表插入数据并执行电子围栏查询

通过在点表插入点,在轨迹表中构造出轨迹数据

-- 向点表插入id为1的轨迹数据
INSERT INTO bill_point VALUES (1, 2, 2, '2000-01-01 00:01:00'), (1, 2.1, 2, '2000-01-01 00:02:00'), (1, 2.2, 2, '2000-01-01 00:03:00');
-- 从轨迹表中查询,确认点表的新的点已经成功同步到轨迹表
SELECT * from bill_traj;
-- 查看id为1的轨迹中的所有点
select f.* from (select traj from bill_traj where id = 1) a, ST_AsTable(a.traj) as f(t timestamp,x double precision, y double precision);

对轨迹表中的轨迹数据执行实时的电子围栏查询

-- 设置电子围栏,这里我们设置为:在2000-01-01 00:05:00通过一个经度在 2.3,纬度在2附近的区域
INSERT INTO fence VALUES(1, '2000-01-01 00:05:00', ST_MakeEnvelope(2.29,1.99,2.31,2.01)); 
-- 我们假设业务上每隔一分钟执行一次电子围栏的扫描,则使用下列语句。
-- now() >= fence.fence_time AND now() - '60 s'::interval < fence.fence_time 这里我们因为一分钟执行一次,因此只截取在这一分钟需要判断的fence。这里使用当前的时间减去fence设定的时间,小于1分钟则代表我们目前需要对此fence进行判断
-- fence.id = bill_traj.id 提取对应的轨迹
-- ST_EndTime(bill_traj.traj) >= fence.fence_time 代表确认轨迹的末尾已经超过此时间
-- ST_2DIntersects(bill_traj.traj, fence.area)检查相交
-- 此时没有因为迟到而触发电子围栏的查询,返回空
SELECT fence.id FROM fence JOIN bill_traj ON now() >= fence.fence_time AND now() - '60 s'::interval < fence.fence_time AND fence.id = bill_traj.id AND ST_EndTime(bill_traj.traj) >= fence.fence_time AND NOT ST_2DIntersects(bill_traj.traj, fence.area);
-- 新插入一个点,此时轨迹的时间到达了电子围栏的设定时间,此点不在围栏范围内,触发电子围栏
INSERT INTO bill_point VALUES (1, 2.25, 2, '2000-01-01 00:05:00');
-- 查看此时id为1的轨迹的点
select f.* from (select traj from bill_traj where id = 1) a, ST_AsTable(a.traj) as f(t timestamp,x double precision, y double precision);
-- 现在我们假设当前时间是2000-01-01 00:05:00。执行下列语句,查询所有fence是否被触发;此时发现id为1的电子围栏被触发,说明对应的车辆已经迟到
SELECT fence.id FROM fence JOIN bill_traj ON fence.id = bill_traj.id AND ST_EndTime(bill_traj.traj) >= fence.fence_time AND NOT ST_2DIntersects(bill_traj.traj, fence.area);
-- 此时又输入了一个新增轨迹点,其空间上进入了电子围栏,说明此时此车辆已经经过指定地点。此时再进行查询,就发现没有电子围栏被触发,所有车辆状态正常
INSERT INTO bill_point VALUES (1, 2.3, 2, '2000-01-01 00:06:00');
SELECT fence.id FROM fence JOIN bill_traj ON fence.id = bill_traj.id AND ST_EndTime(bill_traj.traj) >= fence.fence_time AND NOT ST_2DIntersects(bill_traj.traj, fence.area);
-- 查看此时id为1的轨迹的点
select f.* from (select traj from bill_traj where id = 1) a, ST_AsTable(a.traj) as f(t timestamp,x double precision, y double precision);
-- 轨迹点继续输入,离开电子围栏,但不再影响电子围栏是否被触发
INSERT INTO bill_point VALUES (1, 2.3, 2.1, '2000-01-01 00:07:00');
INSERT INTO bill_point VALUES (1, 2.2, 1.9, '2000-01-01 00:08:00');


直接构造轨迹数据并求取其驻点

接下来我们不通过点表,而是直接在轨迹表中构造一条较长的轨迹数据

--根据分别指定轨迹的时间,空间对象来创建轨迹
INSERT INTO bill_traj SELECT
2, ST_makeTrajectory ('STPOINT'::leaftype, 'LINESTRING(0 0,1 1,2 2,2 2,2 2,2 3,3 4,2 4,2 3,2 3,2 3,2 2,2 1,2 0,1 0,0 0,-1 0)'::geometry, '{"2000-01-01 00:12:34","2000-01-01 00:23:37","2000-01-01 00:34:41","2000-01-01 00:45:45","2000-01-01 00:56:48","2000-01-01 01:07:52","2000-01-01 01:18:56","2000-01-01 01:30:00","2000-01-01 01:41:03","2000-01-01 01:52:07","2000-01-01 02:03:11","2000-01-01 02:14:14","2000-01-01 02:25:18","2000-01-01 02:36:22","2000-01-01 02:47:25","2000-01-01 02:58:29","2000-01-01 03:09:33"}'::timestamp[], NULL);

我们通过对轨迹的驻留点检测,可以得知一个车辆是否进行了足够的休息,或是在哪里休息。

-- 获取id为2的轨迹的驻留点。
-- 其中,第一个参数代表轨迹,第二个参数代表对轨迹按5分钟为采样间距进行采样,第三个参数和第四个参数代表将距离在0.1以内,时间差在15分钟以内的点视为临近点,第五个参数代表一个点的临近点数量超过3个就确定其在此处驻留
SELECT ST_StayPoint(traj, '5 minute', 0.1, '15 minute', 3) from bill_traj where id =2 ;

此函数返回了两个驻留点,

st_staypoint                                       
------------------------------------------------------------------------------------------
 (010100000000000000000000400000000000000040,"2000-01-01 00:34:41","2000-01-01 00:56:48")
 (010100000000000000000000400000000000000840,"2000-01-01 01:41:03","2000-01-01 02:03:11")

业务上,我们可以进一步对此结果进行加工

-- 获取两个驻留点的位置
SELECT ST_AsText((ST_StayPoint(traj, '5 minute', 0.1, '15 minute', 3)).point) from bill_traj where id =2 ;
-- 检查此轨迹的驻留(休息)总时长是否超过30分钟。如果没超过,可能代表其疲劳驾驶
SELECT SUM(duration) >= '30 minute'::interval FROM (SELECT (ST_StayPoint(traj, '5 minute', 0.1, '15 minute', 3)).endt - (ST_StayPoint(traj, '5 minute', 0.1, '15 minute', 3)).startt as duration  from bill_traj where id =2 ) staytime;


轨迹简化

对于点数较多的轨迹点,我们可以使用ST_Compress函数对其进行简化,以便后续的显示。

-- 获取简化后的轨迹,可以看到,id为2的轨迹简化后由17个点简化为7个点。参数0.2代表简化后的轨迹距离原轨迹最大距离为0.2。此简化后的轨迹可以用于前端显示。
select ST_Compress(traj, 0.2) from bill_traj;
-- 查看简化后的id为2的轨迹的所有采样点
select f.* from (select traj from bill_traj where id = 2) a, ST_AsTable(ST_Compress(a.traj, 0.2)) as f(t timestamp,x double precision, y double precision);


总结

Ganos轨迹引擎提供了一组云原生的移动对象数据类型、函数和存储过程,帮助用户高效地管理、查询和分析时空轨迹数据。相较于传统方案,Ganos的轨迹引擎拥有原生数据类型与空间索引,查询效率很高。同时,引擎提供了诸如轨迹构造、轨迹处理、轨迹属性、轨迹事件、轨迹空间关系、轨迹时空关系、轨迹统计、轨迹量测、轨迹相似度等十多大类数百个算子,易用性很强。目前,Ganos轨迹引擎在交通运输、快递物流、快捷出行、生活服务、公共安全等领域有十分完整的能力供给与应用案例,服务了多类客户群体,为客户智能化位置服务应用提供了稳定高效健全的时空基底保障。


感谢阿里云DataV数据可视化团队对本文的大力支持,DataV已经可以接入Ganos轨迹引擎,实现海量移动对象的高效渲染,并与Ganos形成了联合解决方案,欢迎各位用户体验

相关文章
|
1月前
|
存储 人工智能 运维
让 Agent 越用越准、成本越来越低:AgentLoop 的 Agent 经验自进化闭环
企业 Agent 上线后,如何在不重新训练模型的情况下提升准确率、稳定性并优化单位成功成本?本文介绍 AgentLoop 如何基于真实运行轨迹自动生成可复用经验,通过 Skill 和 CLI 按需召回,并给出控制台接入步骤及与 Memory、RAG、微调、RL 的差异。
287 1
|
SQL 存储 数据可视化
Ganos H3地理网格能力解析与最佳实践
本文介绍了Ganos H3的相关功能,帮助读者快速了解Ganos地理网格的重要特性与应用实践。H3是Uber研发的一种覆盖全球表面的二维地理网格,采用了一种全球统一的、多层次的六边形网格体系来表示地球表面,这种地理网格技术在诸多业务场景中得到广泛应用。Ganos不仅提供了H3网格的全套功能,还支持与其它Ganos时空数据类型进行跨模联合分析,极大程度提升了客户对于时空数据的挖掘分析能力。
|
SQL 存储 分布式计算
MaxCompute元数据使用实践--项目信息统计
MaxCompute的租户级别Information Schema从租户角度提供项目元数据及使用历史数据等信息,您可以一次性拉取您同一个元数据中心下所有Project的某类元数据,从而进行各类元数据的统计分析。
1526 2
|
人工智能 弹性计算 编解码
技术分享 | 如何基于阿里云AIACC加速Stable-Diffusion AI绘画
AIACC是基于阿里云IaaS资源推出的神龙AI性能加速套件,用于优化基于AI主流计算框架搭建的模型,能显著提升训练和推理性能。AIACC神龙AI推理加速套件由AIACC-Torch(Pytorch推理加速引擎)、AIACC-MLIR(MLIR推理加速引擎)、AIACC-HRT(AIACC算子深度加速引擎)等组件构成。AIACC神龙AI性能加速套件能够为Stable-Diffusion提供加速优化支持,在512x512分辨率下,可将单张图片的延迟从2秒降低至0.88秒,吞吐提速至原来的2.2倍。
技术分享 | 如何基于阿里云AIACC加速Stable-Diffusion AI绘画
|
存储 算法 Cloud Native
Ganos地理网格引擎支撑无人机路径规划能力实践
随着新能源技术的迅猛发展,低空经济已经逐步成为新的战略性新兴产业,但不同于传统的地表活动,低空活动具有立体性、区域性、融合性等特点,这些特点对于如何安全引导低空活动的顺利开展带来了一系列需要解决的技术问题。Ganos地理网格引擎提供了基于网格的路径规划能力,可以使用DEM、DSM、倾斜摄影等数据构建复杂环境下的无人机路径规划应用。
|
安全 网络安全 数据安全/隐私保护
Cisco-网络地址转换动态NAT
Cisco-网络地址转换动态NAT
384 1
|
Cloud Native 前端开发 关系型数据库
Ganos实时热力聚合查询能力解析与最佳实践
本文主要介绍Ganos实时热力聚合查询并动态输出热力瓦片能力,依托阿里云PolarDB PostgreSQL产品、ADB PostgreSQL和RDS PostgreSQL 三款数据库建设输出。
|
存储 SQL 数据可视化
Ganos三维引擎系列(一):倾斜摄影数据管理与可视化功能解析
本文介绍了阿里云多模态时空数据库Ganos三维引擎在倾斜摄影数据管理中的应用。Ganos三维引擎支持三大类存储结构:表面网格模型、体网格模型与3D实景模型,其中表面网格模型用于存储带有语义的类BIM精细化三维模型,体网格模型用于存储地质体等非匀质“场”类三维模型,3D实景模型用于存储倾斜摄影、精白模等用于渲染的三维模型,三种存储结构都提供了原生数据类型、空间索引、分析算子、导入导出工具、可视化支撑等功能,为数字孪生类应用提供闭环的存算显能力,本文重点介绍基于3D实景模型开展倾斜摄影数据管理与可视化等功能。
|
存储 机器学习/深度学习 算法
Ganos轨迹采样点常用处理方法解析
本文介绍了Ganos轨迹引擎的采样点处理能力,包含轨迹过滤、轨迹切分、轨迹重采样和轨迹简化等,帮助用户快速掌握移动对象的预处理方法,提升业务开发的便捷性。
|
SQL 分布式计算 运维
面向未来的开源 OLAP 技术架构探讨以及选型实践
本文详细介绍了开源大数据OLAP的演化过程和最佳实践。
10901 57