实现北京公交实时预警小程序
北京的天冷的太快,在后厂村的公交站台冻的要死要活几年之后,终于决定动手写个公交到站时间预报的程序,以便能舒服坐在工位等我的公交车.
美好想法是:
当我处在公司累死累活加班以致忘了时时去翻公交软件查看公交到站时间的
悲剧生活中时,系统会在指定时间点,对我乘坐的公交线路进行监控,然后在
计算好大概的公交到站时间之后,给我推送消息通知我--车快来啦,还不快收手
准备跑路.
然后我瞅瞅消息里推送的几趟公交车到站时间表,视bug数量后悠哉决定坐
第几趟公交车滚回家,避免寒风中凌乱的人生.
实现流程
流程简单归类为以下几点
- 获取实时公交位置数据源
- 公交路径相关信息收集
- 公交车实时大致位置计算
- 预警消息通知方式
1. 获取实时公交位置数据源
数据源一直是个大问题,北京实时公交的数据主要有几类,包括北京公交集团旗下官网的数据来源以及其自有公交app(北京实时公交)几个渠道,因为计算到站时间需要公交实时位置的经纬度,官方app倒是提供了,但反编译app包拿到的数据终归不妥,最后还是选择了北京公交集团官网的数据源,信息包括公交车距离目标站距离(单位m)和预计耗时(单位s).
北京公交集团官网地址:link.
公交路径相关信息收集
确定公交实时位置数据源之后,需要做的是获取北京所有公交线路的信息,这里使用了高德开放平台提供的数据,包括:
1.公交车上下行站点信息
2.公交车整个线路途经的poi点,以极小距离分割得到完整线路poi点集
具体js代码为:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>公交线路查询</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
<style type="text/css">
html,body,#container{
height:100%;
}
</style>
</head>
<body>
<div id="container"></div>
<div class="input-card" style='width:18rem;'>
<label style='color:grey'>公交线路查询</label>
<div class="input-item">
<div class="input-item-prepend"><span class="input-item-text" >城市</span></div>
<input id='city' type="text" value='' >
</div>
<div class="input-item">
<div class="input-item-prepend"><span class="input-item-text" >线路名称</span></div>
<input id='BusLineName' type="text" value='' >
</div>
<input id="search" type="button" class="btn" value="查询" />
<input id="clearInnerHtml" type="button" class="btn" value="清除" />
</div>
<script type="text/javascript"
src="https://webapi.amap.com/maps?v=1.4.15&key=226b4aabf9e88b732610db2f4ca2d564&plugin=AMap.LineSearch"></script>
<script language="javascript">
var linesearch;
/*公交线路查询*/
function lineSearch() {
var busLineName = document.getElementById('BusLineName').value;
var cityStr = document.getElementById('city').value;
if(!busLineName) return;
//实例化公交线路查询类,只取回一条路线
if(!linesearch){
linesearch = new AMap.LineSearch({
pageIndex: 1,
city: cityStr,
pageSize: 2,
extensions: 'all'
});
}
linesearch.search(busLineName, function(status, result) {
// map.clearMap()
if (status === 'complete' && result.info === 'OK') {
lineSearch_Callback(result);
} else {
console.log("status:"+status+"---"+JSON.stringify(result));
}
});
}
/*公交路线查询服务返回数据解析概况*/
function lineSearch_Callback(data) {
var lineArr = data.lineInfo;
console.log(lineArr);
document.getElementById('container').innerHTML = JSON.stringify(lineArr);
}
document.getElementById('search').onclick = lineSearch;
/*公交路线查询服务返回数据解析概况*/
function clearInnerHtml(data) {
document.getElementById('container').innerHTML = '';
}
document.getElementById('clearInnerHtml').onclick = clearInnerHtml;
</script>
</body>
</html>
以上js代码能获取到指定公交线路上下行站点信息以及途经线路完整的poi点
公交车实时大致位置计算
基于第一点获取到的实时公交位置信息(距离某站xxx米),以及第二点获取到的公交线路途经的poi点集,我们就能反推出当前公交车的实时经纬度.
我们将公交线路途经poi点集 中每两两相邻的点视为一段小线路,
计算两者之间的方位角,在拿到该方位角之后,
我们就能以某点为起点反推出距离起点xx米的点的经纬度,
同理,我们在获取实时公交距离目标站xxx米的信息之后,便能通过在poi点集上
反向推出当前公交车实时的经纬度数据
预警消息通知方式
最开始通过cordova开发了android/ios两端的应用,以长连接推送的方式向端上发送通知消息,但坑爹的是最开始不知道大部分厂商有耗电保护,过不了多久程序就会被退出,后面又尝试了几家消息推送厂商的服务,延迟还是有,无法做到及时性,最终选择了腾讯爸爸的小程序,以服务消息的方式及时推送预警消息.
(微信搜索小程序:公交预警)
至此,完美实现了当初的想法,通知效果图长这样紫:
其中涉及一些后端代码实现,想沟通的可以留言交流,小程序目前已上线,微信搜索(公交预警)就能体验到,有不足的地方可以相互交流学习^_