在Postgresql中计算工单的对应的GPS轨迹距离

2024-08-31 06:12

本文主要是介绍在Postgresql中计算工单的对应的GPS轨迹距离,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、概述

在某个App开发中,要求记录用户的日常轨迹,在用户巡逻设备的时,将记录的轨迹点当做该设备巡逻时候的轨迹。

由于业务逻辑上没有明确的指示人员巡逻工单-GPS位置之间的关系,所以通过时间关系进行轨迹划定。

二、创建测试表

首先创建测试表,包括用户表、工单表以及GPS轨迹表。

  1. 用户表
--用户表
CREATE TABLE a_users (userid varchar NULL,username varchar NULL
);
  1. 工单表
--用户表
CREATE TABLE a_orders (orderid varchar NULL,relateduserid varchar NULL,order_time timestamptz NULL
);
  1. GPS轨迹表
--GPS记录表
CREATE TABLE a_gps_recording (gpsid int4 NULL,userid varchar NULL,x float4 NULL,y float4 NULL,recordtime timestamptz NULL
);

三、插入测试数据

为三张表分别插入测试数据。

--测试数据
---- 轨迹数据
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000001, '0', 124.00001, 34.00001, '2024-08-30 08:56:39.000 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000002, '0', 124.00001, 34.00002, '2024-08-30 08:56:39.500 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000003, '0', 124.00002, 34.00003, '2024-08-30 08:56:39.600 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000004, '0', 124.00003, 34.00004, '2024-08-30 08:56:39.700 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000005, '0', 124.00004, 34.00005, '2024-08-30 08:56:39.800 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000006, '1', 124.10004, 34.00005, '2024-08-30 05:55:00.000 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000007, '1', 124.20004, 34.00005, '2024-08-30 05:56:00.000 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000008, '1', 124.30004, 34.00005, '2024-08-30 05:57:00.000 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000009, '1', 124.40004, 34.00005, '2024-08-30 06:00:00.000 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000010, '1', 124.50004, 34.00005, '2024-08-30 06:01:00.000 +0800');
INSERT INTO a_gps_recording
(gpsid, userid, x, y, recordtime)
VALUES(900000011, '1', 124.60004, 34.00005, '2024-08-30 06:02:00.000 +0800');
---- 工单数据
INSERT INTO a_orders
(orderid, relateduserid, order_time)
VALUES('100000', '0', '2024-08-30 08:56:39.000');
INSERT INTO a_orders
(orderid, relateduserid, order_time)
VALUES('100001', '1', '2024-08-30 07:20:39.000');
INSERT INTO a_orders
(orderid, relateduserid, order_time)
VALUES('100002', '1', '2024-08-30 06:00:00.000');
---- 用户数据
INSERT INTO a_users (userid, username) VALUES('1', '用户1');
INSERT INTO a_users (userid, username) VALUES('2', '用户2');
INSERT INTO a_users (userid, username) VALUES('3', '用户3');
INSERT INTO a_users (userid, username) VALUES('0', '用户0');

四、查询思路

4.1 建立表工单表和用户表之间的关联,筛选工单

第一个CTE order_user连接a_ordersa_users表,以检索与订单ID“100002”关联的用户名。

4.2 建立订单与轨迹之间的关联查询
  1. 第二个CTE order_gps在订单时间的5分钟时间窗口内从a_gps_recording表中选择与用户相关的gps记录。它计算订单时间和GPS记录时间之间的时间差。
  2. 第三个CTE ordered_data根据记录时间为每个GPS记录分配一个行号。这将有助于计算连续GPS记录之间的距离。
4.3 距离计算
  1. 主查询从ordered_dataCTE中选择所需的列,并使用ST_distance函数计算连续GPS记录之间的距离。ST_Transform函数用于将坐标转换为合适的投影(EPSG:3857)以进行距离计算。
  2. ordered_data(别名od1)和自身(别名od2)之间的左JOIN条件为od1.rn=od2.rn+1,可确保计算连续GPS记录之间的距离。
    此查询的结果将是一个表,其中包含订单IDGPS ID用户ID坐标记录时间时差连续GPS记录之间的行驶距离列。
    请注意,此查询假定数据库中存在a_ordersa_usersa_gps_recording表。确保将表名和列名替换为数据库中的实际名称。

五、查询SQL

--查询指定工单/用户的距离
select orderid,gpsid,userid,x,y,recordtime,time_Diff,distance_in_meters from (-- ■■■■■■order_user■■■■■with order_user as (select ao.*,au.username from a_orders ao left join a_users au on ao.relateduserid = au.userid and ao.orderid = '100002'),-- ■■■■■■order_gps■■■■■order_gps as (select ao.username,ao.orderid,agr.gpsid,agr.userid,agr.x,agr.y,agr.recordtime,abs(EXTRACT(EPOCH FROM age(ao.order_time , agr.recordtime)) / 60) as time_Diff from order_user ao join a_gps_recording agron  --距离工单前后5分钟的位置作为工单相关的距离abs(EXTRACT(EPOCH FROM age(ao.order_time , agr.recordtime)) / 60) < 5 --工单号为100002and ao.relateduserid = agr.userid and ao.orderid = '100002'),-- ■■■■■■ordered_data■■■■■ordered_data as (SELECT orderid,gpsid,userid,x,y,recordtime,time_diff,row_number() OVER (ORDER BY recordtime) AS rnFROM order_gps)SELECT od1.orderid,od1.gpsid,od1.userid,od1.x,od1.y,od1.recordtime,od1.time_Diff,od1.recordtime AS time1,od2.recordtime AS time2,-- ■■■■■■转换地理坐标系到平面坐标系,计算距离■■■■■ST_Distance(ST_Transform(ST_SetSRID(ST_MakePoint(od1.x, od1.y), 4326), 3857), ST_Transform(ST_SetSRID(ST_MakePoint(od2.x, od2.y), 4326), 3857)) AS distance_in_metersFROM ordered_data od1left JOIN ordered_data od2 ON od1.rn = od2.rn + 1
) t;

六、测试结果

运行上述SQL,得到如下查询结果,最后一列distance_in_meters为计算出的相邻两个GPS点之间的距离。

测试结果

进一步计算工单对应的总距离,只需要运行sum函数查询即可。

这篇关于在Postgresql中计算工单的对应的GPS轨迹距离的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123115

相关文章

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的

pytorch+torchvision+python版本对应及环境安装

《pytorch+torchvision+python版本对应及环境安装》本文主要介绍了pytorch+torchvision+python版本对应及环境安装,安装过程中需要注意Numpy版本的降级,... 目录一、版本对应二、安装命令(pip)1. 版本2. 安装全过程3. 命令相关解释参考文章一、版本对

Ubuntu 22.04 服务器安装部署(nginx+postgresql)

《Ubuntu22.04服务器安装部署(nginx+postgresql)》Ubuntu22.04LTS是迄今为止最好的Ubuntu版本之一,很多linux的应用服务器都是选择的这个版本... 目录是什么让 Ubuntu 22.04 LTS 变得安全?更新了安全包linux 内核改进一、部署环境二、安装系统

Python重命名文件并移动到对应文件夹

《Python重命名文件并移动到对应文件夹》在日常的文件管理和处理过程中,我们可能会遇到需要将文件整理到不同文件夹中的需求,下面我们就来看看如何使用Python实现重命名文件并移动到对应文件夹吧... 目录检查并删除空文件夹1. 基本需求2. 实现代码解析3. 代码解释4. 代码执行结果5. 总结方法补充在

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

对postgresql日期和时间的比较

《对postgresql日期和时间的比较》文章介绍了在数据库中处理日期和时间类型时的一些注意事项,包括如何将字符串转换为日期或时间类型,以及在比较时自动转换的情况,作者建议在使用数据库时,根据具体情况... 目录PostgreSQL日期和时间比较DB里保存到时分秒,需要和年月日比较db里存储date或者ti

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

PostgreSQL如何查询表结构和索引信息

《PostgreSQL如何查询表结构和索引信息》文章介绍了在PostgreSQL中查询表结构和索引信息的几种方法,包括使用`d`元命令、系统数据字典查询以及使用可视化工具DBeaver... 目录前言使用\d元命令查看表字段信息和索引信息通过系统数据字典查询表结构通过系统数据字典查询索引信息查询所有的表名可