系统相关
首页 > 系统相关> > PostgreSQL 实时位置跟踪

PostgreSQL 实时位置跟踪

作者:互联网

背景

随着移动设备的普及,越来越多的业务具备了时空属性,例如快递,试试跟踪包裹、快递员位置。例如实体,具备了空间属性。

例如餐饮配送,送货员位置属性。例如车辆,实时位置。等等。

其中两大需求包括:

1、对象位置实时跟踪,例如实时查询某个位点附近、或某个多边形区域内的送货员。

2、对象位置轨迹记录和分析。结合地图,分析轨迹,结合路由算法,预测、生成最佳路径等。

DEMO

以快递配送为例,GPS设备实时上报快递员轨迹,写入位置跟踪系统,同时将轨迹记录永久保存到轨迹分析系统。

由于快递员可能在配送过程中停留时间较长(比如在某个小区配送时),上报的多条位置可能变化并不大,同时考虑到数据库更新消耗,以及位置的时效性,可以避免一些点的更新(打个比方,上一次位置和当前位置变化量在50米时,不更新)。

动态更新可以减少数据库的更新量,提高整体吞吐能力。

设计

 

实时位置更新

1、建表

create table t_pos (  
  uid int primary key,   -- 传感器、快递员、车辆、。。。对象ID  
  pos point,             -- 位置  
  mod_time timestamp     -- 最后修改时间  
);  
  
create index idx_t_pos_1 on t_pos using gist (pos);  

真实环境中,我们可以使用PostGIS空间数据库插件,使用geometry数据类型来存储经纬度点。

create extension postgis;  
  
create table t_pos (  
  uid int primary key,   -- 传感器、快递员、车辆、。。。对象ID  
  pos geometry,          -- 位置  
  mod_time timestamp     -- 最后修改时间  
);  
  
create index idx_t_pos_1 on t_pos using gist (pos);  

2、上报位置,自动根据移动范围,更新位置。

例如,移动距离50米以内,不更新。


 
insert into t_pos values (?, st_setsrid(st_makepoint($lat, $lon), 4326), now())  
on conflict (uid)  
do update set pos=excluded.pos, mod_time=excluded.mod_time  
where st_distancespheroid(t_pos.pos, excluded.pos, 'SPHEROID["WGS84",6378137,298.257223563]') > ?;  -- 超过多少米不更新  

历史轨迹保存

通常终端会批量上报数据,例如每隔10秒上报10秒内采集的点,一次上报的数据可能包含多个点,在PostgreSQL中可以以数组存储。

create table t_pos_hist (  
  uid int,                  -- 传感器、快递员、车辆、。。。对象ID  
  pos point[],              -- 批量上报的位置  
  crt_time timestamp[]      -- 批量上报的时间点  
);   
  
create index idx_t_pos_hist_uid on t_pos_hist (uid);                 -- 对象ID  
create index idx_t_pos_hist_crt_time on t_pos_hist ((crt_time[1]));    -- 对每批数据的起始时间创建索引  

有必要的话,可以多存一个时间字段,用于分区。

标签:Postgre,SQL,位置,地图,分析,GPS,数据
来源: