需要统计出轨迹点出入某个区域的信息,包括:驶入时间、驶出时间

简介: Lindorm Ganos 通过内置的 `ST_TrajectoryProfile` 算子高效统计轨迹的出入信息,利用时空索引技术减少扫描量和内存使用,降低计算成本。它通过空间索引+过滤下推减少扫描量,聚合加速提升效率,并在聚合算子内部完成进出点判断和轨迹信息提取。然而,该算子受限于时间阈值设定,可能在轨迹点不均匀采集时产生误差。测试环境下,查询耗时在20秒内,具体表现取决于过滤后的数据量和空间范围复杂度。

ST_TrajectoryProfile算子
Lindorm Ganos 通过内置ST_TrajectoryProfile来高效的实现出入信息的统计。利用其原生实现的时空索引技术,可有效过滤掉大多数不在查询范围内的数据,减少扫描量、内存使用量,降低计算代价,从而可以有效解决上述的三个问题。具体的解决方法包括:

  1. 利用空间索引+过滤下推,减少扫描量,减少存储层与查询节点间的数据传输。降低数据库IO,减轻查询节点的内存、计算压力;
  2. 聚合加速:分组聚合计算并行进行,并将部分聚合逻辑下推到数据所在节点,减少查询节点内存和计算压力,提高聚合效率;
  3. 进出点计算封装:在聚合算子内部完成进出点的判断和轨迹段进出信息提取,减少业务层操作,使用方便
    使用限制:由于在聚合操作前,1、2两步已经过滤掉了不在查询区域范围内的轨迹点,在进行出入点判断时,也就无法知道在查询范围以外的数据信息,因此对轨迹出入的判断有以下几个局限性:
    1)划分轨迹段的条件依赖于时间阈值的设定,仅在轨迹点均匀采集点的情况下完全没有误差。对于中断采样情况,需要对返回结果进行额外的业务判断
    2)对于出点,只能给出离开区域范围前的最后一个点,需要根据返回数据另外查询离开区域范围后的第一个点
    使用示例
    上述方案由Lindorm Ganos时空引擎的ST_TrajectoryProfile函数实现,函数具体说明详见ST_TrajectoryProfile
    测试表结构
    +-------------------+--------------+-------------------------------------+---------+----------------+------------+
    | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | TYPE | IS_PRIMARY_KEY | SORT_ORDER |
    +-------------------+--------------+-------------------------------------+---------+----------------+------------+
    | default | test | device_code | VARCHAR | true | ASC |
    | default | test | collect_time | BIGINT | true | ASC |
    | default | test | create_time | BIGINT | true | ASC |
    | default | test | latitude | DOUBLE | false | none |
    | default | test | longitude | DOUBLE | false | none |
    | default | test | altitude | DOUBLE | false | none |
    | default | test | gps_type | INT | false | none |
    | default | test | gps_valid | INT | false | none |
    | default | test | gps_status | INT | false | none |
    | default | test | ... | ... | ... | ... |
    +-------------------+--------------+-------------------------------------+---------+----------------+------------+
    表的联合主键为device_code(车辆id)、collect_time(gps位置采集时间)、create_time(记录创建时间),另外还有其它74个非主键属性字段,包括对应collect_time的latitude(纬度)、longitude(经度)等。每辆车的gps按照10s的时间间隔连续采集轨迹点数据。
    创建索引
    为test表创建z-order二级索引,冗余longitude、latitude两列,避免主表回查
    CREATE INDEX zorder_idx ON test (z-order(longitude, latitude)) INLCUDE(longitude, latitude);
    进出点查询
    要获取test表中的每个设备在指定时间段(2022-08-12 11:12:39 - 2022-08-17 09:39:19)内进出指定区域(以经纬度120.20495, 30.187485810为圆心,半径1000米内的区域)的情况,查询语句如下:
    SELECT device_code, ST_TrajectoryProfile(longitude, latitude, collect_time, 10000) FROM test WHERE ST_DwithinSphere(ST_GeomFromText('POINT (120.20495 30.187485810)'), longitude, latitude, 1000.0) and collect_time >= 1660273959000 and collect_time <= 1660700359000 group by device_code;
    ST_TrajectoryProfile函数返回各个轨迹段的概要信息(进出点和进出时间)。由于gps采样间隔为10s,ST_TrajectoryProfile的时间阈值参数为10000(ms)。
    返回结果
    +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | device_code | ST_TRAJECTORYPROFILE(longitude, latitude) |
    +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | 13184922496 | {"0":"{\"endY\":30.1830,\"endX\":120.2000,\"startY\":30.1820,\"startTime\":1660273959000,\"startX\":120.1989,\"endTime\":1660283962000}"} |
    +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    该示例的返回结果表示在查询时间和区域内,只有一辆车进出了区域一次,进入时间为1660273959000 (2022-08-12 11:12:39),进入点为 (120.1989, 30.1820),离开前最后一次记录的时间为1660283962000 (2022-08-12 13:59:22),离开前最后一个记录点为 (120.2000, 30.1830)
    注:该示例collect_time存储格式为LONG类型,可支持的时间字段类型还有TIMESTAMP、TIME
    性能表现
    测试环境
    Lindorm Ganos测试集群:Lindorm 2.4.1版本,三节点16核32GB,1040G性能型云存储
    测试数据
    测试表结构与示例表结构相同,每条记录为车辆行驶过程中采集上传的一个轨迹点,表大小为3146MB,包含25辆车近3个月在经度范围[115.6253, 122.2817]、纬度范围[24.553466, 33.1788] 内的27045751个行驶轨迹点记录。
    查询性能
    • 查询的空间范围为半径1000m的圆形区域或面积在1平方千米左右的不规则区域,查询的时间范围均在一天左右。
    • 返回时间主要取决于索引过滤后聚合计算的数据量和空间范围过滤条件的复杂程度。测试耗时均在20s以内,部分查询情况如下
    查询条件
    聚合计算数据量(查询范围内记录数)
    查询耗时
    //代码效果参考:https://www.xx-ph.com/sitemap/post.html
    //代码效果参考:https://www.h3cw.com/sitemap/post.html
    空间范围:(120.20495 30.187485810) 周边1000m,时间范围:2022-10-20 18:12:48 - 2022-10-21 18:12:48
    3572683
    17s
    空间范围:矩形[(120.20322 30.18733),(120.21495 30.188485)],时间范围:2022-10-20 07:06:08 - 2022-10-21 15:26:08
    23026
    1s
    空间范围:外包框为[(120.20122 30.186485),(120.21595 30.189483)] 的不规则多边形,时间范围:2022-10-01 08:27:16 - 2022-10-02 13:18:41

3008
6s

相关文章
|
SQL 人工智能 分布式计算
基于阿里云PAI平台搭建知识库检索增强的大模型对话系统
基于原始的阿里云计算平台产技文档,搭建一套基于大模型检索增强答疑机器人。本方案已在阿里云线上多个场景落地,将覆盖阿里云官方答疑群聊、研发答疑机器人、钉钉技术服务助手等。线上工单拦截率提升10+%,答疑采纳率70+%,显著提升答疑效率。
|
10月前
|
自然语言处理 NoSQL API
基于百炼平台qwen-max的api 打造一套 检索增强 图谱增强 基于指令的智能工具调用决策 智能体
基于百炼平台的 `qwen-max` API,设计了一套融合检索增强、图谱增强及指令驱动的智能工具调用决策系统。该系统通过解析用户指令,智能选择调用检索、图谱推理或模型生成等工具,以提高问题回答的准确性和丰富性。系统设计包括指令解析、工具调用决策、检索增强、图谱增强等模块,旨在通过多种技术手段综合提升智能体的能力。
676 5
|
JavaScript 前端开发
实现自动扫描工作区npm包并同步cnpm
前言 在开发一个多npm包的项目时,时常会一次更新多个包的代码,再批量发布到 npm 镜像源后。 由于国内网络环境的原因,大部分都会使用淘宝的镜像源进行依赖安装,为了确保发布后,通过淘宝源能够顺利的安装,通常会手动同步一下 cnpm sync vue react 但在一些大型的 monorepo 的多包工程里,手动输入包名是一件非常繁琐的事情,所以准备把输入的过程简化一下,改成自动扫描工作区的包名,然后自动同步。 进而有了这个工具 工具的使用 直接通过 npx 运行即可,将自动扫描所有的包
|
传感器 人工智能 自然语言处理
人工智能数据
人工智能数据
522 1
|
JavaScript Java 测试技术
基于SpringBoot+Vue的汽车4s店管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的汽车4s店管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
297 6
基于SpringBoot+Vue的汽车4s店管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
JavaScript 数据安全/隐私保护 Python
JS逆向 -- 某视频vurl值的加密分析
JS逆向 -- 某视频vurl值的加密分析
348 0
|
JavaScript
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
这篇文章解释了为什么在Vue中组件的`data`属性必须是一个函数而不是一个对象。原因在于组件可能会有多个实例,如果`data`是一个对象,那么这些实例将会共享同一个`data`对象,导致数据污染。而当`data`是一个函数时,每次创建组件实例都会返回一个新的`data`对象,从而确保了数据的隔离。文章通过示例和源码分析,展示了Vue初始化`data`的过程和组件选项合并的原理,最终得出结论:根实例的`data`可以是对象或函数,而组件实例的`data`必须为函数。
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
|
存储 编解码 数据安全/隐私保护
ISPRS Vaihingen 数据集解析
ISPRS Vaihingen 数据集解析
1913 0
ISPRS Vaihingen 数据集解析
|
消息中间件 关系型数据库 MySQL
SpringBoot-Kafka(生产者事务、手动提交offset、定时消费、消息转发、过滤消息内容、自定义分区器、提高吞吐量)
SpringBoot-Kafka(生产者事务、手动提交offset、定时消费、消息转发、过滤消息内容、自定义分区器、提高吞吐量)
SpringBoot-Kafka(生产者事务、手动提交offset、定时消费、消息转发、过滤消息内容、自定义分区器、提高吞吐量)
|
Java
Java 继承深度剖析:子类与父类之间的“血缘”关系,如何传承与革新?
【6月更文挑战第16天】Java 继承体现类之间的&quot;血缘&quot;关系,子类继承父类的属性和方法,如`Student`继承`Person`。子类可扩展或覆盖父类功能,如`Student`的`introduce()`,展示代码复用和定制。同样,`Shape`的子类`Circle`和`Square`继承并定制`draw()`方法,形成多样的类结构,适应不同场景,增强代码组织和效率。
217 4