PostgreSQL 空间独立事件相关性分析 二 - 人车拟合

标签

PostgreSQL , PostGIS , 人车拟合


背景

独立事件相关性分析是一件很有意思的事情,例如

探探软件的擦肩而过功能点,在不同时空与你擦肩而过的人。

舆情分析。

商品最佳销售组合。

安全系统中的人车拟合,对时空数据进行处理,用于司机、乘客、车辆的拟合。

人车拟合

1、建立表结构

create table u_pos (
  id int8,
  uid int8,
  crt_time timestamp,
  pos geometry
);

create table c_pos (
  id int8,
  car_id int8,
  crt_time timestamp,
  pos geometry
);

2、生成测试数据。

以杭州市为例,经纬度范围如下:

东经118°21′-120°30′,北纬29°11′-30°33′ 计算得东经118.35°-120.5°,北纬29.183°-30.55°。

活跃量假设:

1000万人口,1000万车辆。  

人的轨迹数,一天10亿。  

车的轨迹数,一天1亿。

2.1、写入人的活动位置数据,按天分区,保留一年。

for ((i=1;i<=32;i++))
do
nohup psql -c "insert into u_pos select id, random()*10000000, '2017-10-01'::date + ((id*2.7648)||' ms')::interval, st_setsrid(st_makepoint(118.35+random()*2.15, 29.183+random()*1.367), 4326) from generate_series(1,31250000) t(id);" >/dev/null 2>&1 &
done

采用时序数据中最常用的brin索引。

create index idx_u_pos_1 on u_pos using brin(crt_time);

建立人+时间的索引。

create index idx_u_pos_2 on u_pos using btree(uid, crt_time);

2.2、写入车辆的活动位置数据,按天分区,保留一年。

for ((i=1;i<=32;i++))
do
nohup psql -c "insert into c_pos select id, random()*10000000, '2017-10-01'::date + ((id*27.648)||' ms')::interval, st_setsrid(st_makepoint(118.35+random()*2.15, 29.183+random()*1.367), 4326) from generate_series(1,3125000) t(id);" >/dev/null 2>&1 &
done

采用时序数据中最常用的brin索引。

create index idx_c_pos_1 on c_pos using brin(crt_time);

建立车+时间的索引。

create index idx_c_pos_2 on c_pos using btree(car_id, crt_time);

3、求某个时间区间的人车拟合

3.1、车辆,行驶过程中抓到的N个点,返回时间,位置。

select pos, crt_time from c_pos where car_id=? and crt_time between ? and ?;

返回对应时间区间的N个点附近的人交集

create or replace function merge_car_u(
  v_car_id int8,       -- 汽车ID
  s_time timestamp,    -- 搜索范围,开始时间
  e_time timestamp,    -- 搜索范围,结束时间
  ts_range interval,   -- 每个汽车轨迹点对应的:目标人出现的时间与汽车出现时间的时间差(前后各放大多少)
  pos_range float8     -- 每个汽车轨迹点对应的:目标人与汽车的距离
) returns int8[] as $$
declare
  res int8[];
  tmp int8[];
  v_pos geometry;
  v_crt_time timestamp;
  i int := 0;
begin
  for v_pos, v_crt_time in select pos, crt_time from c_pos where car_id=v_car_id and crt_time between s_time and e_time  -- 求轨迹点
  loop
    select array_agg(uid) into tmp from u_pos where crt_time between v_crt_time-ts_range and v_crt_time+ts_range and (v_pos <-> pos) < pos_range;  -- 求对应目标的ID
    if (i <> 0) then
      select array_agg(unnest) into res from (select unnest(res) intersect select unnest(tmp)) t;  -- 求交集
    else
      res := tmp;
    end if;
    i := i+1;
  end loop;
  return res;
end;
$$ language plpgsql strict;

例子:

postgres=# select * from merge_car_u(1, '2017-10-01 01:00:00', '2017-10-01 04:00:00', '10 s', 0.004);
            merge_car_u
-----------------------------------
 {5481974,5958009,3682524,1313466}
(1 row)  

Time: 232.960 ms

3.2、人,运动过程中抓到的N个点,返回时间,位置。

返回对应时间区间的N个点附近的车辆的交集

create or replace function merge_u_car(
  v_uid int8,              -- 人ID
  s_time timestamp,        -- 搜索范围,开始时间
  e_time timestamp,        -- 搜索范围,结束时间
  ts_range interval,       -- 每个人轨迹点对应的:目标车辆出现的时间与人出现时间的时间差(前后各放大多少)
  pos_range float8         -- 每个人轨迹点对应的:目标车辆与人的距离
) returns int8[] as $$
declare
  res int8[];
  tmp int8[];
  v_pos geometry;
  v_crt_time timestamp;
  i int := 0;
begin
  for v_pos, v_crt_time in select pos, crt_time from u_pos where uid=v_uid and crt_time between s_time and e_time  -- 求轨迹点
  loop
    select array_agg(car_id) into tmp from c_pos where crt_time between v_crt_time-ts_range and v_crt_time+ts_range and (v_pos <-> pos) < pos_range;  -- 求对应目标的ID
    if (i <> 0) then
      select array_agg(unnest) into res from (select unnest(res) intersect select unnest(tmp)) t;  -- 求交集
    else
      res := tmp;
    end if;
    i := i+1;
  end loop;
  return res;
end;
$$ language plpgsql strict;

例子:

postgres=# select * from merge_u_car(100, '2017-10-01 01:00:00', '2017-10-01 02:00:00', '100 s', 0.2);
                                                merge_u_car
-----------------------------------------------------------------------------------------------------------
 {6214562,6180159,4534165,7824219,6826437,3020910,1463798,2939986,5786345,7233751,2856178,1719127,7763683}
(1 row)  

Time: 96.986 ms

小结

1、存储、索引优化思路。

时间截断 + 空间排序 存储

例如

(YYYY-MM-DD HH24:MI), (geohash)

存储修整后,建立以上结构的btree或BRIN索引。

当搜索某个时间点,出现在某个点附近的记录时,可以并行,并且搜索的数据块是比较少的,因为密集存储。

2、其他需求:缺失位置的补齐。某些情况下,可能导致车辆、人的位置信息未采集的情况,例如经过拥堵路段、采集设备死角等。

在位置获取出现空缺的情况下,使用pgrouting,以及路网信息,生成若干条路径,补齐为出现的点。同时估算时间,得到点和经过的时间。

3、其他需求:异常位置纠正。

4、拟合性能,以天为分区。1000万人口,1000万车辆。人的轨迹数,一天10亿。车的轨迹数,一天1亿。

可以做到毫秒级别的拟合响应。

参考

《潘金莲改变了历史之 - PostgreSQL舆情事件分析应用》

《为什么啤酒和纸尿裤最搭 - 用HybridDB/PostgreSQL查询商品营销最佳组合》

时间: 2024-11-02 23:11:53

PostgreSQL 空间独立事件相关性分析 二 - 人车拟合的相关文章

PostgreSQL 空间st_contains,st_within空间包含搜索优化 - 降IO和降CPU(bound box)

标签 PostgreSQL , st_contains , st_within , 空间包含 , 空间bound box , GiST索引 , 空间索引结构 , IO放大 , BOUND BOX放大 背景 点面判断.按面圈选点或其他对象,是GIS几何应用中非常典型的需求. 在PostgreSQL中通过建立GiST索引可以加速这类判断,然而,建立索引就够了吗? 很多时候建立索引是不够的,性能没有到达巅峰,如果要更低的延迟,更少的CPU开销,还有什么优化手段呢? 实际上我以前写过一篇类似的文章,讲的

c语言-求输出与关联规则算法类似的相关性分析方法

问题描述 求输出与关联规则算法类似的相关性分析方法 比如说一条关联规则a->(b,c,d) 支持度3 置信度0.3,求输出形式类似于属性a与属性集(b,c,d)的相关系数为0.2的相关性分析方法!!!! 解决方案 http://www.cnblogs.com/qwertWZ/p/4510857.html

一些有用的javascript实例分析(二)

原文:一些有用的javascript实例分析(二) 1 5 求出数组中所有数字的和 2 window.onload = function () 3 { 4 var oBtn = document.getElementsByTagName("button")[0]; 5 var oInput = document.getElementsByTagName("input")[0] 6 var oStrong = document.getElementsByTagName

大数据:从因果分析到相关性分析

大数据已经不再是计算.统计学科的专宠,商学院开始的广泛应用,表明大数据正式进入各行业的广泛应用.统计学家纳特·西尔弗在著名的<信号和噪声>一书中说:"大数据中大多数都是不相干的噪音.除非有很好的技术信息进行过滤和处理,否则将惹上麻烦." 杜克大学富卡商学院今年秋季开始招收大数据商业分析方向的硕士生,西安交通大学管理学院也将录取海外大数据分析的博士生作为新录取教职人员的重点之一.大数据已经不再是计算.统计学科的专宠,商学院开始的广泛应用,表明大数据正式进入各行业的广泛应用.

Oracle数据库安全策略分析(二)_oracle

正在看的ORACLE教程是:Oracle数据库安全策略分析(二). SQL*DBA命令的安全性: 如果您没有SQL*PLUS应用程序,您也可以使用SQL*DBA作SQL查权限相关的命令只能分配给Oracle软件拥有者和DBA组的用户,因为这些命令被授予了特殊的系统权限. (1) startup (2) shutdown (3) connect internal 数据库文件的安全性: Oracle软件的拥有者应该这些数据库文件($ORACLE_HOME/dbs/*.dbf)设置这些文件的使用权限为

Oracle中的PGA监控报警分析二(r12笔记第87天)

今天又收到了一条报警的信息,看起来很常规,但是后面的故事如果你做了分析就会发现其实本身并不平常,我觉得我得出手了. ZABBIX-监控系统: ------------------------------------报警内容: PGA Alarm on alltest ------------------------------------报警级别: PROBLEM ------------------------------------监控项目: PGA:9723.2 -------------

system表空间不足的问题分析(二)

今天收到一条不太起眼的报警邮件,大体内容是某个表空间的空间有些紧张了.大体内容如下:Tablesapce: CMBI_SNZG_DATA: 92.2%  [Warning!] 根据这个信息,很明显是需要添加数据文件了,但是同时还有一个警告就是磁盘空间也告警了,那么这个看起来简单的问题得好好琢磨琢磨了,其实是几件事,一件是做一些数据清理,释放部分表空间,甚至可以通过释放数据文件的空间来进一步释放磁盘空间,第二件是给表空间告警的表空间添加数据文件. 首先查看数据库中的用户占有的数据量的情况,可以看到

驳“麦包包的简单SEO分析”二种观点

A5首页搜索专业里有一篇文章"管中窥豹:麦包包的简单SEO分析",其实昨天就看到了这篇文章,只是仅仅是一扫而过,无细读不成方圆啊,今天好好看了下这篇文章,发现除了第一点品牌和第四点流量之外,其他二点笔者都不是挺赞成的,所以才有了这篇文章"驳麦包包的简单SEO分析三种观点",多多交流才是一切吧. 首先呢,关于收录 原图:   现图:   从两张图中看到收录的差异性很大,可惜原作者并未截取百度权重流量估值,不然可以更好的对比一下了,其实昨天14号时候,百度的收录和反链一

PostgreSQL 空间、多维 序列 生成方法

标签 PostgreSQL , GIS , PostGIS , 序列 , 空间序列 背景 数据库的一维序列是很好理解的东西,就是在一个维度上自增. 那么二维.多维序列怎么理解呢?显然就是在多个维度上齐头并进的自增咯. 二维序列 以二维序列为例,应该是这样增长的: 0,0 0,1 1,0 1,1 1,2 2,1 2,2 ... 那么如何生成以上二维序列呢?实际上可以利用数据库的多个一维序列来生成. create sequence seq1; create sequence seq2; create