从拆解自行车到组装GPS数据

DIY了一辆自行车

以前爱DIY电脑,自从去年折腾一番Skylake,填满了内存槽和硬盘架后,仿佛已经走到了尽头,没有更多折腾的兴趣。作为一个工程师,不折腾点事情似乎就缺了什么似的。折腾心作祟,最近DIY了一辆复古自行车,从车把到车架再到变速器,所有部件统统遴选一遍。货备齐的第一件事情就是把核心部件拿来拆解上油(很讨厌轴承摩擦发出的“嗒嗒嗒”的声响)。

拆散的部件重新安装回去的过程,感觉就像读了一遍“自行车”源代码一样,所有的原理,每个细节的技术实现都了然于胸。调试几次后,一切就绪,开始试车。


骑行记录

早期OSM的数据很大一部分人都是骑行者贡献的。想来也不奇怪,平时户外运动时,大家都喜欢记录一下自己的运动路线,运动结束后看看自己的成就。相比跑步来说,同样的运动时间,骑自行车的运动距离会是跑步的4~6倍,看到的风景也会更多,由此,骑行者贡献了OSM早期数据也就说得通了。

现在骑行记录当然不用非要装备一个GPS,手机上装个app就解决了,在此推荐一款骑行app——STRAVA。这款app功能比较齐全,体验也不错,不但能记录骑行,还能做多种运动统计分析,还能结合地图做骑行展示。

这款应用什么都好,但有两个问题对我造成了极大困扰。首先是是地图上的轨迹怎么看都是歪的,和道路对不上;如果想用某些高级的功能,需要付费,而且还不便宜。对于一个GISer来说很难容忍第一条,对于一个爱折腾的GISer来说第二条也接受不了,只能导出gps数据自行动手了。


显示海量GPS数据

gpx是gps产生的标准数据格式,想必很多热爱户外运动的童鞋都不陌生。如何很好地展示分析这些数据恐怕熟悉的人就少很多了。如果你恰好有一批gpx格式的数据,数据量还比较大,又没有合适的手段去展示和分享这些数据,或者数据量较大,没法在地图上流畅显示,推荐用用GeoHey的数据上图app,无需安装任何插件,也无需任何费用,只要添加gpx文件就能轻松分享、浏览gps数据了,如果想分享到朋友圈炫耀一番,直接点击左侧分享即可。

通常来说,gps数据实际上是每隔一段时间记录一个位置点,并记录当前时间和高度,因此,我们看到的轨迹是一系列的位置点。在我的这此骑行中,每秒钟产生记录一次gps位置,一共记录了8685个gps位置,如果只是要流畅纯粹的展示一下我的骑行路线,基本够用了。

上面提到的第一个困扰已经得到了解决,第二个问题解决起来就稍微麻烦一点,但也更有趣一些。STRAVA应用中只是简单的提到“浏览你的热图分布”,我的理解是这个功能可以把所有的运动轨迹展示到地图上,并且高亮显示走过次数多的路线。我们没有那么多骑行路线,所以也没发看到我的“热图”,但受此启发,我想看看我速度的热图,即看看哪些路段在飙车,哪些路段龟速,整体速度情况优势如何。


重新组装GPS数据

先来看结果

总体来看,车速较快,奥森和后海附近闲庭信步,下次骑车要避开那些颜色偏冷人多的路段。GPS数据里面是没有数据信息的,车速也并不是均匀的,要如何才能三两下把数据组装成这样呢?

这个玩法很简单,但前提条件是你要有PostGIS,并且知道用QGIS把gpx数据转为shp数据。

分解动作详解:

1、把数据导入数据库,命令行中敲入如下命令

shp2pgsql -s 4326 ${gps数据}.shp ride_track | psql -U ${用户名} -d ${数据库名}

2、把数据点连接成轨迹线,并且将路段以分钟为单位聚合起来统计速度。

with base_point as (select gid/2||'A' as seg1,(gid+1)/2||'B' as seg2,* from ride_track where gid>=30), -- 将GPS位置点按照先后线段顺序标号
     base_seg1 as (select st_makeline(array_agg(geom)) as geom,max(time)-min(time) as delta_time,seg1 as seg from base_point group by seg1), -- 奇数线段进行拼接,并计算时间差
     base_seg2 as (select st_makeline(array_agg(geom)) as geom,max(time)-min(time) as delta_time,seg2 as seg from base_point group by seg2), -- 偶数线段进行拼接,并计算时间差
     base_seg as (select offset_data(geom) as geom,extract('epoch' from delta_time) as delta_time,seg from (select * from base_seg1 union select * from base_seg2) as union_segment order by substring(seg,'\d+')::integer,substring(seg,'\w+')), -- 奇偶线段按先后顺序排列,并提取时间差值(其中offset_data为数据偏移算法)
     base_speed as (select *,st_length(geom,TRUE)/delta_time as speed,row_number() over (partition by 1) as _id from base_seg where delta_time>0) -- 计算每秒行驶速度
select st_union(geom) as geom,avg(speed)*3600/1000 into ride_track_speed from base_speed group by _id/60; -- 计算并统计每分钟骑行路径,并生成名为ride_track_speed的数据。

3、把数据导出为shp,并通过GeoHey的数据上图app展现分享数据。

pgsql2shp -f ride_track_speed.shp -u ${用户名} ${数据库名} ride_track_speed | zip -r ride_track_speed.zip ride_track_speed.*

数据上传后就可以轻松分析自己的骑行路线,二维码分享等等。详细的操作过程可以参考另外一篇博文新版数据上图-只为更好体验


还是玩不转?

最后的步骤可能需要预先做许多技术工作,如果也想这么玩数据,又不想敲那么多命令,就果断关注GeoHey公众号,说出你的诉求,或许下周就能用上这个功能。

欢迎从GeoHey获取地理和位置相关的数据、知识、服务

访问网站 http://geohey.com

联系我们 contact@geohey.com

QQ群 164183186

长按扫码关注公众号