背景
随着移动设备的普及,越来越多的业务具备了时空属性,例如快递,试试跟踪包裹、快递员位置。例如实体,具备了空间属性。
例如餐饮配送,送货员位置属性。例如车辆,实时位置。等等。
其中两大需求包括:
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])); -- 对每批数据的起始时间创建索引
有必要的话,可以多存一个时间字段,用于分区。
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/293359.html