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

数据可视化 Jun 30, 2016

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

长按扫码关注公众号

高楠

爱好地图、数据、自动化控制,主要使用Python、PostGIS作为生产工具。专业地理位置数据治理11年。微信:gmchocolate

评论正在加载...
Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
分享