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

news2024/11/15 19:50:59

一、概述

在某个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 agr
			on  
			--距离工单前后5分钟的位置作为工单相关的距离
			abs(EXTRACT(EPOCH FROM age(ao.order_time , agr.recordtime)) / 60) < 5 
			--工单号为100002
			and 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 rn
		    FROM 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_meters
		FROM ordered_data od1
		        left JOIN ordered_data od2 ON od1.rn = od2.rn + 1
) t;

六、测试结果

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

测试结果

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2090147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Core ML

本文翻译整理自&#xff1a;Core ML : https://developer.apple.com/cn/documentation/coreml/ 文章目录 一、概览二、获取 Core ML 模型三、将 Core ML 模型集成到你的 App 中1、将模型添加到您的Xcode项目2、在代码中创建模型3、获取要传递给模型的输入值4、使用模型进行预测…

vue2踩坑记录:el-select如何绑定对象

页面上的下拉框&#xff1a; 选中人员之后&#xff0c;需要使用人员的其它信息做后续操作。所以不能只绑定用户Id&#xff0c;需要绑定整个item(用户对象)&#xff0c;这样每次change事件所获取到的newValue是整个对象&#xff0c;而且v-model中的变量指向的也是整个对象&#…

Windows bat脚本学习五(函数)

一、简介 使用bat脚本时&#xff0c;经常要使用函数&#xff0c;而函数的传参和返回值也是非常重要的&#xff0c;今天就总结一下bat中函数相关的使用方法。 二、函数 1.函数调用 :函数名 在Bat中&#xff0c;使用“:函数名”来定义一个函数。 见如下代码&#xff1a; echo o…

安装KataGo+Sabaki围棋引擎

1.由于我的用户名是中文名,修改TMP和TEMP为SystemRoot(后续修改回来) 2.加入xx.bin文件后,cmd输入katago.exe genconfig -model model.bin -output gtp_custom.cfg 3.KataGo下载完成 4.配置GUI界面

ubuntu录屏解决ubuntu下无法播放MP4格式文件的方法

参考 gnome gnome是系统自带的录屏&#xff0c;通过ctrlshiftaltr触发 保存到了视频目录下&#xff0c;webm格式文件。 screencastify 这是一个chrome扩展&#xff0c;&#xff0c;一般不推荐使用 recapp 比gnome自由一些&#xff0c;可以自由屏幕录制。但是无法修改录制…

利用流水线实现版本一键发布

目录 1. 背景2. 实现步骤3.1 前置条件3.2 更新版本号和拉出发布分支3.3 生成 diffCommit3.4 自动触发联动编译3.5 让通知更友好 3. 总结 1. 背景 通常我们发布版本时会有这样几个步骤&#xff0c;更改版本号&#xff0c;拉出 release 分支&#xff0c;生成发布包。但是博主所在…

关于ThinkPHP 5 框架开启自动搜索控制器 无法访问的问题坑

假如当前有一个登陆接口功能 因为后续会有不同版本的 登陆接口 这时候 我们可以在控制器中 新建文件夹 做区分 方便管理即 新建了一个 api 模块 文件路径是 api/controller/V1/Login 正常情况下 controller 目录下 是 控制器文件 login.php 文件&#xff0c;由于我们有多个…

地下车库电车这样充电,必须改

文 | AUTO芯球 作者 | 响铃 我是真的害怕啊 你们看&#xff0c;我住的小区&#xff0c; 都是这样子啊 一个这样子的塑料盒&#xff0c;最多一个铝板盒子&#xff0c;就给车充电了 你看看 这样的塑料电槽 就这样裸露在外面了 有些摸一下 电线都在发烫 现在我们小区内这…

【NCom】:通用负压退火方法构建超高负载单原子催化剂库

摘要&#xff1a;由高密度单原子填充的催化剂系统对于提高催化活性和选择性至关重要&#xff0c;这可以最大限度地发挥异质单原子催化剂 (SAC) 的工业前景。然而&#xff0c;实现金属含量超过 10 wt% 的高负载 SAC 仍然具有挑战性。在这里&#xff0c;我们描述了一种通用的负压…

【UCB CS61C】Lecture 4 - C Memory Management Usage

目录 C 的内存布局&#xff08;Memory Layout&#xff09;栈&#xff08;Stack&#xff09;静态数据&#xff08;Static Data&#xff09;代码&#xff08;Code&#xff09; 寻址&#xff08;Addressing&#xff09;地址&#xff08;Address&#xff09;字节序&#xff08;Endi…

电脑缺少dll文件怎么解决?Dll文件修复工具使用教程(方法合集)

众所周知&#xff0c;dll文件是计算器中的一类文件。占据了Windows操作系统的重要地位&#xff0c;主要作用就是可以让多个程序在运行时加以使用。dll文件包含了数字、文本、界面的等内容。 电脑缺少dll文件怎么解决&#xff1f;如果你启动某个程序时&#xff0c;发现电脑提示缺…

如何共享EC2 AMI给其他AWS账户

在本篇文章中&#xff0c;我们将详细介绍如何通过Amazon Web Services (AWS) 的Elastic Compute Cloud (EC2) 平台&#xff0c;将自定义AMI&#xff08;Amazon Machine Image&#xff09;共享给其他AWS账户。接下来&#xff0c;我们九河云将一步步引导您完成整个过程&#xff0…

数据驱动,智领办公!陀螺匠·企业助手 v1.7公测版发布

在数字化转型浪潮中&#xff0c;企业对办公自动化系统的需求愈加强烈&#xff0c;追求高效、灵活、智能的办公管理解决方案成为行业共识&#xff0c;我们深知&#xff0c;只有不断创新和完善&#xff0c;才能满足企业日益增长的需求。此次&#xff0c;我们带来陀螺匠企业助手 v…

【GeoScenePro】知识图谱

视频教程: ArcGIS/GeoScene知识图谱入门篇_哔哩哔哩_bilibili 所需软件: GeoScene Pro桌面端产品 Geoscene Enterprise四大组件(GeoScene_Server、GeoScene_DataStore、GeoScene_Portal、GeoScene_Web_Adaptor) 安装 【GeoScenePortal】安装和部署-CSDN博客

2024年下半年软考备考前的注意细节点

一、备考教材信息——选择官方正版&#xff08;电子、纸质都可以&#xff09; 中项 书名&#xff1a;《系统集成项目管理工程师教程》&#xff08;第三版&#xff09; 出版社&#xff1a;清华大学出版社 书籍类型&#xff1a;全国计算机技术与软件专业技术资格&#xff08;…

centos安装docker并配置加速器

docker安装与卸载&#xff1a; 1、检查当前是否安装docker yum list installed | grep docker2、卸载docker 根据yum list installed | grep docker查询出来的内容&#xff0c;逐个进行删除 yum remove docker.x86 64 -y3、启动与关闭docker 4、删除/etc/docker文件夹 如果…

少走弯路,ESP32 读取Micro SD(TF)播放mp3的坑路历程。

这个坑采的非常冤枉和巨大&#xff0c;非常大的冤枉路&#xff0c;只能一声叹息 说一下我是如何踩坑的&#xff0c;原本是打算用esp32 读取SD卡播放mp3,在esp32 读取自己打的SD卡已经踩了无数坑了&#xff0c;详情见&#xff1a; 少走弯路&#xff0c;ESP32 使用Micro SD(TF)…

Java学习第五天

数组 数组适合做一批同类型数据的存储。 静态初始化数组&#xff1a; 注意&#xff1a;数组变量名中存储的是数组在内存中的地址&#xff0c;数组是引用类型。 数组的访问 动态初始化数组&#xff1a; 数组的遍历&#xff1a; 注意左边和右边的区别&#xff0c;一个是改变数组…

日元升值,日股遇冷:出口商的烦恼

最近&#xff0c;日元汇率的走强让不少日本企业感到头疼。日元升值就像一把双刃剑&#xff0c;既能带来好处&#xff0c;也能带来坏处。 为什么日元升值会让日本企业头疼&#xff1f; 出口受阻&#xff1a; 当日元升值时&#xff0c;日本商品在国际市场上的价格就会变得相对较…

Access OpenAI (json) API from R

题意&#xff1a;“从 R 访问 OpenAI (JSON) API” 问题背景&#xff1a; I want to access the OpenAI API with the following curl command from R: “我想从 R 中使用以下 curl 命令访问 OpenAI API&#xff1a;” curl https://api.openai.com/v1/engines/davinci/comp…