在 PostgreSQL 中聚合 (x,y) 坐标点云

Posted

技术标签:

【中文标题】在 PostgreSQL 中聚合 (x,y) 坐标点云【英文标题】:Aggregating (x,y) coordinate point clouds in PostgreSQL 【发布时间】:2012-09-28 14:15:09 【问题描述】:

我有一个具有以下简化结构的 PostgreSQL 数据库表:

设备 ID varchar Pos_X(整数) Pos_Y(整数)

基本上这个表包含很多设备的二维航点数据。现在我想设计一个查询来减少输出中的坐标数。它应该聚合附近的坐标(对于某个 x,y 阈值) 一个例子:

第 1 行:DEVICE1;603;1205

第 2 行:DEVICE1;604;1204

如果阈值为 5,则应将这两行汇总,因为方差小于 5。 知道如何在 PostgreSQL 或 SQL 中执行此操作吗?

【问题讨论】:

【参考方案1】:

结合您的聚合使用经常被忽视的内置函数width_bucket()

如果您的坐标范围从 0 到 2000,并且您想将 5 个正方形内的所有内容合并为单个点,我会像这样布置一个 10 (5*2) 的网格:

SELECT device_id
     , width_bucket(pos_x, 0, 2000, 2000/10) * 10 AS pos_x
     , width_bucket(pos_y, 0, 2000, 2000/10) * 10 AS pos_y
     , count(*) AS ct -- or any other aggregate
FROM   tbl
GROUP  BY 1,2,3
ORDER  BY 1,2,3;

最小化误差,您可以GROUP BY 显示的网格,但要保存实际的平均坐标:

SELECT device_id
     , avg(pos_x)::int AS pos_x   -- save actual averages to minimize error
     , avg(pos_y)::int AS pos_y   -- cast if you need to
     , count(*)        AS ct      -- or any other aggregate
FROM   tbl
GROUP  BY
       device_id
     , width_bucket(pos_x, 0, 2000, 2000/10) * 10  -- aggregate by grid
     , width_bucket(pos_y, 0, 2000, 2000/10) * 10
ORDER  BY 1,2,3;

sqlfiddle demonstrating both alongside.

好吧,这个特殊情况可能更简单:

...
GROUP  BY
       device_id
     , (pos_x / 10) * 10          -- truncates last digit of an integer
     , (pos_y / 10) * 10
...

但这只是因为10 的演示网格大小可以方便地匹配十进制系统。尝试使用17 或其他网格大小的相同...


扩展到时间戳

您可以使用extract() 将datetimestamp 值转换为unix 纪元(自'1970-1-1' 以来的秒数),从而扩展此方法以覆盖它们。

SELECT extract(epoch FROM '2012-10-01 21:06:38+02'::timestamptz);

完成后,将结果转换回timestamp with time zone

SELECT timestamptz 'epoch' + 1349118398 * interval '1s';

或者干脆to_timestamp():

SELECT to_timestamp(1349118398);

【讨论】:

这太棒了,谢谢。现在我需要弄清楚如何在使用时间戳列时扩展它,并且仅在它们相隔最多 5 分钟时才聚合点...【参考方案2】:
select [some aggregates] group by (pos_x/5, pos_y/5); 

你可以有任何数字而不是 5,这取决于你需要多少聚合/

【讨论】:

以上是关于在 PostgreSQL 中聚合 (x,y) 坐标点云的主要内容,如果未能解决你的问题,请参考以下文章

手把手教你 Tableau 绘制跑道图(二十六)

坐标x353855.833y526103.831是用的啥坐标系

建筑坐标X与Y分别表示啥

如何在网格坐标中找到最近的对象

在 python matplotlib 中绘制 (x, y) 坐标列表

Postgresql:如何在聚合函数之后显示附加列