查询以查找空闲时间,即 GPS lat long 在 15 分钟内显示相同的坐标

Query to find idle time i.e GPS lat long showing same coordinates within 15 minutes

我在 postgres 中的 GPS table 具有包含四个字段的模式,如用户 ID (int)、纬度 (float8)、经度 (float8)、记录时间 (时间戳)。 对于每个用户,我们每分钟获得 2 条记录。

需要查询以查找在相同 GPS 经纬度值上花费超过 15 分钟的用户吗?

示例记录可以是

Userid, Latitiude, Longitude, recordedtime 
============================================
'ID1',12.089475408,76.089890,2019-11-24 19:10:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
'ID1',12.089475408,76.089890,2019-11-24 19:11:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
'ID1',12.089475408,76.089890,2019-11-24 19:12:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
....

..

有人可以提供所需的查询吗?

这个 CTE 可能就是您要找的。

WITH j AS (
  SELECT userid,longitude,latitude,
    max(recordedtime)-min(recordedtime) AS timespent
  FROM t
  GROUP BY userid,longitude,latitude
) SELECT * FROM j
  WHERE timespent > interval '15 minute';

 userid | longitude | latitude  | timespent 
--------+-----------+-----------+-----------
 ID1    | 80.205480 | 13.082240 | 00:20:00
(1 Zeile)

你考虑过用PostGIS来处理你的积分吗?您的用例看起来非常简单,但很快您可能会发现自己难以在 PostGIS 中已解决的数据模型中执行地理空间操作。

如果您有兴趣,请按照以下步骤创建基于 GPS 坐标的几何列:

ALTER TABLE t ADD COLUMN geom GEOMETRY;
UPDATE t SET geom = ST_SetSRID(ST_MakePoint(longitude, latitude),4326);

ST_SetSRID函数中的值4326代表Reference System WGS84。看看哪个适合你的坐标。

这就是查询的样子:

WITH j AS (
  SELECT userid,geom,
    max(recordedtime)-min(recordedtime) AS timespent
  FROM t
  GROUP BY userid,geom
) SELECT userid,ST_AsText(geom),timespent FROM j
  WHERE timespent > interval '15 minute';

 userid |        st_astext         | timespent 
--------+--------------------------+-----------
 ID1    | POINT(80.20548 13.08224) | 00:20:00
(1 Zeile)

注意:如@JGH所述,此用例假设坐标相同以计算花费的时间一定的位置。您的坐标有六位小数,因此精度为 0.111 m。长话短说,坐标偏离几米就不行了。在使用 ST_Buffer you can easily create a buffer of a given size and with ST_Within 的 PostGIS 中,您可以检查您的某个点是否在缓冲区内。下面的查询应该给出如何执行此操作的想法:

(缓冲区50米)

WITH j AS (
  SELECT userid, recordedtime, geom,
    ST_Buffer(geom::GEOGRAPHY,50)::GEOMETRY AS buffer
  FROM t
) SELECT t.userid, max(t.recordedTime)-min(t.recordedTime) AS timespent 
  FROM t,j
  WHERE t.userid=j.userid AND ST_Within(t.geom,j.buffer) 
  GROUP BY t.userid
  HAVING max(t.recordedTime)-min(t.recordedTime) > INTERVAL '15 minute';

 userid | timespent 
--------+-----------
 ID1    | 00:22:00
(1 Zeile)