从GPS日志计算用户的距离和持续时间

阿里万

我正在使用北京城市人口流动的GPS数据集在我的原始GPS表中,trajectories是所有用户的GPS序列:

CREATE TABLE trajectories
(
    user_id integer,
    session_id bigint NOT NULL,
    "timestamp" timestamp with time zone NOT NULL,
    lat double precision NOT NULL,
    lon double precision NOT NULL,
    alt double precision,
    CONSTRAINT trajectories_pkey PRIMARY KEY (session_id, "timestamp")
);

SELECT * FROM trajectories ORDER BY user_id, timestamp LIMIT 10;
 user_id |   session_id   |       timestamp        |    lat    |    lon     | alt 
---------+----------------+------------------------+-----------+------------+-----
       1 | 20081023025304 | 2008-10-23 02:53:04+01 | 39.984702 | 116.318417 | 492
       1 | 20081023025304 | 2008-10-23 02:53:10+01 | 39.984683 |  116.31845 | 492
       1 | 20081023025304 | 2008-10-23 02:53:15+01 | 39.984686 | 116.318417 | 492
       1 | 20081023025304 | 2008-10-23 02:53:20+01 | 39.984688 | 116.318385 | 492
       1 | 20081023025304 | 2008-10-23 02:53:25+01 | 39.984655 | 116.318263 | 492
       1 | 20081023025304 | 2008-10-23 02:53:30+01 | 39.984611 | 116.318026 | 493
       1 | 20081023025304 | 2008-10-23 02:53:35+01 | 39.984608 | 116.317761 | 493
       1 | 20081023025304 | 2008-10-23 02:53:40+01 | 39.984563 | 116.317517 | 496
       1 | 20081023025304 | 2008-10-23 02:53:45+01 | 39.984539 | 116.317294 | 500
       1 | 20081023025304 | 2008-10-23 02:53:50+01 | 39.984606 | 116.317065 | 505
(10 rows)

上面的SELECT查询显示了user 1从当前行程(session_id=20081023025304的起点到的GPS点的顺序我想使用此表中的原始数据将计算出的行程指标插入到我定义为的新表中:

CREATE TABLE trip_metrics(
  user_id INT,
  session_id BIGINT,
  lat_start DOUBLE PRECISION,
  lat_end DOUBLE PRECISION,
  lon_start DOUBLE PRECISION,
  lon_end DOUBLE PRECISION,
  trip_starttime timestamp,
  trip_endtime timestamp,
  trip_duration DOUBLE PRECISION,
  trip_distance DOUBLE PRECISION,
  PRIMARY KEY (user_id, session_id, trip_starttime)
  );

这点trip_metrics表是为存储结果进行分析,以使得lat_start, lon_start取的值lat, lon开始位置(在给出的例子:39.984702, 116.318417),trip_starttimestamp取开始时间(在这种情况下2008-10-23 02:53:04+01),并且因此lat_end, lon_end, trip_endtime分别。

最后使用lat_start/end, lon_start/end来计算此行程中该用户覆盖的距离。最终结果应为:

+---------+----------------+-----------+-----------+------------+------------+------------------------+------------------------+---------------+---------------+
| user_id |   session_id   | lat_start |  lat_end  | lon_start  |  lon_end   |     trip_starttime     |      trip_endtime      | trip_duration | trip_distance |
+---------+----------------+-----------+-----------+------------+------------+------------------------+------------------------+---------------+---------------+
|       1 | 20081023025304 | 39.984702 | 39.984606 | 116.318417 | 116.317065 | 2008-10-23 02:53:04+01 | 2008-10-23 02:53:50+01 |               |               |
+---------+----------------+-----------+-----------+------------+------------+------------------------+------------------------+---------------+---------------+

用的值trip_durationtrip_distance计算出的(当然的值trip_duration将是trip_endtime - trip_starttime)。

我一直停留在我的研究为思考如何做到这一点在一两天的PostgrSQL数据库过滤只有北京全市范围内旅行latitude (39.85 - 40.05),并longitude (116.25 - 116.5)作为跨越超越了城市一些行程。我在这里创建了一个分贝提琴其中包含该用户2次旅行的GPS点(每个点10点)。

我将不胜感激任何指南,以解决此问题,以使我目前的研究取得进展。

编辑

碰到这个函数,使用Haversine公式计算距离。我创建了此函数,但不确定如何使用它来获取trip_distance价值。

CREATE OR REPLACE FUNCTION distance(
    lat1 double precision,
    lon1 double precision,
    lat2 double precision,
    lon2 double precision)
  RETURNS double precision AS
$BODY$
DECLARE
    R integer = 6371e3; -- Meters
    rad double precision = 0.01745329252;

    φ1 double precision = lat1 * rad;
    φ2 double precision = lat2 * rad;
    Δφ double precision = (lat2-lat1) * rad;
    Δλ double precision = (lon2-lon1) * rad;

    a double precision = sin(Δφ/2) * sin(Δφ/2) + cos(φ1) * cos(φ2) * sin(Δλ/2) * sin(Δλ/2);
    c double precision = 2 * atan2(sqrt(a), sqrt(1-a));    
BEGIN                                                     
    RETURN R * c;        
END  
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
吉姆·琼斯

为了更轻松地计算距离,您必须按照PostGIS extension标记中的建议安装,方法是:

CREATE EXTENSION postgis;

该函数ST_Distance是您要查找的内容,例如(快速&肮脏):

WITH j AS (
  SELECT user_id, session_id, 
    max(timestamp ORDER BY timestamp),
    min(timestamp ORDER BY timestamp) 
  FROM trajectories t
  GROUP BY user_id,session_id  
) 
SELECT 
  s.user_id,s.session_id, 
  lat_start,lon_start, 
  lat_end,lon_end, 
  trip_starttime, 
  trip_endtime,
  age(trip_endtime,trip_starttime),
  ST_Distance(
    ST_MakePoint(lon_start,lat_start)::geography,
    ST_MakePoint(lon_end,lat_end)::geography) AS trip_distance
FROM 
  (SELECT 
    j.user_id, j.session_id, 
    t.timestamp AS trip_starttime,
    lat AS lat_start, lon AS lon_start FROM j
   JOIN trajectories t ON t.timestamp = j.min 
     AND t.session_id = j.session_id AND t.user_id = j.user_id) s,
  (SELECT 
    j.user_id, j.session_id, 
    t.timestamp AS trip_endtime,
    lat AS lat_end,lon AS lon_end FROM j
   JOIN trajectories t ON t.timestamp = j.max 
     AND t.session_id = j.session_id AND t.user_id = j.user_id) e
WHERE s.user_id = e.user_id AND s.session_id = e.session_id;

 user_id |   session_id   | lat_start | lon_start |  lat_end  |  lon_end   |     trip_starttime     |      trip_endtime      |   age    |  trip_distance   
---------+----------------+-----------+-----------+-----------+------------+------------------------+------------------------+----------+------------------
       1 | 20081023025304 | 39.984702 | 16.318417 | 39.984606 | 116.317065 | 2008-10-23 03:53:04+02 | 2008-10-23 03:53:50+02 | 00:00:46 | 8012597.30391588

附带说明:在分开的列中存储经度和纬度几乎总是一个坏主意。如果可能的话,将它们存储在几何或地理列中。乍一看似乎很有必要,但PostGIS确实提供了很多功能kickass functions

进一步阅读:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何四舍五入谷歌地图持续时间和距离计算器

来自分类Dev

Directions API与航点的总距离和持续时间

来自分类Dev

osmbonuspack中道路的距离和持续时间的单位

来自分类Dev

osmbonuspack中道路的距离和持续时间的单位

来自分类Dev

如何计算以每个日期的持续时间和15分钟的间隔记录的用户

来自分类Dev

如何计算发生之间的时间(和发生的持续时间)

来自分类Dev

计算持续时间(年龄)

来自分类Dev

计算日期持续时间

来自分类Dev

计算夜班持续时间

来自分类Dev

计算不同行和不同列的持续时间?

来自分类Dev

计算总体锻炼时间的“持续时间”

来自分类Dev

如何获得从当前位置到下一步的距离,方向和持续时间?

来自分类Dev

Bing API-行驶持续时间和距离的批处理作业

来自分类Dev

SQL 计算查询开始时间和持续时间以查找结束时间

来自分类Dev

日期持续时间/日期减法计算

来自分类Dev

计算甘特图的总持续时间

来自分类Dev

如何计算表格中的持续时间

来自分类Dev

计算数据集的持续时间

来自分类Dev

在2列中计算持续时间

来自分类Dev

计算复杂表中的持续时间

来自分类Dev

用条件计算日期持续时间

来自分类Dev

从行计算SQLite持续时间

来自分类Dev

如何计算表格中的持续时间

来自分类Dev

计算数据集的持续时间

来自分类Dev

使用Pandas Python在持续时间和日期时间按时间区分用户

来自分类Dev

日期时间和持续时间添加

来自分类Dev

计算vbscript中许多开始和结束时间之间的实际持续时间

来自分类Dev

当某些记录不完整时,计算登录和注销时间之间的持续时间

来自分类Dev

根据日期和持续时间数据计算时间列 - SQL Server ASP Classic

Related 相关文章

热门标签

归档