Archive for 十二月, 2011

创建公交查询数据

公交查询,准确说是公交换乘查询算法有很多人做过,主要有3种方法:

  1. 按照集合求交的方法,把每条线路看作是站点的集合,如果两条线路之间有交集,就说明可以换乘。
  2. 将公交网络抽象成图,用最短路径算法。
  3. 使用换乘矩阵。

这些都有文章能找到,还挺多的,每种算法都各有各的利弊。

用这些算法的前提是要有线路的站点顺序,例如南京138,文澜路下一站是文澜路北站吧。这个数据得有,不然你怎么知道公交车的行驶方向呢?这都不知道就更不用说换乘关系了。

但是,在实际当中是会碰到这种情况的,比如只有站点(point)和线路(line),而没有站点和线路之间的关系:

不过这并不意味着就不能做这个事情了,因为我们知道,在GIS中,要素之间不光有属性关联,而且有空间关联。现在只是没有属性关联而已,可以通过空间上的相对位置找到他们之间的关系:

我的思路是这样的:站点就是point,线路是line。line其实也是由point构成的,只不过必须得有两个以上的point,point之间先相互连接组成线段,再由线段组成line。所以要找到point和line之间的关系,只需找到point和构成line的point(vertex)之间的关系就可以了。如果point和vertex重合,那说明point在line当中,也就是说这条线路包含这个站点。而vertex在line中是按顺序存储的,这个顺序就是公交车的起点到终点。因为制作数据的人员是先绘制站点,然后按公交车的线路将站点连接起来的,不然不符合常理吧。

那么,如何实践呢?首先必须进行point和line之间的拓扑验证,就是必须保证所有的point必须在line上。拓扑验证结果如下:

有21个错误,即21个点不在线上。通过编辑将点移到线上即可。

但是,point在line上,并不一定保证point在vertex上。还要再一次用点和点是否一致的拓扑规则进行验证,这需要将line先打断成vertex,打断后有172491个点(407条线路),这样去和1267个点去做验证会很慢很慢,可以先将重复的vertex去掉再做(这得自己code了,推荐FileGDBAPI),去掉之后只有24013个vertex,这样进行验证就很快。通过验证发现,point和vertex是完全一致的(coincide with),也就是说所有的point都和vertex重合。(其实,只需要一次点和点是否一致的拓扑验证就够了,不过做的时候就是这么做的,将错就错吧。)

最后,去遍历线路,按顺序进行vertex和point的位置进行比较,位置一样就记录下这个站点。当然还需要一些额外的处理,例如有些上下行线路完全一致的,做数据的人就直接复制了一份,这样上下行两条line中存的vertex顺序是一致的,这还得自己判断给他逆转过来,诸如此类等等。

看一下138的结果:

【程序获得】太阳城-1040.黄庄一号路-1041.朱庄-535.朱庄北站-532.仙鹤门-531.仙鹤门东-1042.应天学院-1043.学衡路-530.亚东新城区-792.亚东新城区-870.文澜路南站-869.文澜路-868.文澜路北站-867.学海路-1044.学子路-1049.东部山庄-1048.四桥指挥部-1047.戴家库-1045.南山公墓-1046.栖霞寺

【8684】太阳城 – 黄庄一号路 – 朱庄 – 朱庄北站 – 仙鹤门[地铁站] – 仙鹤门东 – 应天学院(仙林大道) – 学衡路 – 亚东新城区(仙林大学城管委会) – 文澜路南站 – 文澜路 – 文澜路北站 – 学海路 – 学子路 – 衡阳寺 – 红枫新村 – 栖霞老街 – 芦干圩 – 栖霞寺 – 栖霞

从太阳城到学子路的顺序都是正确的,后面不一样是因为我这份数据是2号线开通前的,数据本身的不一致不在我的考虑范围内了。

创建好数据之后,可以选前面提到的算法中的任一个进行计算,当然还要做很多的工作。

——————-

这个事情做了我将近半个月的时间,当然包括后面算法的调试,我现在是深深体会到程序=数据结构+算法,其实我这里都没提到这次用的数据结构和算法,只是介绍了下数据的预处理,有机会以后再说吧。

还有一些比较好玩的事情,比如:

  • Google的公交合作伙伴计划,你只需要按Goolge的数据格式,将某个城市的公交数据上传到Google那里,你就能使用公交换乘啦。这比较适合小城市,因为大城市都已经有数据了,小城市的线路不多,需求不大,而且数据也不好弄,所以用这种方式补充Google的数据,也让当地的人能获得便利,是双赢的事情。这还带来一个好处,就是大家都能使用这些公交数据做研究等等。可以看看Google所需要的数据格式:

  • 现在的公交很多都带GPS了,在公交换乘查询中,如果能考虑到公交车的实时位置,推荐最合适的公交供换乘参考,这是一个方向吧。我查了一下,Google已经在部分城市实现了,其实这个问题应该也不会很难,主要是各个agency肯不肯将数据放出的问题,特别是我朝各部门一直将数据视为生命,不然也不会有我前面这么苦逼地数据预处理了。国内杭州在这些方面一直走在前面,杭州的公交实时位置数据已经做成服务发布了,但是相当不好用额,不过已经走在全国前面了:

  • 还看到一个团队做过类似的事情,Stanford的同学做了当地的公交实时换乘iOS上的软件。他们做这个是因为相关课程涉及到,因此就干脆开发了一个软件发布到App Store中,还产出了两篇论文。这种一举多得的事情真好!上面有关Google公交数据格式的截图就来自他们的论文中。